Skip to content

Control Flow and Functions

The building blocks of programming

Table of Contents

Control Flow and Functions

Script Editor

  reset MATLAB

Control Flow

If, Else Statement

Example - IF ELSE

IF, ELSEIF Statement

Example - ELSEIF

Switch Case

Example - SWITCH CASE

  And now, this...

LOOPS

For Loops

  Example 1 - For Loops

  Example 2 - For loops

  Example 3 - For Loop with any vector

  Example 4 - FOR LOOP and Matrices

Example - Fibonacci sequence

   So, how do we build the fibonacci sequence ?

   Using a FOR LOP

  Preallocation

  Preallocated

While Loops

  Example: Craps

  Roll your own Black Jack Game

   Ask if the user wants to Hit

Functions

  Role your own functions

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:

  • Home: Preferences : Color

reset MATLAB

clc % this clears the command window
clearvars % this clears the workspace

Control Flow

If, Else Statement

image_0.png

  • 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:

  1. Assign an integer to the variable x
  2. If the x is ODD, display 'x is odd'
  3. 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)

    x = 5
    if mod(x,2)
        s = 'odd';
    else
        s = 'even';
    end
    fprintf('x is %s',s)
    

  • 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

image_1.png

  • 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

image_2.png

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).

hand = randi([2 30],1,1) % simulate a hand ranging from 2 to 30
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

image_3.png

  • 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...

web("https://www.youtube.com/watch?v=nrhD8JPn7Vo")

LOOPS

clc
clearvars

For Loops

image_4.png

  • 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.

for n = 1:10
    fprintf('This is loop run #%d\n',n); % runs 10 times
end
fprintf('fin.');

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 = 1;
for m = 2:2:10
    fprintf('On loop run #%d, m = %d\n',i, m)
    i = i+1;
end
  • 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

    for n='a':'f'
        fprintf('The current iterated letter is %s\n',n)
    end
    

  • 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

mat = reshape(1:9,3,3)

for o = mat
    display(o)
end
  • 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.

image_5.pngimage_6.pngimage_7.png

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

SciFri - Fibonacci sequence

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
fib(4) = fib(2) + fib(3) % the fourth term is the sum of elements 2 and 3 in the array

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

n=6 % current term
fib(n) = fib(n-2) + fib(n-1)

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.

for n=1:numel(fib)-1
    (fib(n+1)+fib(n))/fib(n+1)
end

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

tic;
for n=3:num_terms
    fib(n) = fib(n-2) + fib(n-1);
end
toc
disp(fib)
  • 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.

die = 0;
while die ~= 5
    die = randi(6,1,1)
end
  • notice, for this to work, you create the variable die before the start of the loop

Example: Craps

image_8.png

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

  1. Generate the sum for the 1st two cards
  2. If the sum of the two cards is below 21, ask the User if they want to Hit,
  3. If they do want to hit, add another card to the total
  4. 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:

response = input('Hit?',"s") % the second input "s" means to request a character
  • Whatever the user inputs is stored in response

Next, we need a WHILE LOOP to continue until one of the following happens:

  1. Hand is greater than 21. Bust
  2. Hand is equal to 21. Black Jack
  3. Hand is less than 21 and the user does not want any more cards.
  4. 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
dealer = randi([17 26],1,1) % dealer must hit on 16 or lower
  • 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

image_9.png

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:

open mean.m

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

function out = myFirstFunction(in)
in = in + 10;
out = in;
end

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.

clearvars
b = myFirstFunction(20)
  • 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

  1. Name of Function: myFibonacci
  2. Input : num_terms - a scalar whole number to indicated how many terms of the sequence to create
  3. Output: fib - variable containing the fibonacci sequence up to the number of terms input
  4. 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 = myFibonacci(10)
  • f should contain the first 10 terms in the sequence
f = 1×10
     1     1     2     3     5     8    13    21    34    55