Control structures#

Learning goals

After finishing this chapter, you are expected to

  • use if, elif, and else

  • write while loops

  • write for loops

Conditional statements with if#

Now that you are able to write and run scripts in VS Code, it is time to do some more interesting programming. So far, your scripts have been quite predictable. They are a series of statements that are executed from top to bottom, i.e., sequential execution. One nice feature of almost all programming languages is that they allow the use of control structures that direct the execution of your program. One of the most commonly used control structures is the conditional statement if. An if statement looks like this:

if <expr>:
    <statement>

Here, <expr> is a boolean expression, i.e., something that takes on the value True or False. The <statement> is a valid Python statement, something that will be executed if <expr> evaluates to True. The colon : is part of the Python syntax and should always be placed after the boolean expression. Further, note that there is some whitespace in front of the <statement>. This is called indentation and is also part of the Python syntax. Python uses four spaces as indentation. You usually don’t have to care of this yourself: the interpreter and any IDE that knows that you’re programming in Python will help you automatically use that indentation when necessary.

To get a better feeling about the behavior of the if-statement, take a good look at the following code examples. Note that the interpreter only prints yes if the <expr> is True. Otherwise, nothing happens. Also, note that if y gets evaluated to True. This is so because Python evaluates any non-zero integer as True (we have also seen this in the first chapter).

x = 0
y = 5

if x < y:           # True
    print('yes')      
yes
if y < x:           # False
    print('yes')    
if x:               # False
    print('yes')    
if y:               # True
    print('yes')    
yes

In the first chapter, you have used the and, or and not logical operators that evaluate to a boolean. You can also use these in the expression of your if statement, as in the examples below.

if x or y:          # True
    print('yes')    
yes
if x and y:         # False
    print('yes')    
if not x:           # True
    print('yes')
yes

Blocks#

The <statement> that follows an if condition in Python does not necessarily have to be just one line of code. In fact, you can add a block or suite of statements after your if condition. As long as you stay at the same indentation level, these will be jointly executed with the first statement. For example, based on the cases above, we could have the following piece of code:

if y: 
    print('y')
    print('is a non-zero integer')
    print('so I will print')
    print('yes')
y
is a non-zero integer
so I will print
yes

Here, all the print statements form a block of code at the same indentation level. Within a block, you can have additional if statements. For example, instead of writing if x and y: as we did above, you could also write the following to get the exact same behavior. Notice that now we have added two levels of indentation.

if x:
    if y:
        print('yes')

Blocks can be nested to arbitrary depth, and depending on the expressions, some lines will be executed while others won’t.

Exercise 3.1

One of the lines in the following code is not executed. Which line is it?

if 'foo' in ['foo', 'bar', 'baz']:       
    print('Outer condition is true')      

    if 10 > 20:                           
        print('Inner condition 1')        

    print('Between inner conditions')     

    if 10 < 20:                           
        print('Inner condition 2')        

    print('End of outer condition')       
print('After outer condition')            

Opdracht 3.1

Één van de regels in onderstaand voorbeeld wordt niet uitgevoerd. Welke regel is dit?

if 'foo' in ['foo', 'bar', 'baz']:       
    print('Outer condition is true')      

    if 10 > 20:                           
        print('Inner condition 1')        

    print('Between inner conditions')     

    if 10 < 20:                           
        print('Inner condition 2')        

    print('End of outer condition')       
print('After outer condition')            

else and elif#

As you might expect, where there’s an if there can also be an else. This else is an expression which is evaluated as the opposite of the if expression. The statement following this expression is what gets executed if the expression following if is evaluated to be False.

For example, take the following piece of code. In this case, the expression following if is obviously False, so the statement following else will be executed and ‘smaller’ will be printed.

if 10 > 20:
    print('larger')
else:
    print('smaller')
smaller

A third kind of expression is the elif or ‘else if’ expression that can be used in case there are more than two possible outcomes. Following an if expression, you can have any number of elif expressions that you desire, potentially followed by an else statement. Note that if the expression following if is True, none of the other expressions will actually be checked. Similarly, as soon as one of the elif conditions is true, the other conditions will not be checked. The following provides an example of using if, elif and else.

language = 'french'
if language == 'english':
    print('hello')
elif language == 'dutch':
    print('hallo')
elif language == 'french':
    print('bonjour')
else:
    print('unknown language')
bonjour

Exercise 3.2

