Control Flow and Functions
The building blocks of programming
Table of Contents
Example 3 - For Loop with any vector
Example 4 - FOR LOOP and Matrices
So, how do we build the fibonacci sequence ?
Creating a Function for the Fibonacci Sequence
Script Editor
Color provides information
- orange: warning - it works, but it could work better (often you can ignore orange, at least at this stage)
- red: error - something is wrong - fix it
- pink: strings
- blue: key words
- green: comments
You can see where these colors are set in the preferences:
reset MATLAB
Control Flow
If, Else Statement
- Uses logical operations to determine which statement to execute
- Any logical operation OR anything that can be resolved to TRUE or FALSE can be used as conditional statement
Example - IF ELSE
Create an IF, ELSE statement based on the following pseudocode:
- Assign an integer to the variable x
- If the x is ODD, display 'x is odd'
- Else display 'x is even'
NOTES:
- You should use mod to see if it is divisible by 2
- The output from mod can be typecast into a conditional statement
ADVANCED
- Inside the IF, ELSE statement, just set a string s to 'even' or 'odd'
-
Use fprintf to report the final outcome (after the IF ELSE statement)
-
notice only one of two statements is executed
- What happens if you remove the relational operation? (==0)? Does it still work? Why?
IF, ELSEIF Statement
- If you have more than one conditional statement to test, add IF ELSE statements
- Each conditional statement will be tested sequentially
- This means that if TWO conditional statements resolve to TRUE, only the first conditional statement will be executed
Example - ELSEIF
Blackjack, a popular casino game is deceptively simple. Just get a higher score than the dealer, but don't go over 21.
When playing Black Jack, you are dealt two cards and then asked whether you want any more cards. Its your job to decide whether you want another card (Hit me!) or you just want to stick with what you have ('Hold.')
Here we will use the function randi to simulate a black jack hand, with a range of values from 2 (the minimal value you can get with 2 cards) to 30 (if you're foolish enough to hit on a 20).
if hand > 21 % if greater than 21
s = 'Ooh, bust. Pay up.';
elseif hand==21 % if equal to 21
s = 'Black Jack!!!';
beep
elseif hand >= 16 % Hold at 16 or higher
s = 'Would you like to hold?';
else
s = 'Hit?';
end
fprintf('%d. %s', hand,s)
- How would you add a statement asking 'Would you like to double down?' if you get a 10 OR an 11?
- Does the order of the statements matter?
- How would you add the total of the hand to the reported statement?
Switch Case
- ONLY tests for equality, not other operations
- You don’t explicit set up a conditional statement - the conditional statement is implied (IS EQUAL TO)
- You can have as many case statements as you want
- The comparison doesn’t have to be a character array
- You can even mix and match character arrays and numbers
Example - SWITCH CASE
- match a color
%answer = inputdlg('Enter a color:'); % dialog box to request data answer = "yellow" switch answer{:} % answer = cell array - {} opens element to access content case 'red' str = 'Roses are red'; case 'green' str = 'Stems are green'; case 'blue' str = 'Violets are blue'; case 'magenta' str = 'Magenta is Magnificent!' case {'orange', 'yellow'} str = 'Orange you glad you chose yellow (or orange)' otherwise str = 'try again'; end fprintf('%s', str)
Try it now:
- Run the code section
- Explore the workspace: examine answer and str
Next:
- add a new case for magenta. set str be 'Magenta is Magnificent'
- add a new case for cyan: set str to 'Cyan is cool!'
- add a new case for either 'orange' or 'yellow'. Note, case statements can be cell arrays: set str to 'Orange you glad you chose yellow (or orange)'
- Test your code. Did it work?
Finally:
- Comment out the first line of code
- Add a new line of code that contains drop down menu (Under the insert field) and add all of the potential colors there. That way you don't have to worry about proper capitalization or misspellings. Make sure the drop down menu assigns the variable answer
And now, this...
LOOPS
For Loops
- For loops repeated execute the code block inside the loop
- The number of times this block runs is dependent on the size of the array in the array assignment
- - specifically, the number of COLUMNS in the array
Example 1 - For Loops
The only thing that changes in this loop is the value of n.
Example 2 - For loops
- Note: The array doesn't have to be called n. Let's call it m this time
How many times will this run?
- i is created before the loop starts
- i increase by 1 on each iteration of the loop because of the mathematical operation inside the loop
- Notice that inside the loop, m is a scalar.
- On each iteration of the loop, the value of m changes
Example 3 - For Loop with any vector
For Loops can be initialize with any type of vector, including a character array.
-
In this example, we run the FOR LOOP with a character array
-
You Try: Increase the number of times this loop loops by increasing the number of letters in the vector
Example 4 - FOR LOOP and Matrices
- The array runs 3 times (only 3 columns)
- The variable o changes to a vector on each iteration
- Very rare that you would ever need to do this, but there it is
Example - Fibonacci sequence
The fibonacci sequence is a very famous sequence that forms the basis for the golden rectangle and commonly occurs in nature, seen in such things as the spirals in seashells and galaxies. Even the Human hand comes very close to creating a Fibonacci Sequence.
The fibonacci sequence in our hand allows for a perfect curl when we clench our fist.
The sequence itself is simple. Every term in the sequence is the sum of the two preceding terms
1 1 2 3 5 8 13 21...
This sequence is the foundation for the Golden ratio ( \(\phi\), Phi, 1.6), which when used in a design, it fosters organic and natural-looking compositions that are aesthetically pleasing to the eye. The Golden Ratio is calculated by dividing the sequential terms in the fibonacci sequence, as follows
$$ \frac{\left(2+3\right)}{3}=1\ldotp 667 $$
$$ \frac{\left(3+5\right)}{5}=1\ldotp 6 $$
$$ \frac{\left(5+8\right)}{8}=1\ldotp 625 $$
and so on
So, how do we build the fibonacci sequence ?
Without a FOR LOOP, it would look something like this:
fib = [1 1] % start with two terms
fib(3) = fib(1) + fib(2) % the third term is the sum of the first two terms
Now you try: Term 5
How would you calculate the fifth term of the fibonacci sequence?
Notice for each term, you sum the previous two elements.
Using a FOR LOP
A FOR LOOP simplifies the process of creating this sequence. Notice that once we get started, the only thing that changes in the code are the two indices that we use to find the last two elements in the array.
If the index is n
, you need the following syntax
For Loops are perfect for automating these simple changes.
fib = [1 1]; % Preallocate terms 1 and 2 with 1 1
for n=3:10 % start with the 3rd term
fib(n) = fib(n-2) + fib(n-1);
disp(fib)
end
- Perfect! It does the exact same thing but all the way up to term 10
- Notice that we had to start by adding 1 and 1 to fs, before the FOR LOOP
- Also notice that the number of terms we end up with is 2 plus the number of loop iterations
We can also use a FOR LOOP to find the golden ratio, which is the Next Term + Current Term divided by the Next Term. In this example, the Current Term is indexed by n
, while the Next Term is indexed by n+1. We stop the loop early (-1), because there is no Next term after the final term.
Preallocation
Great, so we can scale this up and get lots of terms, like the first 102 terms. However, notice the little orange squiggly line under fib
in the previous loop. This is a warning that we should to preallocate (even if we don't want to). Hover over the squiggly line and you will see the warning that I'm talking about
What's the big deal? Well, let's see by timing it. The functions tic and toc start and stop a timer, and then report the time it takes to execute a certain block of code. Let's time the for loop for 100 terms (98 loops)
clearvars
num_terms = 100; % number of terms to generate
tic % start timer (to see how fast the code runs)
fib = [1 1]; % create the first two terms of the sequence
for n=3:num_terms % run the loop 10 times
fib(n) = fib(n-2) + fib(n-1);
end
toc % end timer
disp(fib)
- The problem with this approach to be building the sequence that MATLAB has to create a copy of the array (somewhere in memory) on every iteration of the loop
- the bigger and bigger this array gets, the more and more memory you are going to need to use and the slower the code will run
- You may even run out of memory
Preallocated
Fine, so what do we do? And what does it mean to preallocate anyways?
Preallocation takes a little work. You have to decide beforehand how big your array is going to get.
In the previous example, the array ended up being 2 plus the number of iterations of the FOR loop. Ok, let's use that information
fib = zeros(1,num_terms); % the Preallocation step
fib(1:2) = 1; % fill the first two terms of fs with 1s
- Ok, so now the size of fs is predetermined to be 2 plus the number of the loops
- We used the function zero to create an "empty" array that we will fill on each iteration of the loop
Now we're ready to run the for loop
- Notice here that instead of simply tacking on a new element to fs on each iteration of the loop, we are replacing the 0's in the preallocated array fs with the numbers of the sequence
- Also notice that the orange squiggle is now gone
- Lets compare speeds (change the number of terms to 100 in the non-preallocated block )
Thus,
- If you build matrices inside of a for-loop, it is better to preallocate that matrix with zeros before starting the loop
- This is to save memory and time
While Loops
Sometimes, you don't know when the loop should end.
WHILE Loops keep running until the conditional statement turns FALSE
- So, on every iteration of the loop, it checks the value of a variable towards a logical operation. If the
- Basically, it asks on every loop, 'Are we done yet?, Are we done yet?, ...
This simple while loop replicates the action of a single die, using the function randi. We set the conditional statement to be: "keep rolling until you get a 5.
Example: Craps
In craps, you roll two dice and you want to get a 7
or 11
, I think, most of the time, or something like that. I always forget.
So, this WHILE LOOP will continue to roll the dice until you get a 7
. The dice here being the output from the randi function, with a maximum value of 12 (since we're rolling two dice). Here, we also add a loop reporter, roll
, which starts at 1 and increase by 1 for every roll of the dice.
Try it now:
dice = 0;
roll = 1;
while dice ~= 7
dice = randi([2 12],1,1); % returns random number between 2 and 12
fprintf('Roll %d: %d\n',roll,dice)
roll = roll+1; % increment the dice roll by 1 on every iteration of the while loop
end
Roll your own Black Jack Game
In Black Jack, you are first dealt 2 cards. Then you are asked if you want another card (Hit?). This continues until you don't won't want any more cards, or the sum total of your hand exceeds 21 and you bust.
So, our game must
- Generate the sum for the 1st two cards
- If the sum of the two cards is below 21, ask the User if they want to Hit,
- If they do want to hit, add another card to the total
- If they don't want to hit, end the loop.
Ask if the user wants to Hit
To request input from a user, you can use the function input
:
- Whatever the user inputs is stored in
response
Next, we need a WHILE LOOP to continue until one of the following happens:
- Hand is greater than 21. Bust
- Hand is equal to 21. Black Jack
- Hand is less than 21 and the user does not want any more cards.
- The loop should keep looping until the user stops asking for more cards, or the sum of the cards exceeds 20.
Here we combine the IF ELSE statement with a WHILE LOOP to tackle the above.
keep_playing = true; % initially set to true
hand = randi([2 21],1,1); % simulate a hand of two cards ranging from 2 to 21
while keep_playing % keep going while variable is true
fprintf('Hand = %d. ', hand) % displays the current hand
if hand > 21 % if greater than 21
disp('Ooh, bust. Pay up.');
break % immediately end while loop
elseif hand==21 % if equal to 21
disp('Black Jack!!!');
beep
break % immediately end while loop
else
response = input('Hit?',"s") ; % request Y or N answer
if contains(response,'y','IgnoreCase',true) % if Yes on Hit
hand = hand + randi([1 11]); % add a new card to the hand
else
keep_playing=false;
end
end
end
- What happens When you Enter a 'y'?
- An 'n'?
- How would you add a final accounting for who wins? e.g. 'You Win!' or "Sorry, the Dealer wins' or 'Dealer Busts! you Win!"
So, how do we add 11 as a possibility?
The syntax gets a little convoluted, but basically you need a logical operation that looks for either a 7 or an 11. And then you flip that logic using LOGICAL NOT.
dice = 0;
roll = 1; % keeps track of the loops
while ~(dice == 7 || dice == 11) % the NOT of either 7 or 11
dice = randi([2 12],1,1); % returns random number between 2 and 12
fprintf('Roll %d: %d\n',roll,dice) % reports the results
roll = roll+1; % increment the roll count
end
Functions
Functions are Great ways to package algorithms. Functions are often stored as files. Most of the included MATLAB functions are files.
For example, we can open the mean
function as follows:
Role your own functions
With a function, you just write the code once and you can call it from anywhere in the script. This helps keep your scripts readable and not overly huge. Plus, any updates to the code (like changing the color of the histogram) can be made in the function (not in lines scattered throughout the script).
The syntax to create a function is as follows
The first line contains
- the keyword function
- the output:
out
- the name of the function:
myFirstFunction
- the input:
in
- The last line contains the key word end.
And in between function and end is the code of the function. Notice that there is nothing magic about the code inside a function. It looks just like the code that we use in our scripts. .
Now that we have added this function to this script, we can call it like any other function.
- notice that in and out are not added to the workspace - functions have their own secret workspace
- Function variables are assigned inside the function and deleted when the function is done
- Try it now: modify the function to multiply the input by 10 and re-execute this code block
Creating a Function for the Fibonacci Sequence
Here is the basic code for the Fibonacci Sequence
fib = zeros(1,num_terms); % the Preallocation step
fib(1:2) = 1; % fill the first two terms of fs with 1s
for n=3:num_terms
fib(n) = fib(n-2) + fib(n-1);
end
Package this code into a function with the following properties
- Name of Function:
myFibonacci
Input
: num_terms
- a scalar whole number to indicated how many terms of the sequence to create- Output:
fib
- variable containing the fibonacci sequence up to the number of terms input - Don't forget to add an end at the end
Hot Tip: Highlight all the code in the above code block and then select "Refactor: Convert to Local Function" from the Live Editor tab
Test your function using the following call
- f should contain the first 10 terms in the sequence
f = 1×10 1 1 2 3 5 8 13 21 34 55