Control structures#
Learning goals
After finishing this chapter, you are expected to
use
if
,elif
, andelse
write
while
loopswrite
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.
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
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
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
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.
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
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
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
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.
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.