In each of the following equations, evaluate the given code fragments. Investigate each of the fragments for the various starting values. Use Python to check your answer.

  1. What is the value of m if
    a) n = 7
    b) n = 0
    c) n = -7 ?

        if n > 1:
            m = n + 2
        else:
            m = n - 1
    
  2. What is the value of t if
    a) s = 1
    b) s = 7
    c) s = 57
    d) s = 300

    if s <= 1:
        t = 2*s
    elif s < 10:
        t = 9 - s
    elif s < 100:
        t = s**2
    else:
        t = s
  1. What is the value of h if
    a) t = 50
    b) t = 19
    c) t = -6
    d) t = 0

    if t >= 24:
        h = 3*t + 1
    elif t < 9:
        h = t**2/3 - 2*t
    else:
        h = -t
  1. What is the value of y if
    a) x = -1
    b) x = 5
    c) x = 30
    d) x = 56

    if 0 < x < 7:
        y = 4 * x
    elif 7 < x < 55:
        y = -10 * x
    else:
        y = 333

Opdracht 3.2

Bekijk de vier stukjes Python-code hieronder. Geef met behulp van Python antwoord op de vier vragen die bij elk stukje code staan.

  1. Wat is de waarde van m als
    a) n = 7
    b) n = 0
    c) n = -7 ?

        if n > 1:
            m = n + 2
        else:
            m = n - 1
    
  2. Wat is de waarde van t als
    a) s = 1
    b) s = 7
    c) s = 57
    d) s = 300

    if s <= 1:
        t = 2*s
    elif s < 10:
        t = 9 - s
    elif s < 100:
        t = s**2
    else:
        t = s
  1. Wat is de waarde van h als a) t = 50
    b) t = 19
    c) t = -6
    d) t = 0

    if t >= 24:
        h = 3*t + 1
    elif t < 9:
        h = t**2/3 - 2*t
    else:
        h = -t
  1. Wat is de waarde van y als a) x = -1
    b) x = 5
    c) x = 30
    d) x = 56

    if 0 < x < 7:
        y = 4 * x
    elif 7 < x < 55:
        y = -10 * x
    else:
        y = 333

Exercise 3.3

A bank will offer a customer a loan if they are 21 or over and have an annual income of at least €21000. Write a Python script that contains the customer’s age and income in a dictionary. Depending on the age and income, one of the following lines should be printed (using the print function):

  • ‘We are able to offer you a loan.’

  • ‘Unfortunately at this time we are unable to offer you a loan.’

Verify your code by testing with

  • A 40-year old man with an annual income of €11000

  • A 18-year old woman with an annual income of €25000

  • A 30-year old woman with an annual income of €40000

  • A 15-year old boy with an annual income of €5000

Opdracht 3.3

Een bank geeft alleen leningen aan klanten die minstens 21 jaar zijn en een jaarinkomen hebben van tenminste €21000.

Schrijf een Python script waarin je de leeftijd en het inkomen van de klant in een dictionary zet (zie vorige hoofdstuk). Afhankelijk van de leeftijd en het inkomen van de klant in de dictionary, moet het script één van de volgende twee regels printen met de print functie.

  • ‘We kunnen u een lening geven’

  • ‘Helaas kunnen we u op dit moment geen lening geven’

Controleer of je script goed werkt door dictionaries te maken voor

  • Een 40-jarige man met een jaarinkomen van €11000

  • Een 18-jarige vrouw met een jaarinkomen van €25000

  • Een 30-jarige vrouw met een jaarinkomen van €40000

  • Een 15-jarige man met een jaarinkomen van €50000

Exercise 3.4

Write a Python script that asks the user for two numbers and prints ‘The first number can be divided by the second number’ or ‘The first number cannot be divided by the second number’, depending on which is the case.

Tip: Use them modulo operator and theinput en print-functions from the first chapter.

Opdracht 3.4

Schrijf een Python script dat de gebruiker vraagt om twee getallen en afhankelijk van de situatie één van de volgende twee zinnen laat zien

  • ‘Het eerste getal kan zonder rest worden gedeeld door het tweede getal’

  • ‘Het eerste getal kan alleen met rest worden gedeeld door het tweede getal’

Tip: Gebruik de modulo-operator en de input en print-functies uit het eerste hoofdstuk.

Conditional expression

In addition to the syntax above, Python offers a compact way of writing binary if/else statements. This is called a conditional expression or ternary operator and means that the expression

if 10 > 20:
    print('larger')
else:
    print('smaller')

can also be written in one line of code as

print('larger') if 10 > 20 else print('smaller')

It can in some cases be useful two write expressions like this, for example when you want to compactly assign a value to a variable.

coat = 'raincoat' if raining else 'jacket'

while loops#

Iteration control structures, loops, are used to repeat a block of statements until some condition is met. Python supports two types of loops: the while-loop and the for-loop. A while loop executes some statement as long as a condition is True. We call each time that the statement below while is executed an ‘iteration’. As soon as the condition is False the loop will stop iterating.

a = 1
while a < 10:
    print(a)
    a += 2

