I have designed a while loop in Matlab to do a specific task. Firstly, I am importing the titles of several columns of an excel spreadsheet.
'student #' ' assn1' ' assn2' ' assn3' ' assn4' ' assn5' ' lab1' ' lab2' ' lab3' ' lab4' ' midterm' ' final exam'
These are stored in a matrix called 'txt'. While my counter variable 'i' has not reached the numerical value equal to the size of 'txt', enter the loop. I store the current value of the vector in the variable j.If the first 4 letters of this value are equal to "assn", increase the assignmentCounter by 1. If it is not, do nothing. Then, before exiting the loop, increase the counter variable 'i' by 1. Ideally, this program should tell me how many times an assn appears in the matrix 'txt'. However, my end result is that the assignmentCounter is 0. I do not know what to do. Any help would be greatly appreciated, thanks!
Code:
%Assignment 4
clear;
clc;
filename = 'marksdata.xlsx';
[num, txt, raw] = xlsread(filename);
%Loop through the categories
assignmentCounter = 0;
categorySize = size(txt);
i = 1;
loopCount = 0;
while i < categorySize
j = txt(i, categorySize);
if strncmpi('assn',j, 4)
assignmentCounter = assignmentCounter + 1;
end
i = i + 1;
end
Ideally, this program should tell me how many times an assn appears in
the matrix 'txt'.
If that is all what you want, this why not:
txt={'student #' ' assn1' ' assn2' ' assn3' ' assn4' ' assn5' ' lab1' ' lab2' ' lab3' ' lab4' ' midterm' ' final exam'}
c=strfind(txt,'assn');
sum(~cellfun(#isempty,c))
% 5
so assn shows up 5 times.
Related
The program requires input of positive numbers, and counts each even number using a loop function that doesn't count odds and ends if a O is input.
I'm not sure how to go about creating a loop or if I can use an if function within the loop.
Dim Count = 0
While (number mod 2 = 0) do
Count + 1 = Count
I actually didn't understand the question very well but as far as concerned, if you dont want odd numbers to be included I suggest on count add 2 not one , since the count variable starts with zero do:
Dim Count+2
Btw when do you want the count to stop? At 2 And goes back to 0?
If so then use the if statement
var Dim_count = 0;
if(Dim_count == 0){Dim_count+2}
else if(Dim_count ==2){Dim_Count =0;}
It would help if you provide a sample input so we can work with actual code and guide you to the right solution.
If you receive the input as, let's say, array of numbers, you can simply loop trough it using for or foreach and add additional condition to check for 0 if you want to preliminary exit:
For Each number As Integer In numbers
If (number mod 2 = 0) Then
Count = Count + 1
End If
If (number = 0) Then
Exit For
End If
Next
If you have existing code in which somehow number is reinitialized/redefined on each iteration already, then what you have is pretty close to what you need:
While (number <> 0)
If (number mod 2 = 0) Then
Count = Count + 1
End If
End While
Function counts even numbers:
REM function gets input, exits at 0 and adds positive even numbers.
DO
INPUT X
IF X = 0 THEN PRINT Y; " even numbers": END
IF X > 0 THEN
IF X / 2 = X \ 2 THEN Y = Y + 1
END IF
LOOP
I am completely unsure about this. just a guess...
Dim j as Integer
Dim i As integer
j = 0
i = 2
For i = 1 to 100
j = j+i
Print j
Loop
End Sub
Assuming you are getting numbers from some input, this is how you can do it. Have an infinite loop with While True, then for every number given from your input, check if its even using number mod 2 = 0. This will go on forever so you need to add some condition (another if statement) for it to stop the while loop. More information about while loops here: https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/while-end-while-statement
Dim Count = 0
While True do
If (number mod 2 = 0) Then
Count + 1 = Count
End If
End While
I have the following function:
Function get_equal_array_subset(column_label As String, _
loop_array() As Variant, _
values_array() As Variant)
' this function outputs an array of value from the values_array, based on a loop through the loop_array
' column_label is the first item in the array of the ouput array; i.e. the column lable of a new range
' loop_array is array being looped through and testing each value
' valus_array is the array from which values are taken with the test is met in the first array
' *** arrays have to be of equal lenght ***
Dim subset_array() As Variant
subset_array = Array(column_label)
Dim rows_dim As Long
Dim cols_dim As Integer
Dim agent_subset_counter As Long
agent_subset_counter = 0 ' counter to set the key for the new array
For rows_dim = 2 To UBound(loop_array, 1)
For cols_dim = 1 To UBound(loop_array, 2)
If loop_array(rows_dim, cols_dim) > 2 Then
agent_subset_counter = agent_subset_counter + 1 ' increase the subset counter by 1
ReDim Preserve subset_array(agent_subset_counter) ' resize the array account for the next id
subset_array(agent_subset_counter) = values_array(rows_dim, cols_dim) ' add the new id to the agent subset
End If
Next cols_dim
Next rows_dim
get_equal_array_subset = subset_array
End Function
Is there a way for me to make the If loop_array(rows_dim, cols_dim) > 2 Then a variable? Let's say I wanted the test to be > 3 or = 5 or non blank...etc.
I would go for the magic Application.Evaluate() method of the Application class. An example might be to define a series of tests into an array, let's say:
Dim myTests(4)
myTests(1) = "> 3"
myTests(2) = "= 5"
myTests(3) = "+3 < 5"
myTests(4) = "- 4 + sum(1,2) < 5"
Hence, using the simple statement:
If Application.Evaluate(loop_array(rows_dim, cols_dim) & myTests(j)) Then
Clearly, the variable j should be defined depending on the test you want to use and this kind of method would allow you to define several arrays of operators (one array for operators like +, - etc., another one for values like 3, 5 etc.)
NOTE If you don't know it yet, the Application.Evaluate() method will evaluate the expression and returning the result as Excel would do. It's basically using the same code that Excel uses to evaluate what you write in a cell:
Application.Evaluate("2+3") --> 5
Application.Evaluate("2 < 3") --> True
Application.Evaluate("IF(2=3,1,2)") --> 2
'etc.
If you wanted to make the "magic number" 2 into a variable, then you would use an array item in place of the 2.If, however, you wanted separate logic, then you use use a Select Case structure.
it might be a basic question. I am a beginner.
When I am trying to import an excel file with 5 columns and row 1 as column header, and generating a function for doing the same, MATLAB is not generating 5 variable as per the column headers, but only one variable and that too with the default name, ans.
Kindly help.
Here is the code:
function [Date,Open,High,Low,Close] = importfile(workbookFile,sheetName,startRow,endRow)
% If no sheet is specified, read first sheet
if nargin == 1 || isempty(sheetName)
sheetName = 1;
end
% If row start and end points are not specified, define defaults
if nargin <= 3
startRow = 2;
endRow = 250;
end
%% Import the data, extracting spreadsheet dates in MATLAB serial date number format (datenum)
[~, ~, raw, dateNums] = xlsread(workbookFile, sheetName, sprintf('A%d:E%d',startRow(1),endRow(1)),'' , #convertSpreadsheetDates);
for block=2:length(startRow)
[~, ~, tmpRawBlock,tmpDateNumBlock] = xlsread(workbookFile, sheetName, sprintf('A%d:E%d',startRow(block),endRow(block)),'' , #convertSpreadsheetDates);
raw = [raw;tmpRawBlock]; %#ok<AGROW>
dateNums = [dateNums;tmpDateNumBlock]; %#ok<AGROW>
end
%% Replace date strings by MATLAB serial date numbers (datenum)
R = ~cellfun(#isequalwithequalnans,dateNums,raw) & cellfun('isclass',raw,'char'); % Find spreadsheet dates
raw(R) = dateNums(R);
%% Create output variable
data = reshape([raw{:}],size(raw));
%% Allocate imported array to column variable names
Date = data(:,1);
Open = data(:,2);
High = data(:,3);
Low = data(:,4);
Close = data(:,5);
Do [Date,Open,High,Low,Close] = importfile('filename.xlsx');
I have a list of products with the ID and the picture name. One entry per picture, instead of one entry per product and the pictures in columns as I need it. If the file had only a few entries, the manual procedure I guess it would be to cut all the picture names for the same product, paste (transpose) and remove the entries without names. But since the file has over 100,000 entries, does anyone know how to do this using VBA?
EXAMPLE:
What I have...
product_id; picture_name
1; picture1.jpg
1; picture2.jpg
1; picture3.jpg
2; picture4.jpg
3; picture5.jpg
3; picture6.jpg
What I need...
product_id; 1st_picture; 2nd_picture; 3rd_picture...
1; picture1.jpg; picture2.jpg; picture3.jpg
2; picture4.jpg
3; picture5.jpg; picture6.jpg
Thank so you much in advance for your help.
I guess this solves your problem
Compare two consecutive rows one by one
If two rows matches,Take the corresponding value in 2nd column of 2nd row put the value in next to 2nd column of 1st row and delete the 2nd row
If not matches skip the previous step and go for comparison of next two rows.
Here is the Code
Sub SortPics()
i = 2
Do
Flag = False
VarComp1 = Sheets("YourSheetName").Cells(i, 1).Value
VarComp2 = Sheets("YourSheetName").Cells(i + 1, 1).Value
If VarComp1 = VarComp2 And VarComp2 <> "" Then
Set VarSec1 = Sheets("YourSheetName").Cells(i, 2)
Set VarSec2 = Sheets("YourSheetName").Cells(i + 1, 2)
VarSec1.Offset(0, 1 + j).Value = VarSec2.Value
Sheets("YourSheetName").Cells(i + 1, 1).EntireRow.Delete
i = i - 1
Flag = True
End If
i = i + 1
If Flag = True Then
j = j + 1
Else
j = 0
End If
Loop While VarComp1 <> ""
End Sub
How do I iterate back to zero in a Microsoft Excel Caeser Cipher code?
I've tried:
If Letter_value + Offset > 25 Then
Letter_value Offset = Letter_value + Offset - 25
This does not work.
I think I figured out what you're asking.
Take a look at the mod operator.
This function assumes that your alphabet starts with 1 = "A" and your alphabet only consists of the letters A-Z.
Function simpleCeaserEncode(letter_value As Integer, offset As Integer) As Integer
' returns simple ceaser encoded value of of the letter_value
If letter_value + offset > 25 Then
simpleCeaserEncode = (letter_value + offset) Mod 26
Else
simpleCeaserEncode = letter_value + offset
End If
End Function
Private Sub test()
Debug.Print simpleCeaserEncode(20, 10)
' ==> 4
Debug.Print simpleCeaserEncode(20, 2)
' ==> 22
End Sub