Part 2

Simple loops

We have now covered conditional structures in some detail. Another central technique in programming is repetition, or iteration. Together these form the fundamental control structures any programmer must master. They are called control structures because essentially they allow you to control which lines of code get executed when. While conditional structures allow you to choose between sections of code, iteration structures allow you to repeat sections of code. They are often called loops because they allow the program to "loop back" to some line that was already executed before. The process of executing one repetition of a loop is also referred to as an iteration of the loop.

This section introduces a simple while loop. Its structure is similar to the conditional statements we already covered. In the next part we will delve into some more sophisticated examples.

Let's have a look at a program which asks the user to type in a number and then prints out the number squared. This continues until the user types in -1.

while True:
    number = int(input("Please type in a number, -1 to quit: "))

    if number == -1:
        break

    print(number ** 2)

print("Thanks and bye!")

Running the program could look like this:

Sample output

Please type in a number, -1 to quit: 2 4 Please type in a number, -1 to quit: 4 16 Please type in a number, -1 to quit: 10 100 Please type in a number, -1 to quit: -1 Thanks and bye!

As you can see above, the program asks for several numbers, thanks to the while statement in the program. When the user types in -1, the break command is executed, which exits the loop and execution continues from the first line after the while block.

With loops, it is crucial that there is always a way to exit the loop at some point in the code, otherwise the repetition could go on forever. To illustrate this, let's change the above example a little:

number = int(input("Please type in a number, -1 to quit: "))
while True:
    if number == -1:
        break

    print(number ** 2)

print("Thanks and bye!")

In this version the program asks the user to type in a number outside the loop. If the user types in any other number than -1, the loop is never exited from. This forms an infinite loop, which means the block of code within the loop is repeated endlessly:

Sample output

Please type in a number, -1 to quit: 2 4 4 4 4 4 4 4 4 (continued ad infinitum...)

The following program has a similar structure to the example above the infinite loop, but the user experience is quite different. This program allows the user to proceed only if they type in the correct PIN 1234:

while True:
    code = input("Please type in your PIN: ")
    if code == "1234":
        break
    print("Incorrect...try again")

print("Correct PIN entered!")
Sample output

Please type in your PIN: 0000 Incorrect...try again Please type in your PIN: 9999 Incorrect...try again Please type in your PIN: 1234 Correct PIN entered!

Loops and helper variables

Let's make the PIN checking example a bit more realistic. This version gives the user only three attempts at typing in a PIN.

The program uses two helper variables. The variable attempts keeps track of how many times the user has typed in a PIN. The variable success is set to either True or False based on whether the user is successful in signing in.

attempts = 0

while True:
    code = input("Please type in your PIN: ")
    attempts += 1

    if code == "1234":
        success = True
        break

    if attempts == 3:
        success = False
        break

    # this is printed if the code was incorrect AND there have been less than three attempts
    print("Incorrect...try again")

if success:
    print("Correct PIN entered!")
else:
    print("Too many attempts...")
Sample output

Please type in your PIN: 0000 Incorrect...try again Please type in your PIN: 1234 Correct PIN entered!

Sample output

Please type in your PIN: 0000 Incorrect...try again Please type in your PIN: 9999 Incorrect...try again Please type in your PIN: 4321 Too many attempts...

The loop is exited either when the user types the correct PIN or if there have been too many attempts. The if statement after the loop checks the value of the variable success and prints out a message accordingly.

Debugging print statements in loops

Adding loops to programs also adds to the potential sources of bugs. It becomes even more important to master the use of debugging print statements as introduced in the first section of this part.

Let's have a look at a program almost identical to the previous example, but with one crucial difference:

attempts = 0

while True:
    code = input("Please type in your PIN: ")
    attempts += 1

    if attempts == 3:
        success = False
        break

    if code == "1234":
        success = True
        break

    print("Incorrect...try again")

if success:
    print("Correct PIN entered!")
else:
    print("Too many attempts...")

This version acts strangely when the user types in the correct code on the third attempt:

Sample output

Please type in your PIN: 0000 Incorrect...try again Please type in your PIN: 9999 Incorrect...try again Please type in your PIN: 1234 Too many attempts...

So, let's try and find the cause by adding some strategic debugging print statements inside the loop:

while True:
    print("beginning of the while block:")
    code = input("Please type in your PIN: ")
    attempts += 1

    print("attempts:", attempts)
    print("condition1:", attempts == 3)
    if attempts == 3:
        success = False
        break

    print("code:", code)
    print("condition2:", code == "1234")
    if code == "1234":
        success = True
        break

    print("Incorrect...try again")
Sample output

beginning of the while block: Please type in your PIN: 2233 attempts: 1 condition1: False code: 2233 condition2: False Incorrect...try again beginning of the while block: Please type in your PIN: 4545 attempts: 2 condition1: False code: 4545 condition2: False Incorrect...try again beginning of the while block: Please type in your PIN: 1234 attempts: 3 condition1: True Too many attempts...

From the above printouts we can see that during the third iteration of the loop the condition of the first if statement is True, and the loop is exited. This iteration never gets to the second if statement, which checks whether the code was typed in correctly:

  while True:
    # ....

    # this block is executed too early
    if attempts == 3:
        success = False
        break

    # the third iteration never gets this far
    if code == "1234":
        success = True
        break

The order of conditional statements, or of different branches within a conditional statement, is a common cause for bugs, especially in loops. Debugging print statements are often the simplest way of finding their cause.

Concatenating strings with the + operator

The above example with PIN checking used a helper variable attempts to keep track of how many times the user had tried to type in a code:

attempts = 0

while True:
    code = input("Please type in your PIN: ")
    attempts += 1
    # ...

The variable is set to zero outside the loop, and each iteration increases its value by one.

A similar idea of incrementation works with string variables as well. The program could, for instance, keep track of all the PIN codes the user typed in:


codes = ""
attempts = 0

while True:
    code = input("Please type in your PIN: ")
    attempts += 1
    codes += code + ", "
    # ...

The helper variable is initialized to an empty string, that is, a string with no characters in it:

codes = ""

With each iteration the string gets longer, as the code the user typed in is added, along with a comma:

    code = input("Please type in your PIN: ")
    codes += code + ", "

If the user types in the codes 1111 2222 1234, at the end of the program's execution the value of codes would be

Sample output

1111, 2222, 1234,

You have reached the end of this section!

You can check your current points from the blue blob in the bottom-right corner of the page.