The animation below nicely visualizes how a while loop works in this piece of code. As you can see, the while statement is checked at the beginning of each iteration. If that is the case, the block below the while statement is executed. If not, the loop ends.

whileloop

You can use while loops for situations in which you do not know beforehand how many iterations you need. For example, we can write a script that uses a while loop to create the longest possible list of even numbers that together are less than 40.

even_sum = 0
n = 0
even_numbers = []


while even_sum < 40:
    even_sum += n
    even_numbers.append(n)
    n += 2

print(even_sum)
print(even_numbers[:-1])
42
[0, 2, 4, 6, 8, 10]

If you look closely at this example, you can see that even_sum is actually larger than 40. This is so because at the moment that even_sum < 40 became False (and the loop stopped), the last number n=12 had already been added to even_numbers. Hence, we have to use slicing to exclude the last number in the print statement.

We could prevent this by using an if expression and a break statement. Once Python encounters a break, it immediately exits whatever loop it is in. In this case, the code could be changed to the following.

even_sum = 0
n = 0
even_numbers = []

while even_sum < 40:
    if even_sum + n >= 40: # Check if adding the current number n would let even_sum exceed 40
        break              # If that is the case, get out of the loop immediately
    else:                  # If not, continue looping
        even_sum += n
        even_numbers.append(n)
        n += 2 
print(even_sum)        
print(even_numbers)
30
[0, 2, 4, 6, 8, 10]

In addition to break, Python also contains a continue statement. If Python encounters a continue statement, it stays in the loop, but ends the current iteration. In our example, imagine that (for some reason) we do not want to include a number n if it can be divided by 6. Then we can add an elif statement to check this condition and skip the current iteration if the condition is met.

even_sum = 0
n = 0
even_numbers = []

while even_sum < 40:
    if even_sum + n >= 40: # Check if adding the current number n would let odd_sum exceed 40
        break              # If that is the case, get out of the loop immediately
    elif n % 6 == 0:       # If the number n can be divided by 6
        n += 2             # Increment the number
        continue           # Move on to next iteration
    else:                  # If neither condition is met, continue looping
        even_sum += n
        even_numbers.append(n)
        n += 2 
print(even_sum)  
print(even_numbers)
38
[2, 4, 8, 10, 14]

Infinite loops

A while loop will continue running as long as its condition is True. That means that it’s also possible to make an infinite loop that causes your code to get stuck. For example, the following code will run forever if you don’t stop it.

while True:
    print('Running')

If you make such a loop, always make sure that there is also a break statement inside (in combination with an if) so you an actually exit the loop. If you accidentally do end up in an infinite loop, you can in most terminals use Ctrl + c to shut down your script.

Exercise 3.5

Write a script that determines the largest integer \(n\) for which \(1^3 + 2^3 + \cdots + n^3\) is less than 2000. Use a while loop in this script. Use the code below as as basis.

total = 0
n = 0

while <fill_in>:
    total = <fill_in>
    n = <fill_in>
    
print(<fill_in>)

Opdracht 3.5

Schrijf een script dat de grootste integer \(n\) bepaald waarvoor \(1^3 + 2^3 + \cdots + n^3\) kleiner is dan 2000. Gebruik een while-loop in dit script. Je kunt onderstaande code als startpunt gebruiken.

total = 0
n = 0

while <fill_in>:
    total = <fill_in>
    n = <fill_in>
    
print(<fill_in>)

Exercise 3.6

Write a guessing game where the user has to guess a secret number. After every guess the program tells the user whether their number was too large or too small. At the end of the game, the number of tries needed by the user should be printed.

Start your script with the following code to define the secret number:

import random

secret_number = random.randint(0, 50)
number_guessed = False
n_guesses = 0

# The rest of your code goes here
while <fill_in>:
    <fill_in>
    
print(f'You needed {n_guesses} guesses!')

Opdracht 3.6

Schrijf een spel waarbij de menselijke speler een geheim getal moet raden. De speler mag raden wat het getal is, waarna de computer zegt of het echte getal hoger of lager is. Aan het eind van het spel krijgt de speler te zien hoeveel beurten hij of zij nodig had. Je kunt onderstaande code gebruiken als startpunt.

import random

secret_number = random.randint(0, 50)
number_guessed = False
n_guesses = 0

# The rest of your code goes here
while <fill_in>:
    <fill_in>
    
print(f'You needed {n_guesses} guesses!')

for loops#

In contrast to a while-loop, for which the number of iterations is not defined, in a for-loop the number of iterations is fixed upon entering the loop. The standard for-loop has general syntax

for item in <sequence>:
    do something 

Here, <sequence> can be a list, set, tuple, dictionary, or string. For example, we can print all elements in the list [1, 2, 3, 5, 8] as follows

