Control Flow Structures

Control flow structures are used to organize and add complexity to a program. They serve different purposes, and we will see each of them in detail.

If, else and elif

The if block is a control structure that controls the execution of a block of code based in a certain condition. If the condition defined is true, the code inside the if block will be executed. This block of code should be indented just after the condition, always with the same number of spaces through the whole Python program (the examples in this chapter will make this easier to understand), in order for Python to understand where your if block code begins and ends. After the message shows up, if you type Felipe, a message will be shown, because the condition established on the if block definition is true. If you type anything else, nothing will be printed. Below, consider we ran the program twice, one typing Felipe and one typing Maria:

name = input("Hi, what's your name?\n")
if name == "Felipe":
    print("Hi, %s" % name)

> Hi, what's your name?
> Felipe
> Hi, Felipe

> Hi, what's your name?
> Maria

And what if I want to print another message when the condition is not true. In this case, we can use else. else is always executed if the condition on the if is not true:

name = input("Hi, what's your name?\n")
if name == "Felipe":
    print("Hi, %s" % name)
else:
    print("Hi, visitor")

> Hi, what's your name?
> Felipe
> Hi, Felipe

> Hi, what's your name?
> Maria
> Hi, visitor

And finally, if we want to test more than one condition, we can use elif. elif may be used as many times as necessary to test the number of conditions you want. If none of them are true, else can still be executed, in the end:

name = input("Hi, what's your name?\n")

if name == "Felipe":
    print("Hey, Felipe")
elif name == "John":
    print("Hi, John")
elif name == "Carlos":
    print("What's up, Carlos?")
else:
    print("Hi, visitor")

> Hi, what's your name?
> Felipe
> Hey, Felipe

> Hi, what's your name?
> John
> Hi, John

> Hi, what's your name?
> Carlos
> What's up, Carlos?

> Hi, what's your name?
> Jack
> Hi, visitor

Loops - For

Loops are control structures used for repetition. Imagine if I wanted to write a program that would print all the numbers from 1 to 10, or a program that would print separately each item of a certain list. You could create code that would have print 10 times, one for each number, or a print for each item in a list. But this would be boring and repetitive. And as the numbers grow (like a list with 500 items), this becomes basically impossible. The right way to do this is through a for loop. The for loop iterates over elements in a sequence, executing the code in the indented block just below it. It can be a string, a list. Let’s see an example

names = ["Alfredo", "Mario", "Jose", "Carolina", "Joana", "Luiza"]
for name in names:
  print(name)

> Alfredo
> Mario
> Jose
> Carolina
> Joana
> Luiza

You can also iterate over dicitionaries, but there are different ways to do this, since it’s known that dicitionaries are formed by key-value pairs. In this sense, you can iterate over only keys, only values or both. Let’s see how to do it:

student = {"name": "Maria", "age": 20, "grade": 9.2}

print("Example 1a - iterating over keys")
for key in student:
  print(key)

print("\n")
print("Example 1b - iterating over keys")
for key in student.keys():
  print(key)

print("\n")
print("Example 2 - iterating over values")
for value in student.values():
  print(value)

print("\n")
print("Example 3 - iterating over pairs")
for key, value in student.items():
  print(key + " - " + str(value))

> Example 1a - iterating over keys
> name
> age
> grade

> Example 1b - iterating over keys
> name
> age
> grade

> Example 2 - iterating over values
> Maria
> 20
> 9.2

> Example 3 - iterating over pairs
> name - Maria
> age - 20
> grade - 9.2

For printing numbers, we can use the range() function. It creates a sequence of integer numbers. You can pass 1 or 2 parameters. If you pass 1, the interval created will start from 0 up to the number passed, excluding it. If 2 parameters are passed, the interval will go from the first number to the second:

print("Range with 1 parameter")
for i in range(5):
    print(i)

print("Range with 2 parameters")    
for i in range(3,10):
    print(i)

> Range with 1 parameter
> 0
> 1
> 2
> 3
> 4
> Range with 2 parameters
> 3
> 4
> 5
> 6
> 7
> 8
> 9

If the idea is to repeat a certain block of code a certain number of times, using range() is the solution. As you can see in the examples, the name of the item (the one that cames after the for keyword) might be anything that is compliant with the variable naming rules in Python. This name represents one element in the sequence that is being iterated, being different in each iteration. The example will help on making this more clear:

Two important keywords that are related to loops are break and continue. These commands change the natural flow of a loop. break will stop the execution of a loop entirely and exit it. continue will stop executing that single iteration and jump to the next one. Let’s see an example of using them:

print("break example")
for i in range(1,11):
    if i % 5 == 0:
        break
    print(i)
    
print("continue example")
for i in range(1,11):
    if i % 5 == 0:
        continue
    print(i)

> break example
> 1
> 2
> 3
> 4
> continue example
> 1
> 2
> 3
> 4
> 6
> 7
> 8
> 9

In the first example, with break, the loop would initially print all numbers from 1 to 10. However, we added a condition that if the value of i was divisible by 5, it would execute the break command. Thus, when i is 5, the break command is executed and only prints up to 4.

Following the same logic for continue, the command made it so that the printing for 5 and 10 was skipped.

Loops - while

while loops are similar to for loops, in the sense that it runs code on the block inside of it repeatedly. The difference is that it executes the block of code as long as a certain condition is true. Let’s see an example that works the same as the one above:

counter = 0
while counter < 5:
  print(counter)
  counter = counter + 1

> 0
> 1
> 2
> 3
> 4

This example will print the counter variable, and in the end of the block of code, increment its value by 1. As per the condition, the block of code will be executed as long as the value is less than 5. When the value is incremented to 5, the condition stops being true, and the code on the block stops being executed.

You have to be careful in the while loop to not write a condition that never becomes false. If that happens, your code will continue executing forever (and eventually crash). In the previous example, if we forgot to add the last line (I absolutely never did that), the code would print 0 infinite times, because since we’re not incrementing the counter, it would never become bigger than 5. If you get into this condition, just press Ctrl + C and the code will be interrupted.

One thing that is done pretty regularly in Python is to have a while True condition, and inside of it, define a condition that will run the break command to exit the loop:

while True:
  name = input("Type your name or exit to finish the program: ")
  if name == "exit":
    break
  else:
    print("Hey, %s" % name)

> Type your name or exit to finish the program: Felipe
> Hey, Felipe
> Type your name or exit to finish the program: Maria
> Hey, Maria
> Type your name or exit to finish the program: exit

Conclusion

And thus, we went through all control structures in Python. We saw how they allow complexity to be added to a program, executing different blocks of code based in conditions or in the repetition thorugh for loops, avoiding repeated code. In the next chapter, we will see something that we have been using for the entire book, functions.