6.2. Loops#

Loops are a construction in a programming language that allows you to execute the same piece of code repeatedly. In Python, there are two types of loops: while loops and for loops. We will look at while loops first and then move on to the more common for loops.

6.2.1. The while loop#

Using the while command you can specify that a block of code gets executed over and over again, until a certain condition is satified (as the word “while” suggests):

while expression:
    code that gets executed

As long as expression is true, the code block will be executed over and over again.

This is a simple example where we use a while loop to count to 10:

i = 1
while i <= 10:
    print(i)
    i = i+1

In the code above:

  • In line 1, we first set the value of variable i to 1.

  • In line 2, we initiate the while loop and tell Python to execute the code (lines 3 and 4) as long as i is less than or equal to 10.

  • In line 3, we print the current value of i.

  • In line 4, after printing the current value of i, we increase i by 1 (e.g., in the first round of execution of while loop, i = 1, so i = i + 1 = 1 + 1 = 2 will set i to 2); because i = 2 is less than 10, another round of line 3 and 4 code execution takes place, and so on.

In the next example, we use a while loop to add up all the numbers between 1 and 10:

i = 1
s = 0

while i <= 10:
    s = s+i
    i = i+1

print("Sum is", s)

Note that with while loops, you have to be careful to make sure that your code block does something that results in your expression becoming False at some point. Otherwise, the loop will run forever.

For example, when we initially wrote the above cell to calculate the sum, we forgot the i = i + 1 line of code:

i = 1
s = 0

while i <= 10:
    s = s + i

print("Sum is", s)

This code will never finish: it will go into an infinite loop. Note that in such cases we have to manually stop the code execution or it will run forever…

Debugging while loops

If your code doesn’t seem to stop running, you may need to debug your code to see where your mistake is. A handy way to do this is to add a print() statement inside your while loop: it will enable you to see if your variable is doing what you think it should be doing.

Indentation matters

In Python programming, it’s important not only in which order you write your code lines, but also how you use indentation! In the example above, if print("Sum is", s) and print("i is", i) were indented, Python would think they’re also part of the while loop. Therefore, in every loop iteration, they would also get executed. Try it!

6.2.1.1. When to use a while loop?#

For both examples above, one would typically use a for loop, which we will explore below. One scenario in which while loops are very useful is when you don’t know ahead of time how many iterations of the loop you will need.

For example, let’s consider the following sum:

\[ S(n) = \sum_{i=1}^n i^2 + i \]

Let’s say we want to know for which \(n\) the sum exceeds 30. We can easily check this with a while loop:

i = 1
s = 0

while s < 30:
    s += i*i + i
    i += 1

print("Sum is", s)
print("i is", i)

Tip

In this code we used a new operator +=. This is a special assignment operator that increments the variable by the specified amount. a += 1 is equivalent to a = a + 1. This saves a bit of typing and looks neat.

# Your code here
import micropip
await micropip.install("jupyterquiz")
from jupyterquiz import display_quiz
import json

with open("questions8.json", "r") as file:
    questions=json.load(file)
    
display_quiz(questions, border_radius=0)

6.2.2. The for loop#

The for loop is designed to execute a piece of code a fixed number of times. The syntax of the for loop is:

for i in (a, b, c, d, ...):
    code to be executed

In each subsequent iteration of the for loop, the variable i is assigned next value that is supplied in the list of values.

We can now perform our sum calculation from above using a for loop:

s = 0

for i in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10):
    s += i
    print(s)
# Your code here

6.2.2.1. The range function#

You can imagine that if we wanted to perform this sum up to 100, it would be very annoying to type out all the numbers. For this, Python has a convenient function range() which can automatically generate ranges of numbers for you.

The range function can be used in a couple of different ways, which we will look at here. We will see, however, that range() does some funny things, which is related to the fact that Python counts from zero. For now, let’s look at some concrete examples.

6.2.2.1.1. range(N)#

If you give range() only one argument \(N\), it will give a range of numbers starting from 0, and a total number of numbers determined by the argument \(N\). For example, range(10) is equivalent to (0, 1, 2, 3, 4, 5, 6, 7, 8, 9).

for i in range(10):
    print(i)

6.2.2.1.2. range(N, M)#

If you give range() two arguments \(N,M\), it will give a range of numbers starting from N and stopping at M - 1. Therefore, range(1, 11) is equivalent to (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).

for i in range(1,11):
    print(i)

You might ask: why not stop at M? If you say “range from N to M”, you would think that this range should include M.

There are at least two possible reasons:

  1. For programmers, it is nice that range(0, 10) and range(10) do the same thing.

  2. It will be handy that range(j, j + N) will then always give you N numbers in the range.

6.2.2.1.3. range(N, M, S)#

This is similar to range(N, M), but now with the chance to change the steps using \(S\). range(N, M, S), therefore, gives a range of numbers less than \(M\), starting from \(N\), and with a step \(S\). range(1, 11, 2) is equivalent to (1, 3, 5, 7, 9).

for i in range(1,11,2):
    print(i)

Note that the range() function works only with integers: range(1,11,0.5) is not allowed. For floating point ranges, we can use the special function arange() from the so-called numpy package, but more on that later.

# Your code here
import micropip
await micropip.install("jupyterquiz")
from jupyterquiz import display_quiz
import json

with open("questions7.json", "r") as file:
    questions=json.load(file)
    
display_quiz(questions, border_radius=0)

6.2.2.2. Exiting a loop#

In addition to the examples we saw above, Python offers extra commands for controlling the flow of execution in a loop: break and continue commands.

break is a command you can use to force the exiting of either a for loop or a while loop. For example, you can replace the while loop above using something like this:

s = 0
i = 0

while True:
    s += i*i + i
    i += 1
    if s > 30: 
        break
        
print(s)

It looks funny at first, because while True looks like you will loop forever. But, of course, you are saved by the break statement.

Using break statements can sometimes make your code more readable, particularly if you want to be able to exit the loop under different conditions, or have an exit condition trigger a certain piece of code.

The statement continue is used if you want to skip the rest of the code in the code block and restart the next iteration of the loop. This can sometimes be useful as a way of avoiding adding an else statement.

sum = 0
for i in range(30):
    if (i % 5) == 0:
        continue
    # print(i)
    sum += i
    
print("The sum of numbers between 0 and 29 excluding those that are divisible by 5 is:", s)
    

This is probably not a great example, but in any case, you now know what continue does. To check what happens to i due to continue, you can un-comment the print(i) line and rerun the code.

# Your code here
import micropip
await micropip.install("jupyterquiz")
from jupyterquiz import display_quiz
import json

with open("questions9.json", "r") as file:
    questions=json.load(file)
    
display_quiz(questions, border_radius=0)