for item in [1, 2, 3, 5, 8]:
    print(item) 
1
2
3
5
8

The for-loop iterates over something which we call an iterable: an object that is able to return its items one-by-one until no more items remain. For example, if we want to print ‘Hello world’ five times, we can make a list with five items (here digits) and iterate over that list.

for item in [1, 2, 3, 4, 5]:
    print('Hello world')
Hello world
Hello world
Hello world
Hello world
Hello world

Note that in the example above, we actually don’t do anything with the items in the list. We have here used integers in ascending order, but basically any item of any type will do. In contrast to other programming languages, Python does not use these integers as indices unless you want it to do so. We do have to give a name to the variable that holds the value coming from the list, but we could also use the ‘throwaway’ variable name _. To illustrate this, the previous result could also have been obtained with strings in a list.

for _ in ['person', 'woman', 'man', 'camera', 'tv']:
    print('Hello world')
Hello world
Hello world
Hello world
Hello world
Hello world

Now let’s say that we want to do something a 1000 times. For example, add all integers between 0 and 1000. You can imagine it would be very cumbersome to write out a list with 1000 integers to iterate over. Luckily, the built-in range(start, stop, step) function in Python returns an iterable that provides numbers from start to stop with an interval of step. Now, to print ‘Hello world’ 5 times, we simply use.

for _ in range(0, 5, 1): 
    print('Hello world')
Hello world
Hello world
Hello world
Hello world
Hello world

The arguments of the range function work very similar to slicing that you have seen for lists and tuples. The function returns integers up to but not including the stop argument. Moreover, step sizes can be negative. Take a look at the following examples.

for digit in range(0, 5, 1):
    print(digit)
print('---')

for digit in range(1, 9, 2):
    print(digit)
print('---')

for digit in range(9, 2, -1):
    print(digit)
0
1
2
3
4
---
1
3
5
7
---
9
8
7
6
5
4
3

As mentioned above, your for loop can iterate over lists, tuples, sets, dictionaries, and strings. For example, we can loop over the letters in a string.

some_string = 'coffee'
for letter in some_string:
    print(letter)
c
o
f
f
e
e

break and continue

Just like in a while loop, you can use break and continue to exit the loop or skip iterations in a for loop.

Exercise 3.7

Use a for loop to compute the sum of all odd numbers smaller than 100. Tip Use range with a step size of two.

Opdracht 3.7

Gebruik een for-loop om de som van alle oneven getallen onder de 100 te bepalen. Tip Gebruik range met een stapgrootte van twee.

Nested loops#

Just like we can nest conditional statements in blocks, we can also nest loops. For example, we can generate a multiplication table for numbers 1 to 5 with two nested loops.

for i in range(1, 6):
    row = []
    for j in range(1, 6):
        row.append(i*j)
    print(row)
[1, 2, 3, 4, 5]
[2, 4, 6, 8, 10]
[3, 6, 9, 12, 15]
[4, 8, 12, 16, 20]
[5, 10, 15, 20, 25]

There are no restrictions on kinds of loops that you nest: a for loop can contain a while loop and vice versa. Moreover, there are no restrictions on the number of loops that you nest (or the depth). You can, for example, nest three loops as follows.

for i in range(3):
    j = 0
    while j < 7:
        for k in range(2):
            print(i, j, k)
            j = j + 2
0 0 0
0 2 1
0 4 0
0 6 1
1 0 0
1 2 1
1 4 0
1 6 1
2 0 0
2 2 1
2 4 0
2 6 1

Simultaneously looping over two sequences#

Sometimes you might want to loop over two sequences at the same time. An easy example is pairwise multiplication of two vectors: the aim is to compute a new vector in which each element is the product of the elements in the two input item at the same index. For this, you can use the zip function that you have seen before and that acts like a zipper conjoining two lists. See below for an example

vector_a = [3, 6, 5] # Define an input vector as a list
vector_b = [2, 4, 8] # Define a second input vector
vector_c = []        # Define an output vector 

for elem_a, elem_b in zip(vector_a, vector_b): # Jointly iterate over the two input vectors
    vector_c.append(elem_a * elem_b)           # Append product of elements to output vector
    
print(vector_c)
[6, 24, 40]

Exercise 3.8

Write a script that uses a for loop to compute Fibonacci numbers (as in Exercise 1.12). The script asks the user how many numbers should be computed. This can be any number, so your code should be able to deal with this.

Opdracht 3.8

Schrijf een script dat een for-loop gebruikt om Fibonacci numbers te berekenen (zoals in Opdracht 1.12). Het script vraagt de gebruiker eerst hoeveel nummers berekend moeten worden en berekent dan de reeks.