Flow Control
Contents
4.3. Flow Control#
4.3.1. Conditional Statements and Blocks#
Sometimes, we will only want to execute some piece of code if a certain condition is met.
These conditions can be anything.
For example, we might add to total sales if the transaction value is positive, but add to total returns if the value is negative.
Or, we might want to add up all incurred costs, only if the transaction happened before a certain date.
We use conditionals to run particular pieces of code when certain criterion are met.
Conditionals are closely tied to booleans, so if you don’t remember what those are, go back to the basics lecture for a refresher.
The basic syntax for conditionals is
if condition:
# code to run when condition is True
else:
# code to run if no conditions above are True
Note that immediately following the condition, there is a colon and that the next line begins with blank spaces.
Using 4 spaces is a very strong convention, so that is what we do — we recommend that you do the same.
Also note that the else
clause is optional.
Let’s see some simple examples.
if True:
print("This is where `True` code is run")
This is where `True` code is run
Alternatively, you could have a test which returns a booleans
if 1 < 2:
print("This is where `True` code is run")
This is where `True` code is run
This example is equivalent to just typing the print statement, but the example below isn’t…
if False:
print("This is where `True` code is run")
Or
if 1 > 2:
print("This is where `True` code is run")
Notice that when you run the cells above nothing is printed.
That is because the condition for the if
statement was not true, so the code
inside the indented block was never run.
This also allows us to demonstrate the role of indentation in determining the “block” of code.
val = False
if val is True: # check an expression
print("This is where `True` code is run")
print("More code in the if block")
print("Code runs after 'if' block, regardless of val")
Code runs after 'if' block, regardless of val
The next example shows us how else
works.
val = (2 == 4) # returns False
if val is True:
print("This is where `True` code is run")
else:
print("This is where `False` code is run")
print("More else code")
print("Code runs after 'if' block, regardless of val")
This is where `False` code is run
More else code
Code runs after 'if' block, regardless of val
The if False: ...
part of this example is the same as the example
before, but now, we added an else:
clause.
In this case, because the conditional for the if
statement was not
True
, the if code block was not executed, but the else
block was.
Finally, the Condition is True
is assumed in the if
statement, and is often left out. For example, the following are identical
if (1 < 2) is True:
print("1 < 2")
if 1 < 2:
print("1 < 2")
1 < 2
1 < 2
4.3.1.1. elif
clauses#
Sometimes, you have more than one condition you want to check.
For example, you might want to run a different set of code based on which quarter a particular transaction took place in.
In this case you could check whether the date is in Q1, or in Q2, or in Q3, or if not any of these it must be in Q4.
The way to express this type of conditional is to use one or more elif
clause in addition to the if
and the else
.
The syntax is
if condition1:
# code to run when condition1 is True
elif condition2:
# code to run when condition2 is True
elif condition3:
# code to run when condition3 is True
else:
# code to run when none of the above are true
You can include as many elif
clauses as you want.
As before, the else
part is optional.
Here’s how we might express the quarter example referred to above.
import datetime
halloween = datetime.date(2017, 10, 31)
if halloween.month > 9:
print("Halloween is in Q4")
elif halloween.month > 6:
print("Halloween is in Q3")
elif halloween.month > 3:
print("Halloween is in Q2")
else:
print("Halloween is in Q1")
Halloween is in Q4
Note that when there are multiple if
or elif
conditions, only the code
corresponding to the first true clause is run.
We saw this in action above.
We know that when halloween.month > 9
is true, then halloween.month > 6
and halloween.month > 3
must also be true, but only the code block
associated with halloween.month > 9
was printed.
4.3.2. Iteration#
When doing computations or analyzing data, we often need to repeat certain operations a finite number of times or until some condition is met.
Examples include processing all data files in a directory (folder), aggregating revenues and costs for every period in a year, or computing the net present value of certain assets. (In fact, later in this section, we will verify the equations that we wrote down above.)
These are all examples of a programming concept called iteration.
We feel the concept is best understood through example, so we will present a contrived example and then discuss the details behind doing iteration in Python.
4.3.2.1. A Contrived Example#
Suppose we wanted to print out the first 10 integers and their squares.
We could do something like this.
print(f"1**2 = {1**2}")
print(f"2**2 = {2**2}")
print(f"3**2 = {3**2}")
print(f"4**2 = {4**2}")
# .. and so on until 10
1**2 = 1
2**2 = 4
3**2 = 9
4**2 = 16
As you can see, the code above is repetitive.
For each integer, the code is exactly the same except for the two places where the “current” integer appears.
Suppose that I asked you to write the same print statement for an int stored in
a variable named i
.
You might write the following code:
print(f"{i}**2 = {i**2}")
This more general version of the operation suggests a strategy for achieving our
goal with less repetition: have a variable i
take on the values 1 through 10
(Quiz: How can we use range
to create the numbers 1 to 10?) and run the line
of code above for each new value of i
.
This can be accomplished with a for
loop!
for i in range(1, 11):
print(f"{i}**2 = {i**2}")
1**2 = 1
2**2 = 4
3**2 = 9
4**2 = 16
5**2 = 25
6**2 = 36
7**2 = 49
8**2 = 64
9**2 = 81
10**2 = 100
Whoa, what just happened?
The integer i
took on the values in range(1, 11)
one by one and
for each new value it did the operations in the indented block (here
just one line that called the print
function).
4.3.2.2. for
Loops#
The general structure of a standard for
loop is as follows.
for item in iterable:
# operation 1 with item
# operation 2 with item
# ...
# operation N with item
where iterable
is anything capable of producing one item at a time (see
here for official
definition from the Python team).
We’ve actually already seen some of the most common iterables!
Lists, tuples, dicts, and range/zip/enumerate objects are all iterables.
Note that we can have as many operations as we want inside the indented block.
We will refer to the indented block as the “body” of the loop.
When the for loop is executed, item
will take on one value from iterable
at a time and execute the loop body for each value.
When iterating, each item
in iterable
might actually contain more than
one value.
4.3.2.3. while
Loops#
A related but slightly different form of iteration is to repeat something until some condition is met.
This is typically achieved using a while
loop.
The structure of a while loop is
while True_condition:
# repeat these steps
where True_condition
is some conditional statement that should evaluate to
True
when iterations should continue and False
when Python should stop
iterating.
For example, suppose we wanted to know the smallest N
such that
\( \sum_{i=0}^N i > 1000 \).
We figure this out using a while loop as follows.
total = 0
i = 0
while total <= 1000:
i = i + 1
total = total + i
print("The answer is", i)
The answer is 45
Let’s check our work.
# Should be just less than 1000 because range(45) goes from 0 to 44
sum(range(45))
990
# should be between 990 + 45 = 1035
sum(range(46))
1035
A warning: one common programming error with while loops is to forget to set the variable you use in the condition prior to executing. For example, take the following code which correctly sets a counter
i = 0
And then executes a while loop
while i < 3:
print(i)
i = i + 1
print("done")
0
1
2
done
No problems. But if you were to execute the above cell again, or another cell, the i=3
remains, and code is never executed (since i < 3
begins as False).
while i < 3:
print(i)
i = i + 1
print("done")
done
4.3.2.4. break
and continue
#
4.3.2.4.1. break
Out of a Loop#
Sometimes we want to stop a loop early if some condition is met.
Let’s revisit the example of finding the smallest N
such that
\( \sum_{i=0}^N i > 1000 \).
Clearly N
must be less than 1000, so we know we will find the answer
if we start with a for
loop over all items in range(1001)
.
Then, we can keep a running total as we proceed and tell Python to stop iterating through our range once total goes above 1000.
total = 0
for i in range(1001):
total = total + i
if total > 1000:
break
print("The answer is", i)
The answer is 45
4.3.2.4.2. continue
to the Next Iteration#
Sometimes we might want to stop the body of a loop early if a condition is met.
To do this we can use the continue
keyword.
The basic syntax for doing this is:
for item in iterable:
# always do these operations
if condition:
continue
# only do these operations if condition is False
Inside the loop body, Python will stop that loop iteration of the loop and continue directly to the next iteration when it encounters the continue
statement.
For example, suppose I ask you to loop over the numbers 1 to 10 and print out
the message “{i} An odd number!” whenever the number i
is odd, and do
nothing otherwise.
You can use continue to do this as follows:
for i in range(1, 11):
if i % 2 == 0: # an even number... This is modulus division
continue
print(i, "is an odd number!")
1 is an odd number!
3 is an odd number!
5 is an odd number!
7 is an odd number!
9 is an odd number!