1/58
Looks like no tags are added yet.
if/else statement
if logical vector true, then something happens.
elseif logical vector true, then something happens.
if everything above is not true, else something happens (no condition, it’s the last resort).
if no else at the end, and nothing is true, no output.
put most restrictive conditions first.
*if you get 60 first, the first statement would be true and a 60 would be an A, which is not right.
function out = calcLetterGrade(num)
if num >= 90
let = 'A'
elseif num >= 80
let = 'B'
elseif num >= 70
let = 'C'
elseif num >= 60
let = 'D'
else
let = 'F'
end
out = sprint('Your numerical grade is %d which is the letter grade %s',num,let)
end
switch/case/otherwise.
switch variable
case {things variable must be equal to in order to output}
something that happens.
case {things that variable must be equal to if above was not right}
something that happens
go down list til something happens.
if none of the cases are valid, you can put otherwise at end which is the last resort.
if no cases are valid and no otherwise, nothing happens.
Yes, {1, 2, 3} acts like an “or” between the values. case {1, 2, 3} behaves like x == 1 | x == 2 | x == 3.
Variable must be the following:
x = 5;
switch x % scalar double, fine
switch 5 % also fine
switch 'cat' % string, fine
switch true % scalar logical, fine (it counts as a number)Invalid variables:
switch [5 4 3 1] % numeric vector, error
switch [true false true] % logical vector, errorconverting switch to if/else.
% switch statement
switch name
case {'Kantwon','Serena','Jessie J'}
out = 'come on in!'
case {'James','Alex'}
out ='call the police!'
otherwise
out = 'y r u here?'
end
%make the switch into an if
if strcmp(name, 'Kantwon') | strcmp(name, 'Serena') | strcmp(name, 'Jessie J')
out = 'come on in!';
elseif strcmp(name, 'James') | strcmp(name, 'Alex')
out = 'call the police!'
else
out = 'y r u here?'
end
***Notes
Must use strcmp. if you use a mask, it compares letter by letter, which outputs a logical vector, not a single true/false. If names are different length, you will get an error because it element size needs to match (if both are characters).
If the names were the same length, it could work because if/else collapses a logical vector into a single value (if all are true, its true, but if one is false, its false).
strcmp and strcmpi also allows for picking if case sensitive or not.
Use || and && if the if/else is a single true or false output (no vector of logicals).
Tracing if/else statement
If/else statement:
%when something is true, it does not evaluate rest but goes line by line
%til the end, then back to top at if, then to the end
converting switch to if/else
%switch statement win
var = 7
switch var
case{'James', 7, true}
out = 'yay'
otherwise
out='boo'
end
matlab
var = 7;
if strcmp(var, 'James') || var == 7 || var == true
out = 'yay';
else
out = 'boo';
endMatlab can compare var to a scalar number because 7 is scalar, so it’s compared line by line to var. If var were a character vector, it would be valid.
matlab
var = 'Heyyy';
switch var
case {'Jamesie', 7, true, 'a', 77}
out = 'yay';
otherwise
out = 'boo';
endmatlab
var = 'Heyyy';
if strcmp(var, 'Jamesie') ||
(isnumeric(var) && var == 7)
|| (islogical(var) && var == true) ||
strcmp(var, 'a') || (isnumeric(var)
&& var == 77)
out = 'yay';
else
out = 'boo';
endwhen to use what when converting
1. ischar(var) && strcmp(var, 'James'): fine, but you don’t need the guard. strcmp already returns a single false for any non-string (strcmp(7, 'James') is false, no error). So plain strcmp(var, 'James') is safe for every type of var.
2. isnumeric(var) && var == 7: correct. If var is a string, isnumeric is false and && skips the ==, so a vector never reaches ||.
3. islogical(var) && var == true: this is the one that’s off. In a switch, case true matches when var is true or the number 1, because numbers and logicals compare with ==. With islogical, var = 1 would fail your guard, but the switch would say yay. The switch would also say yay for var = 1 through case true, since 1 == true
2. Is isnumeric(var) necessary for var == 7? Only if var could be a multi-character string. The guard exists to stop something like 'Hey' == 7 from producing a vector that crashes ||. If you know var will be a single number, a single logical, or a single letter, plain var == 7 is safe and you can skip it. In class, if the problem says var is a number, just write var == 7.
When to use/not use if/elseif/else
When to use/not use switch/case/otherwise
If/else:
Multiple different conditions that depend on multiple different variables.
A switch can’t do this, because it only looks at one variable (could ony look at age, not age, temp, and hasID).
matlab
if age < 18
out = 'minor';
elseif hasID && age >= 21
out = 'can enter';
elseif temp > 100 || isSick
out = 'go home';
endHaving range of values
Bad when you have multiple cases. So like the same variable has many different values.
Can use if for anything, however.
matlab
if x == 1 || x == 2 || x == 3 || x == 4 || x == 5Switch/case/otherwise:
Use if you want to compare to specific values.
Do not use if there is a range of values.
If there’s >,<,<=,>=.
Wanting to compare a variable to many different strings.
A switch is good when the class of the variable being checked is unknown.
A switch is good when multiple cases result in the same value.
A switch is good when comparing strings.
ischar(x)
islogical(x),
iscell(x)
isstruct(x)
isnumeric(x)
returns true if X is the same data type.
any size (single value, vector, matrix)
Returns one output either true/false for entire input.
isempty(arr)
Returns true if any dimension of arr is 0.
matlab
size([]) % 0 0 empty
size('') % 0 0 empty string
size(zeros(0,3)) % 0 3 empty (0 rows, 3 columns, so no elements)
size(zeros(3,0)) % 3 0 empty (3 rows, 0 columns, still no elements)Appear from result of a logical mask outputting nothing.
v = [1 2 3];
v(v > 10) % nothing passes the mask, returns a 1x0 empty
Returns one output either true/false.
all()
any()
Returns true if all of the values in a logical vector are true.
Returns true if any of the values in a logical vector are true
Works for vector or matrix.
Returns one value for a vector, but one per column for a matrix.
strcmp(a,b)
strcmpi(a,b)
returns true if strings a and b are the same, strcmpi is case insensitive.
works for strings only, outputs one true/false.
== ~= > < >= <=
work for array, vector, or scalar, but both sides have to be same size element wise, or one side has to be a scalar.
& | ~
works for any size
both sides must be the same size element wise or one side is a scalar.
outputs same size as input.
&& ||
works for single values only (single output logicals)
outputs a single true/false, not a vector.
Nesting for if/elseif/else and switch/case/otherwise
Putting switch inside if/else:
After each if or elseif, for the output, you can put a switch that runs if that condition for if or elseif is true.
Putting an if/else inside a switch:
After the case, if the case is true, you can put an if/else inside the case.
Remember, else and otherwise cannot have a condition or case, but they can have a nested switch or if/else conditional if all the possibilities above it are invalid.
common mistakes
Check the number of elements on both sides, make sure they are equal.
When concatenating, make sure everything is the same variable type (don’t mix char with double, if you want them to be together, use num2str or str2num).
Be careful with time calculations and round vs floor vs ceil, usually convert to minutes and then use mod or floor and dividing to get the hours and mins.
Use floor for min and hours, don’t mix match floor and round.
Remember that sprintf has ‘‘ in the string.
Put most restrictive condition first in if/else conditional.
Remember to assign output and seperate inputs with comma.
if/else statement
if using an or operand, if the first part is true already, the second half of or is not evaluated and it outputs the result.
remember you cannot index beyond the vector size or else the output is an error.
A = 1:5 ;
B = 1:4 ;
C = 3;
%(A(5)<B(5))
if (false) & (A(5)<B(5))
C = 99
end
% This code will Error (Index exceeds the number of array elements(4) )
% if (A(5)<B(5)) & (false)
% C = 99
% end
if (true) | (A(5)<B(5))
C = 99
end
% This code will Error (Index exceeds the number of array elements(4) )
if (A(5)<B(5)) | (true)
C = 99
end
Conditionals vs iterations
Conditionals: if/elseif/else and switch/case/otherwise
They only run the first true output
Iterations: for and while loop
They run/loop repeatedly til the condition is false.
Iterations: while loop
Unspecified number of loops.
Conditional in first line, with variable that is either scalar of represents length of a vector determined before the loop.
Increment the variable in the last line of the loop so it ends eventually. Initialize the variable before the loop.
For loops do not use conditional.
Do not have a looping variable like for loops, so you must initialize and increment variable.
Loop only checks condition at the top, so final value of variable may exceed the condition.
Scalar example: final values are x=5 and y=6
x = 2
y = 3
while x < 5 % n<logical condition>
%<code block>
y = y + 1 %
x = x + 1 %
end
Vector example: index is initialized and increments to go through the length of the vector.
% if a number is even, add 10 to it.
vec = [1 2 3 4 8 11]
a = length(vec)
index = 1
while index<=a
if mod(vec(index),2) == 0
vec(index) = vec(index) + 10
else
vec = vec
end
index = index + 1
end
Iterations: for loops
Runs a specific number of times based on the length of a vector variable at the beginning.
x = [vec]
Cannot put in vector directly, must be assigned to a variable.
Can be vector, scalar, or matrix.
Every loop, the value of x goes through the vector chronologically.
Choosing to plug in vector directly for first line, or the index vector:
If you only need to look at each value (sum, max, count), looping over values is fine.
If you need to change the vector or know where you are in it, loop over positions.
If the variable isn’t used in the body, the loop still runs once per element. It’s just a counter.
for x = 'hello' runs 5 times, and a scalar like for x = 7 runs once.
for loop trick
multiplying values adjacent together (result is a vector 1 length shorter)
vec = [8 7 5 9 2]
for i = 1:length(vec)-1
vec(i) = vec(i) .* vec(i+1)
end
deleting values from vec greater than 5
%remove values greater than 5 using iteration
for i = length(vec):-1:1
if vec(i)>5
vec(i) = []
end
end
Conditions for while loop
Things that work next to while:
a comparison: x < 5, vec(i) == 0
a function that returns one true/false: strcmp(a, b), isempty(v), ischar(x), all(mask), any(mask)
a logical variable: check
several of these joined with &&, ||, or &, |
common mistakes
1. Loop bounds and off-by-one (your most common)
while index<a instead of <=, which skipped the last element
1:(len-4) instead of 1:(len-3) in find2020
1:len-1 with x+1 indexing in the min-finder, when 1:len with newarr(x) is simpler
Putting index <= len after the check that reads newarr(index), so it crashed before the guard ran (sumTo0)
for x = len or for x = len-1 when you needed 1:len. A single number is a one-element list, so the loop runs once.
for x = num in workoutAlgo, same issue
2. Length counts elements, not digits
length(mins) == 1 when you meant the digit count (length(num2str(mins)))
3. Output and variable name mismatches
Assigning median, sentence, maximum, minimum, or final when the function line returns something else, or never assigning an output at all
Function names that don’t match the assignment (ratRacee, canReach, trafficControl)
Typos: numstr, indice vs indices, 'Micheal', sprint, str for str1
Using your function’s name as a variable (wordLength), or built-in names (log, var, median)
4. Acting on the whole vector when you meant one element
mod(vec,2) == 0 instead of mod(vec(x),2) == 0
grades + grades.*.01 in a loop about grades(a)
mask+1:end where you needed a position from find or strfind
len(x) instead of newarr(x) (indexing the wrong variable)
5. Strings vs numbers
== on strings of different lengths instead of strcmp
'2' and '0' as characters when the vector held numbers
%d with a char string, or concatenating a number into a string
Turning mins into a string and then comparing it with > 30
6. Accumulators and starting values
out = [] then out + 1 (needs 0)
Not resetting final each week
Appending a instead of the result a > 5
No starting value for minimum (use the first element)
7. Logic and operators
= vs ==
Chained comparisons like 2 * vec(x+3) == 0
~= to combine masks instead of & with ~
Backwards comparison (minimum < newarr(x+1) finds the max, not the min)
elseif with no condition, or else attached to the wrong if
Re-checking even/odd every pass in workoutAlgo
8. Loop structure
Missing the increment in a while
Assuming an if repeats like a loop
Trying to update the loop variable in a for (x = x+1, x = [x 7])
Sorting from column 1 first, or not applying arr = arr(index,:) after each sort
9. Cosmetic
Missing end, and missing semicolons so everything prints
Pre-submit checklist (this catches most of them):
For every x+k or x-k in a loop, what’s the last value of x, and does that spot exist?
Test every < or <= on the last element.
Does the output name in the function line match what I assign?
Is each variable one value or a vector, a number or a string, at each comparison?
Counters start at 0, lists at [], and max/min start at the first element.
In a for, is the list long enough? In a while, does something change the condition?
Trace the first example, then the shortest input.
strtok
strtok removes delimiters at the front.
Example: ‘,1,2,3’ would output num=’1’ and str = ‘,2,3’
when you have to use strtok, usually its with a while and ~isempty because str pulls phrases til the string is empty and has nothing left to pull.
finding the longest or shortest word
sort of like the minimum problem, use length(vec) > longWord and length(vec)< shortWord, redo throughout the entire vector to get final longest and shortest words.
finding the mode number
use a mask in a loop, and find the sum of the mask at every spot of the vector.
save the sums by building a seperate vector (so you have the sum at each spot)
then find the max, and index at the max.
use index to find the original spot of the sum aka the mode number.
When to initialize:
Rule: a variable must exist before you use it, and anything that builds up over a loop must be started before the loop.
Ask two questions about each variable:
Does it carry information from one loop pass to the next? Then create it before the loop.
Is it only needed inside one pass? Then it can be created inside the loop.
To use while or for loop
If the vector at the top line of the for loop changes, it wont update because only the initial vector is used. Use the while loop.
cell array
Create in 2 different ways:
[{42} {‘Hello’} {false}]
{ 42 ‘Hello’ false}
Indexing a cell array returns a cell (cell with its contents), not the contents of the cell itself.
Index with {} instead of () to get contents of cell.
Retriever a cell with (), retrieve contents with {}.
For ca = {1, 'hey', true};
ca(1) → {[1]}
ca(2) → {'hey'} (or {['hey']})
ca(3) → {[1]} in MATLAB's display, because logical true displays as 1 in some cell-array contexts.
RHS indexing: retrieves stuff already existing
LHS indexing: replace a cell with (), replace stuff inside cell with {}.
cell array: how it outputs LHS and RHS
1. Using () vs. {} to retrieve a value RHS
Code | Output | What you get |
|---|---|---|
|
| The cell itself |
|
| The contents of the cell |
|
| The cell itself |
|
| The contents of the cell |
|
| The cell itself |
|
| The logical value |
2. Replacing a value using () vs. {}
Suppose you want to replace the second cell with 97. RHS
Code | Correct? | Why? |
|---|---|---|
| Yes |
|
| Yes |
|
| Yes |
|
| No | You cannot assign a double directly to a cell using |
Cell array: a cell can contain a cell
Example
[ {12} {‘Hello} {{‘hi’}} ]
{12 ‘Hello’ {‘hi"}}
Adding to cells and making them larger: LHS indexing
Removing cells from an array
Removing content of cell from an array.
Use () to add a cell.
Use {} to add data to a cell, can be cell that is beyond what exists if LHS indexing.
Cells that are in between will be empty {[]}.
Use () to remove existing cell from array
cell(2) = []
Use {} to remove contents from existing cell without deleting the cell.
cell{2} = []
cell = {1 [] ‘Hi’ 15} also written as cell = [ {1} {[]} {‘Hi’} {15} }
Write {15}, but MATLAB displays {[15]} when you call cell(4). Both represent a cell containing the number 15.
Accessing vector data within a cell (RHS).
You access data in a vector of regular type (like vec or array) by using () like vec(1).
So, to get the data of a vector in a cell, first access the data inside the cell with {}, then access data in the cell data with ().
You ust get the data inside a cell with {} first because you cannot access anything through the cell if its {‘Hello’} and not ‘Hello’.
Changing vector data within a cell (LHS)
word = ca{1}
word = ‘Hello’
To access ‘e’ or second index within cell of an array:
letter = ca{1}(2)
letter = ‘e’
Changing vector data within a cell:
cell{1}(1) = ‘J’
cell{1} = ‘Jello’
Functions of cell arrays:
length(cellarr)
size(cellarr)
cell2mat()
num2cell()
cellstr()
Length(cellarr): use if the cell array is a vector of cells.
size(cellarr): use if the cell array is an array of cells.
Output is dimensions of cells in rows and columns, not whats in the cells.
cell2mat(): Converts a cell array to a regular array, only works if everything in the cell is the same data type, and the vectors in each cell are equal lengths.
Error if there are different data types in the cell array.
Error if the vectors in each cell of the cell array are different lengths.
num2cell(): Converts an array of numeric data into a cell, each number is put in its own cell.
cellstr(): Converts array of characters into cell array, with each row of the character array as its own cell in the cell array. Cell array is a long column. (4×3 char array to 4×1 cell array).
Spaces at end of char array are removed when put in cell array (spaces were there to make dimensions the same).
Functions of cell arrays that can see through cells with character data:
sort()
strcmp/strcmpi
contains
strrep
sort()
Only sorts ascending.
Cells need character vectors.
1xN or Nx1 vector of cells.
Use sort indices to rearrange columns.
First sort the row or column of data that is all characters to get the indices.
Then, use that order to sort the rows or columns of the entire cell array.
To sort descending:
First sort regularly.
Then apply the sort order in reverse order.
For descending order, use range indexing to reverse.
% Can only sort on cell arrays of all chars
names = {'Jeremy' 'Emily' 'Hurley' 'Matthew'}
[sortedNames, inds] = sort(names)
inds = inds(end:-1:1) % for descending
% CAN'T sort in descending
% CAN'T sort doubles
%steps if you need to sort doubles:
% cell2mat
% sort
% num2cell
Functions of cell arrays that can see through cells with character data:
strcmp(comparison, cells)
strcmpi(comparison, cells)
Comparison is character vector or single cell with a character vector.
Cells are cell array of character vectors.
Output is logical mask that can be used.
Use to retrieve cells.
Can apply comparison and cells in either order.
Functions of cell arrays that can see through cells with character data:
contains(cells, pattern)
Output is logical mask if cell contains the pattern vector.
Cells must be a cell array of character vectors.
Pattern should be a character vector or cell containing a character vector.
Output is a logical vector that can be used as a logical mask.
strrep(cells, search, replace)
Replaces the search character with replace.
Cells should be cell array of character vectors.
Search and replace should be character vector or cell containing a character vector.
Search and replace can be different lengths.
Can find a part of the word, not the whole word.
% What does this give us?
avatarCa = {'Zuko' true 16;
'Azula' false 14}
ages = avatarCa{:,3} % WRONG, only grabs 1st value
ages2 = [avatarCa{:,3}] % RIGHT!
ages3 = cell2mat(avatarCa(:,3))
names3 = cell2mat(avatarCa(:,1))
ages = avatarCa{:,3} only has 1 output because there is only 1 output assigned, so it only grabs the first value.
ages2 = [avatarCa{:,3}] outputs the entire numeric column because its put in a vector, and {} extracted the contents of the cells
ages3 = cell2mat(avatarCa(:,1)) outputted a 2×1 column vector because all contents of the cells are the same data type and equal length (1×1 and 1×1 or 1×2 and 1×2). Equal length in size of dimensions, not digit length. () extracts cells, not cell contents, and cell2mat is for cells to array, not contents of cell to array.
Masking with cell array
Cannot make a mask with a cell array, but you can apply an existing mask to a cell array to choose certain cells.
% This is bad
caNum = {12 34 45}
%mask = caNum == {45 6 7} % errors
% you could apply masks if you have already created them.
mask = [true true false]
appCa = caNum(mask)
num2cell vs cellstr for a character array/vector
|
| |
|---|---|---|
What goes in each cell? | One whole row of text | One individual character |
|
|
|
Preserves row structure? | Yes, one cell per row | Yes, one cell per character position |

cell2mat() size requirements
Combining direction | Example | Rule |
|---|---|---|
Horizontal (row of cells) |
| Contents must have the same number of rows. Different word lengths are OK! |
Vertical (column of cells) |
| Contents must have the same number of columns. Different word lengths cause an error! |
ca = {'Kantwon', 'Forsyth', 'Stallworth'};
newStr = cell2mat(ca)
% 'KantwonForsythStallworth'