Preparation#
Reading material#
In the Think Python (TP) book, loops are covered in Chapter 7 Iteration and Search. However, the book shows looping on strings which we have not yet studied, and it only explains for-loops. In this course, we teach both the for-loop and the while-loop. Therefore, this week is better aligned with the lecture notes of the CS50 course, Lecture 2 Loops, first three sections.
No Shortcuts to Learning#
Learning a new skill can be challenging, and for many students, loops mark the first real hurdle. Some may start looking for shortcuts to avoid the hard work.
Everyone learns at their own pace and benefits from different activities. Watching programming videos or reading solutions can be helpful, but they should supplement—not replace—your own practice.
Copy-and-Run#
Prep 4.1: Basic For-loop#
For each of the code blocks below, try to predict what will be printed. Then run the code to see if you were right.
for i in range(3):
print("Hello!")
for i in range(5):
print(i)
for i in range(4):
print(i, "Hello!")
As you can see, writing for i in
makes the code loop (repeat), and the variable i
changes value each time the loop runs. The expression range(4)
specifies which values i
takes. Here, i
is called the iteration variable. It is very common to use i
as the iteration variable, but you can use any variable name you like.
Sometimes we use the iteration variable in the loop body, but sometimes we don’t. Look again at the examples above and see which of them use the iteration variable in the loop body.
Now look at the two code blocks below. What is the difference between them and how does it affect the output? Try to predict what will be printed. Did you get it right?
for iter in range(7):
print("Hello!")
print("Counting", iter)
for iter in range(7):
print("Hello!")
print("Counting", iter)
Prep 4.2: The range
function#
The range
function generates a sequence of numbers. To learn about range
, start by looking at the text printed by the following code.
for i in range(1, 11, 2):
print(i)
Now make changes to the code, run it again, and observe the result. Change the range
and its arguments to:
range(0, 11, 2)
range(12, 5, -1)
range(8, 3, -2)
range(3, 8)
range(4, 40, 4)
As you can see, the range
function can take either 1, 2, or 3 arguments. The names of arguments are start
, stop
, and step
. Based on your observations, answer the following questions:
If only one argument is given, which one is it? What value is used for the other two?
If two arguments are given, which ones, and in what order? What value is used for the third one?
If three arguments are given, which ones, and in what order?
Will the value of
stop
be reached?
Hint
range(stop)
is the same asrange(0, stop, 1)
.range(start, stop)
is the same asrange(start, stop, 1)
.range(start, stop, step)
range
will stop before reaching the value ofstop
.
Try now the following values:
range(0)
range(3, 3)
range(6, 2)
range(1, 8, -2)
range(0, 0, 0)
What can you conclude?
Hint
Range may be empty.
With this knowledge, change the arguments you give to range
such that the code:
Prints numbers from 1 to 10:
1
,2
, …,10
.Prints even numbers from 0 to 10:
0
,2
,4
, …,10
.Prints a countdown from 10 to 0:
10
,9
, …,0
. You can use a negative step size.Prints numbers:
17
,21
,25
,29
. You can use an appropriate step size.Prints multiples of 5:
0
,5
,10
,15
, …,45
,50
.Does not print anything.
Prep 4.3: More range
examples#
Often, you will not give specific numbers to start
, stop
, and step
but rather the variables and expressions from which the values are computed. Predict the output of the following blocks, and then run it to see if you were right.
i = 2
b = 7
for k in range(i, b):
print('Hello', k)
for j in range(i, i + b):
print('Hi', j)
for a in range(b - i, b):
print('Bye', a)
my_name = 'Marianne'
for i in range(len(my_name)):
print('Hi ' + my_name)
Now try guessing the output of the following code.
a = 16
b = 2
for i in range(a/b):
print(i)
Was this surprising? What can you conclude about the range
function? What data type it expects as arguments?
Hint
If you give range
a float, it will not work.
Compare the text printed by the three loops below.
for a in range(3):
print(a * 22 + 55)
for a in range(45, 0, -22):
print(100 - a)
for a in range(55, 100, 22):
print(a)
You can see that range arguments and formulas inside the loop can be used creatively to achieve the same result in different ways.
Prep 4.4: Using the Iteration Variable#
For each of the code blocks below, try to predict what will be printed. Then run the code to see if you were right.
for j in range(3):
print(j ** 2)
for k in range(6):
print(2*k+1)
for times in range(1, 6):
greeting = "Hello! " * times
print(greeting)
import math
for n in range(2, 7):
s = math.sqrt(n)
print("The square root of", n, "is", s)
As you can see, you may use the iteration variable in expressions inside the loop body to compute other values.
What is the iteration variable in each of the examples? For all the examples above, try to predict which variables are defined after the loop is executed, and what their values are. Test your predictions by running the code. What is greeting
after the loop in the second example? What is s
after the loop in the third example? You can add extra print statements after the loop to test the different variables. Remember to remove the indentation when you want to add lines of code outside the loop.
Prep 4.5: Collecting Values#
For each of the following blocks, try to predict what the code does. Which variables are defined after the loop is executed, and what are their values? Run the code to see if you were right. You can add more print statements to test more variables.
current_sum = 0
for element in range(1, 11):
current_sum = current_sum + element
print(current_sum)
text = ""
for n in range(10):
text = text + str(n) + " "
print("After the loop, text is:")
print(text)
current_sum = 0
for i in range(1, 11):
s = i ** 2
print("Square of", i, "is", s)
current_sum = current_sum + s
print("The sum of squares is", current_sum)
As you can see, we may use loops to collect something, like summing numbers or concatenating strings. For this, we need to initialize a variable before the loop, and then repeatedly update it inside the loop.
Remember from our topic on variables, then when we write x = x + 1
we overwrite the x
variable with the new value, where we have added 1.
Prep 4.6: Basic While-loop#
For each of the code blocks below, try to predict what will be printed. Then run the code to see if you were right.
x = 0
while x < 10:
print(x)
x = x + 1
print("We are done and x is", x)
x = 10
while x > 0:
print(x)
x = x - 2
print("We are done and x is", x)
x = 1
while x <= 1000:
print(x)
x = x * 2
print("We are done and x is", x)
The while-loop will keep running as long as the condition is True
.
For each of the examples above, identify the condition.
Identify the value of
x
before the loop is executed.What is the value of the condition before the loop is executed?
Identify the value of
x
after the loop is executed.What is the value of the condition after the loop is executed?
Try changing the condition in the loops above so that the loop runs exactly 2 times.
Prep 4.7: Be Careful with While-loops#
Now, try running this code.
x = 10
while x < 5:
print(x)
x = x + 1
print("We are done and x is", x)
As before, identify the value of
x
before and after the loop is executed.What is the value of the condition before and after the loop is executed? If the condition is not
True
before the loop is executed, the loop will not run at all!
You can also create a loop that will never end, a so-called infinite loop. Before you try that, you should know how to force a running program to stop.
Try to run the following infinite loop, and stop it by pressing ctrl+C or ⌘+C, which will result in a KeyboardInterrupt
error.
j = 0
while True:
print(j)
j = j + 1
Warning
Certain versions of Python have a bug where the IDLE window freezes during an infinite loop, so it no longer responds to ctrl+C. If this happens, you can close the IDLE window and open it again. When we move to VS Code next week, this will not be an issue.
It happens that you sometimes accidentally create an infinite loop. Below, an example of an accidental infinite loop is given. Why will it never stop? Add a print
statement to see the value of x
in each iteration to figure out why it will never stop. Change just one character in the code to make the loop stop after 10 iterations.
x = 0
while x < 10:
print("I'm running!")
x = x - 1
Prep 4.8: More While-loops#
For each of the code blocks below, try to predict what will be printed. Then, run the code to see if you were right.
text = 'abe'
while text == 'abe':
text = text + 'a'
print(text)
text = 'abracadabra'
s = ''
while len(s) < len(text):
s = s + 'a'
print(s)
Prep 4.9: Breaking Loops#
Try to predict what the following code does, then run it to see if you were right.
for i in range(100):
print(i)
if i >= 5:
print("I am tired of looping!")
break
max_iterations = 100
i = 0
while i < max_iterations:
print(i)
if i >= 10:
break
i = i + 1
If you want to exit a loop before it is finished, you can use the break
statement.
Prep 4.10: Doing Something Once#
Run the following code to see what it does. Try to predict what the code does before running it.
balance = 950
meal_cost = 100
waiting = True
for day in range(100):
balance = balance - meal_cost
if balance < 0 and waiting:
print("The balance is negative after", day, "days.")
waiting = False
print("Final bank balance", balance)
Often, you want to do something in just one iteration, even if a loop keeps going. This can be done by using a boolean variable to keep track of whether this has already been done. In the example above, once waiting
becomes false, the message will not be printed again, despite the balance still being negative.
Prep 4.11: Nested Loops#
Try to predict what the following code does, then run it to see if you were right.
for i in range(2):
for j in range(3):
print(i, j)
x = 0
for i in range(5):
for j in range(6):
x = x + 1
print("x is", x)
Loops may be nested, similar to nested if
statements.
Now look carefully at this nested loop, and try to predict how many lines will be printed. Run the code to confirm.
for i in range(4):
for j in range(i):
print(i, j)
If you are unsure about what this code does, it is a good idea to add some print statements to see when the loop body is entered and exited. For the last example, you could add print statements to get the code below. Try running it and see if it prints as you expected.
for i in range(4):
print("*-*-*-* START OF OUTER LOOP *-*-*-*")
for j in range(i):
print("*-* START OF INNER LOOP *-*")
print(i, j)
As you can see, the first time the outer loop is entered, the inner loop is not entered at all. The second time the outer loop is entered, the inner loop is entered once, and so on. The last time the outer loop is entered, the inner loop is entered three times.
You can also use Python Tutor to visualize the flow of control. You can copy code from any exercise, paste it into Python Tutor, and run it to observe how the lines get executed.
Prep 4.12: Bad For-loop Practices#
In for-loops, the iteration variable gets updated automatically for each iteration. It is a bad practice to change the value of the iteration variable inside the loop. This can lead to unexpected behavior. Try to predict what the following code does, then run it to see if you were right.
for i in range(5):
print(i)
i = i + 100 # This is bad practice!
print(i)
print("The value of i after the loop is", i)
Another bad practice is to use the same variable name in nested loops. Run the code below to confirm that the code runs, but it may be difficult to understand how the value of i
changes.
for i in range(1, 3):
print(i)
for i in range(11, 13): # This is bad practice!
print(i)
Prep 4.13: Debug Loops#
Below we have several examples, which all contain syntax errors that will prevent the code from running.
For all the examples below, first try to find the error by reading the code. Then run the code to see what happens. Carefully read the error message. Finally, try to fix the error. We have provided hints for fixing the error, but you should try to fix the error without looking at the hints first.
for i range(5):
print(i)
Hint
The keyword in
is missing between i
and range(5)
.
for i in range(5):
x = x + 1
Hint
You need to define x
(preferably outside the loop, e.g., x = 0
) before you can use it.
month = "January"
for i in range(4, 14):
# I don't care for all dates
print("Today is the "+str(i)+"th of " + month)
Hint
The body of the loop (indented code block) cannot be empty; comments do not count.
Prep 4.14: Predict the Outcome#
For each of the loops below, predict:
How many lines will be printed?
What will be printed on each line?
Then run the code to see if you were right.
i = 5
for _ in range(3):
print("Print A", i)
i = 5
for i in range(3):
print("Print B", i)
for i in range(1, 10, 5):
print("Print C", i)
for i in range(5):
if i % 2 == 0:
print("Print D", i)
x = 0
while x <= 10:
x = x + 1
if x > 8:
print("Print E", x)
x = -1
while x < 99:
x = x + 1
if x == 1:
break
print("Print F", x)
x = -1234
while x < 0:
x = x + 1
print("Print G", x)
x = 0
while x < 0:
x = x + 1
if x == 0:
print("Print H", x)
break
a = 0
b = 0
while a < 5 and b < 5:
if a < b:
a = a + 1
else:
b = b + 1
print("Print I", a, b)
Self quiz#
Question 4.1#
What happens when running the following code?
for i in range(5):
a = i
print(a)
Question 4.2#
How many lines will the following code print?
for i in range(1, 10):
print("Do something")
Question 4.3#
Which is identical to range(5)
?
Question 4.4#
After the following code is executed, what is the value of x
?
x = 0
for i in range(5):
x = x + i
Question 4.5#
How many times will Please no spam :(
be printed by the following code?
for i in range(3):
for j in range(2):
print("Please no spam :(")
Question 4.6#
How many lines will the following code print?
x = 0
while x < 5:
x = 2 * x
print("Do something")
Question 4.7#
What is the value of text
after the following code is executed?
text = "Hello "
for r in range(1, 3):
text = r * text
Question 4.8#
Which values will m
have during the execution of the following code?
a = 3
b = 6
for m in range(min(a, b), max(a, b)):
print(m)
Question 4.9#
How many lines will the following code print?
x = 5
for i in range(10):
if i > x:
break
print("Do something")
Question 4.10#
What is the value of x
after the following code is executed?
x = 999
for x in range(5):
break
Question 4.11#
What is the value of x
after the following code is executed?
x = 3
while x > 0:
x = x - 1
Question 4.12#
What is the value of i
after the following code is executed?
i = 0
while len(str(i)) < 5:
i = i + 1
Question 4.13#
What will be printed by running the following code?
num = 1
while True:
num = num + 1
if (num % 5) == 1:
break
print(num)
Question 4.14#
Which numbers will be printed by the following code?
a = 2
b = 5
for i in range(a, b + 1):
print(i)
Question 4.15#
How many times will the following code print Hi Alice
?
name = "Alice"
for i in range(len(name)):
print('Hi ' + name)
Question 4.16#
Which value will s
have after the following code is executed?
s = ''
for i in range(1, 6):
s = s + str(i)
Question 4.17#
How many lines will be printed by the following code?
for i in range(5):
if i % 2 == 0:
print("I've been executed")
Question 4.18#
What is the value of the variable x
after the following code is executed?
x = 0
while (0 < x) and (x < 10):
x = x + 1
Question 4.19#
How many lines will the following code print?
x = 0
while x < 4:
x = x + 1
print(x)
Question 4.20#
What is the value of x
after the following code is executed?
x = 0
while x < 109:
x = x + 2