Data Science and Computing with Python for Pilots and Flight Test Engineers
Control Flow Structures
Introduction
Control flow structures are used to manipulate the order in which individual program instructions are processed during program execution.
We do not always want a whole program to be executed line by line sequentially from top to bottom. Sometimes we want to run through a piece of code several times in a row, perhaps with different parameters. Sometimes we want to execute a certain piece of code only, if a certain condition is met, or not met. Sometimes we simply want to jump from one part of the code to another. And some pieces of code may produce errors during natural operation, yet these errors must not abort the program but instead the program must continue running nonetheless (for instance, if a file is not found) – this is called error handling.
All of this, and more, is done in a computer program with so called control flow structures, of which we get to know a few important ones below, and will learn how they are implemented in Python. Control flow (or flow of control) refers to the order in which the statements of a program are executed (and is not to be confused with flow control of data in data communications).
Conditional Statements (if/elif/else, switch)
If Statement
We can use the if statement to run a part of the code only if a certain condition is satisfied. There are three parts:
- if: this part of the code is run if the specified condition is met.
- elif: is short for “else if”; it is looked at only if the first condition was not satisfied. There can be multiple elif statements behind each other.
- else: this part is run only if none of the previous statements were true. There can be only one else part.
The “elif” and “else” parts of the if statement are optional. You can omit them if you don’t need them.
Below we show you an example of an if statement with two elif and an else part. Notice the indented lines. In Python, the indentation groups lines together in the statement. The indentation is nominally 4 spaces (but you can use any other number. Do not use the tab key for this in a normal text editor (this is not like a shell script that uses tabs). While it visually looks the same, the computer can tell the difference and may return an error. You can use the tab key in a Jupyter notebook, as it will resolve automatically in 4 spaces (you can also use shift tab to remove 4 spaces, and these tab operations work on whole paragraphs if you select them).
When the regular code resumes, it starts again at the beginning of the line. Only the indented lines are part of the if/elif/else statement stucture.
Notice the double equal sign in the condition, as in “x==3”. This is a true equal sign in programming, in the sense that it will ask if the left-hand side equals the right-hand side. The computer is not assigning \(x\) the value 3 here, it asks whether \(x\) equals 3 or not, and returns a True or False value. (Remember that we have previously said that a single “=” in programming is not the equal of an equation, but rather an assignment.)
After copying the code below into your Jupyter notebook on your computer, change the value of \(x\) in the first line of the code and watch what happens to the printouts. Do this until you understand what is happening.
x = 5 # CHANGE: change this value as you wish.
if (x < 3):
y = x + 2
print("x is small.")
print("Try to make x larger.")
elif (x == 3):
y = 7
print("x equals three.")
elif (x == 4):
y = 8
print("x equals four.")
else:
y = 12 - x
print("x is too large.")
print("If you keep making x too large, it may become so powerful that it will become a dictator some day.")
print("So please make x smaller.")
print("---------")
print("x equals:", x)
print("y equals:", y)
Switch Statement (Switch Case, Structural Pattern Matching)
The switch statement lets you choose between several code blocks to be executed, depending on the value of the variable in the switch statement. The code will execute only one of the choices and none of the others.
Until Python 3.10, Python did not have a switch case statement, like other programming languages (e.g. C/C++), and programmers had to implement the functionality themselves with consecutive elif statements. But since Version 3.10 Python it has been implemented as structural pattern matching, as is described in this structural pattern matching tutorial.
Looping Structures (for, while)
For Loop
The for loop lets an index (\(i\) in the example below) run through a range of integer values. Study the example below and try to figure out how it works. It executes the loop 10 times, letting the index run from 0 to 9, incrementing it automatically by one on each execution.
Python allows for more elaborate for statements (including specification by how much the index should jump between executions of the loop), but we do not need to get into them here. Consult the for loop section of a Python tutorial if you are curious. For our purposes it is sufficient if you understand the simple example below.
To use the example in your own code later, simply change the indented lines (the body of the for loop, which is run through several times) to whatever you need to do, and change the number 10 to however many times you want the loop to run.
x = 0
for i in range(0, 10):
x = x + 5
print("x:", x)
print("i:", i)
print("---")
print("The code has finished, after having run the for-loop", i+1, "times.")
While Loop
The while loop is executed, while the specified condition (\(i<7\) in the example below) is true. Note that it is possible that the body of the while loop is never executed (in the case below, if you set \(i\) equal or larger to 7 right in the beginning).
i = 0
while (i<7):
print("i=", i)
i = i + 2
Python does not have a do while loop structure built in, which would guarantee the execution of the loop body at least once, before the condition is potentially falsified and the while loop abandoned. However, there are ways how you can code this up in Python yourself, as is shown, for instance, in this do while loop Python article.
Jump Statements (break, continue, return)
Break Statement
The break statement exits a loop code block immediately at the location of the statement in the code and the loop gets abandoned entirely immediately, without running through further iterations of the loop that were supposed to happen. Break is the statement to get out of a look immediately and entirely. Do no confuse this with the continue statement discussed next, which exits only the current iteration of the loop prematurely, and make sure you understand the subtle difference. The code examples below will help you understand, if you run them in your Jupyter notebook at home.
x = 1 # CHANGE: Choose either value 0 or 1 for x.
for i in range(0, 10):
x = x + 2
print("x:", x)
print("i:", i)
if (x==7):
print("Let's exist the loop early, because we do not like the number 7.")
print("-----")
break
print("---")
print("The code has finished, after having run the for-loop", i+1, "times.")
Continue Statement
Like the break discussed above, the continue statement stops the execution of a pass through the body of a loop immediately at the location of the continue statement in the code. However, unlike the break statement, the loop is not abandoned entirely afterwards. Instead, the loop simply continues with the next value of the iterator. Only the execution of the run through the loop, which encountered the continue statement, was cut short by the continue statement.
for i in range(0, 10):
print("---")
print("i:", i)
if (i%2==0): # checks if i is even.
continue
print("i is an odd number")
print("---")
print("The code has finished, after having run the for-loop", i+1, "times.")
Return Statement
The return statement marks the end of the code block of a function. When used without argument, it is optional. When used with one or more arguments (separated by a comma), the function returns these variables to the program which called the function. We will see examples of this, when we discuss functions.
Functions
Functions are another form of control flow structure in computer programs. They are such an important concept, also in mathematics and not only in computer programming, that we will devote the whole next lesson to them.
Error Handling (try/except/else/finally)
Error handling deal with what the program is supposed to do, if some something goes wrong and an instruction cannot be followed (which ordinarily would lead to the program crashing and stopping to run, unless special provisions are made). The implementation of a try-catch block in Python is explained below. A try-catch block tries to execute a piece of code. It either manages to do so successfully, or it does not, in which case the code is expected to do something else, but it is supposed to continue to run instead of crashing.
As a simple illustration of the concept, imagine you try to open a file with an application, but the file does not exist (perhaps because you made a typo in its filename). You do not want the application to crash because of it. You want the application to show you an error message that the file could not be found, but the application should continue running and perhaps give you another chance to type in the correct file name.
Python implements this with the following syntax:
- try: Tries to execute a piece of code. Unlike for code without a try, if there is an error, the program does not abort, instead, it continues in the “except” section.
- except: This piece of code is executed, if the piece of code in the “try” section failed to execute properly and caused an error (which normally would cause an interruption of the running of the program).
- else: This piece of code is executed, if the piece of code in the “try” section executed properly without an error.
- finally: This piece of code is executed regardless of the outcome of the “try” section and subsequent branching into “except” or “else”.
Below we give a very simple example that tries to print the value of a variable x. We do not know if the variable x has been defined beforehand or not. If it has, print(x) executes normally and returns the value of x on the screen. If the variable x does not exist yet in the program, then print(x) will fail. The code structure below prevents the program from crashing though and instead it prints an error message. If the print statement is successful, it additionally points out that the variable was successfully completed. In either case, the program informs you that it continues to run and has not crashed.
try:
print(x)
except:
print("There was an error; perhaps variable x has not been defined.")
else:
print("The output of variable x has been successful. It can be found above.")
finally:
print("The whole printing procedure with try/except/else has been completed, with one outcome or the other, and the program continues to run.")
Synchronization
Text still to be written…