6. Control Statements#

So far, we have seen some basic programs and uses of data, but we have not had to make any decisions to decide what code to execute or to repeat the execution of certain lines of code. Control statements allow us to alter a program’s behavior based on different conditions within the data.

In our daily lives, we run across countless situations where we choose different behavior based on some condition:

  • What to wear based on the weather

  • When to wake up and go to sleep - based upon the time of day

  • Converting values into different types - for a given numeric grade, produce the equivalent letter grade

  • Restrictions on who can drive or drink. (and it better not be both at the same time!)

In this notebook, we will see how to use an if statement to execute different code blocks based upon a conditional expression that evaluates to a Boolean (True or False).

6.1. if statement#

We use the if statement to execute a code block when a specified condition is True. The basic syntax:

if condition:
    block

If the condition evaluates to True, then the statement(s) in the block are executed.

Below, we present a flowchart to represent the execution of an if statement. Flowcharts can help you visualize and understand a process. We use flowcharts to show the overview of different Python statements. Initially, you may want to draw flowcharts to help you understand a problem or a program, but flowcharts are too cumbersome to use in practice.

  • Ovals or rounded rectangles indicate the beginning or end of a program. terminal

  • Rectangles represent one or more operations that occur in sequence. process

  • Diamonds represent a conditional operation to choose which path a program or process will follow. decision

  • Arrows represent the program’s (process’s) order of operation. Labels may indicate decision paths. flowline

  • Parallelograms (not shown) represent data input and output.

You can augment these diagrams with whatever notes, variable assignments, etc., to help document a given process.

1age = input("What is your age?")
2if int(age) >= 16:
3    print("You are old enough to drive in most US states.")
What is your age? 23
You are old enough to drive in most US states.

In the above example, int(age) >= 16 is the conditional expression. With Python, this is any expression that evaluates to True or False. Recall that any nonzero numeric value is True, and zero is False. For strings, any non-empty string is True, and an empty string is False. Of course, we can use Boolean variables as well.

1team_won = True
2if team_won:
3    print ("Let's celebrate!")
Let's celebrate!
1if 0:
2    print("nothing to see here - zero evaluates to false")
1if -1:
2    print("Hey - I'm here")
Hey - I'm here
1if "message":
2    print("Hey - I was true. non-empty strings are true")
Hey - I was true. non-empty strings are true
1if "":
2    print("Sting empty, evaluates to false,  you can't see me!")

In the above examples, the print statements after the if statements form the “true-block”. These code blocks can be any number of statements, including nested if statements.

6.2. Comparison Operators#

Sometimes, using a single value is sufficient for an if statement. Python, though, supports several conditional operators:

Comparison
Operator

Example

Meaning

>

x > y

x is greater than y

<

x < y

x is less than y

>=

x >= y

x is greater than or equal to y

<=

x <= y

x is less than or equal to y

==

x == y

x is equal to y

!=

x != y

x is not equal to y

1print("4 < 5:", 4 < 5)
2print("10 > 5:", 10 > 5)
3print("5 <= 6:", 5 <= 6)
4print("Hello:", "hello" == "hel"+"lo")  # Use string concatenation to create "hello"
4 < 5: True
10 > 5: True
5 <= 6: True
Hello: True

6.3. if else statement#

In addition to executing the true block, Python allows for an optional else block that executes if the condition evaluates to False.

1age = 15
2if age >= 16:
3    print("You can drive!")
4    print("You need a license first, though...")
5else:
6    print("You are not old enough to drive.")
7    print("You will need to wait until you are 16.")
You are not old enough to drive.
You will need to wait until you are 16.

In Python, indention determines the code blocks that execute for the if statement. The Python convention is to use four spaces. However, you can use any number of spaces that you like as long as you are consistent with the spacing. Avoid using tabs or mixing tabs and spaces - this will lead to consistency issues.

As you write programs, make sure the code blocks are correctly indented -

1age = 17
2if age >= 16:
3    print("You can drive!")
4else:
5    print("You are not old enough to drive.")
6print("You will need to wait until you are 16.")  #oops, didn't indent this properly, semantic error
You can drive!
You will need to wait until you are 16.
age = 10
if age >= 16:
    print("You can drive!")
else:
    print("You are not old enough to drive.")
   print("You will need to wait until you are 16.")   #syntax error - indention level not matched
File <tokenize>:6
    print("You will need to wait until you are 16.")   #syntax error - indention level not matched
    ^
IndentationError: unindent does not match any outer indentation level

6.4. if elif statement#

If you have several conditions that you need to evaluate in order, you can use an if elif statement. As with the if statement, you can have an optional else portion at the end of the statement.

 1grade = int(input("What was your score on the test?"))
 2if grade >= 90:
 3    print("A")
 4elif grade >= 80:
 5    print("B")
 6elif grade >= 70:
 7    print("C")
 8elif grade >= 60:
 9    print("D")
10else:
11    print("F") 
What was your score on the test? 88
B

Python evaluates these if clauses in their listed order.

What does the following code produce?

 1grade = 90
 2if grade >= 70:
 3    print("C")
 4elif grade >= 80:
 5    print("B")
 6elif grade >= 90:
 7    print("A")
 8elif grade >= 60:
 9    print("D")
10else:
11    print("F") 
C

Not including the colon at the end of an expression will cause the Python interpreter to report a “SyntaxError”.

1if True                # missing :    SyntaxError
2    print("Message")
  Cell In[13], line 1
    if True                # missing :    SyntaxError
                           ^
SyntaxError: expected ':'

6.5. Nested Ifs#

As code blocks can contain any Python statement, if statements can be nested.

Run the following code block several times, changing the salary, commute_time_min, and free_coffee values to see how the logic works. You should be able to produce each of the four different outputs.

 1salary = 60000
 2commute_time_min = 30
 3free_coffee = False
 4if salary > 50000:
 5    if commute_time_min < 60:
 6        if free_coffee:
 7            print("Cool.  I'm going to like this job")
 8        else:
 9            print("Close location and I like the salary, but I NEED coffee")
10    else:
11        print("I don't want to drive that far")
12else:
13    print("I'm worth more than that")
Close location and I like the salary, but I NEED coffee

Step through code on PythonTutor.com

While producing each of these outputs may have seemed frustrating, this is an essential aspect of testing - following each of the different paths a program can follow.

The following table shows the different possibilities. Notice that we only listed a couple of different values for salary and commute_time_min. The program’s logic creates equivalence classes for these variables. Any salary value less than or equal to 50,000 is in one class, and any value greater than 50,000 is in another equivalence class. Similarly, any value for commute_time_min < 60 is in one class, and all other values are in another. free_coffee only has two possibilities.

Salary

Commute Time

Free Coffee

Expected Output

50000

I’m worth more than that

60000

70

I don’t want to drive that far

60000

50

True

Cool. I’m going to like this job

60000

50

False

Close location and I like the salary, but I NEED coffee

6.6. Boolean Operators#

Python offers three Boolean (logical) operators.

6.6.1. And#

The and operator joins two conditional expressions and ensures that both are True for the “true block” to execute. If either of the conditions is False, then the entire and expression evaluates to False. Note that for “true”, the actual value returned is the last “true” value.

1age = 21
2gender = "Male"
3if gender == "Male" and age < 25:
4    print ("You will need to take out a loan to buy car insurance!")
5else:
6    print ("Maybe car insurance won't be too expensive for you...")
You will need to take out a loan to buy car insurance!

Practice running the above code block with different values for age and gender.

6.6.2. Or#

The or operator also joins two conditional expressions. If at least one of the expressions evaluates to True, then it evaluates to True. Only if both expressions are False will the expression evaluate to False. Note that for “true”, the actual value returned is the first “true” value.

1outlook = "overcast"
2humidity = "low"
3if outlook == "sunny" or humidity == "low":
4    print("Play golf!")
Play golf!

6.6.3. Not#

The not operator (aka “logical complement”, “negation”) reverses the value of a Boolean. That is, False becomes True, and True becomes False.

1a = 10
2if not (a > 15):
3    print ("I'm here")
I'm here

6.7. Short-Circuit Evaluation#

Like most other programming languages, the and and or operators utilize short-circuit evaluation. Once the Python interpreter can determine the outcome of a Boolean expression, the interpreter no longer needs to continue evaluation.

For and, if the first expression evaluates to False, the second expression will not be evaluated as the result of the operator will always be False.

For or, if the first expression evaluates to True, the second expression will not be evaluated as the result of the operator will always be True.

Note: def allows us to create functions that the next notebook will present.

 1def expr(num, result):
 2    print ('evaluating', num, result)
 3    return result
 4
 5if expr(1,False) and expr(2,True):
 6    print ("expr #1 was True\n")
 7else:
 8    print ("expr #1 was false\n")
 9    
10if expr(1,True) or expr(2,True):
11    print ("expr #2 was True\n")
12else:
13    print ("expr #2 was false\n")
14    
15if expr(1,False) or expr(2,True):
16    print ("expr #3 was True\n")
17else:
18    print ("If #3 was false\n")   
evaluating 1 False
expr #1 was false

evaluating 1 True
expr #2 was True

evaluating 1 False
evaluating 2 True
expr #3 was True

The result of a logical expression is not always True or False; the Python interpreter returns the last value evaluated.

1a = 0
2b = 3
3x = b or a
4print(x)
3

If you need a boolean result, then force the conversion to boolean with the built-in function bool()

1print(bool(b or a))
True

Here is an example where the behavior would be useful:

key = load_secret_key() or 'randomStringValue'

The Python interpreter will try to load the secret key from some configuration using the function load_secret_key(). If that function does not return a valid value, then the interpreter assigns the value of 'randomStringValue' to key.

Programmers can use multiple and and or clauses in the same expression. Use parenthesis to ensure the correct order of operations / logical meaning.

1def expr(num, result):
2    print ('evaluating', num, result)
3    return result
4
5print (expr(1,True) and (expr(2,False) or expr(3,True)))
evaluating 1 True
evaluating 2 False
evaluating 3 True
True

6.8. Footnote#

Historically, in Python, a group of statements executed together is called a “suite”. However, most other programming languages and even the Python Grammer Specification refer to this as a block. Therefore, we will use the term “block” for this class.

6.9. Variables Revisited#

Think of variables as values with names; those names describe what those values represent.

Variables appear within our Python programs under one of these three usages:

  1. To declare and set a value to the variable.

  2. To assign the variable to a new value (object)

  3. Use the variable - whether in an expression or outputting the value in some fashion

As we declare a variable, remember that the name must be a legal identifier: The variable name must start with a letter or an underscore. The variable name only contains letters, numbers, and underscores. The variable name can not be one of Python’s reserved words.

Before we use a variable, we must declare it first and assign some value to it.

To assign a value to a variable, we use an assignment operator:

a = 45 * 10

Programmers read that line of code as “set a to the value of 45 times 10” or “a is assigned expression”.

The first time a variable is assigned a value is also known as initializing the variable.

Once a variable has been assigned a value or to an existing object, programmers can then use that variable in other statements and expressions.

1a = 45 * 10;
2print(a)
3b = a // 30;
4print(b)
450
15

Unlike many other programming languages, Python is dynamically-typed. Therefore, we can change the variable’s type by assigning different values(objects) to the variable.

6.10. Float Equality#

While it is possible to test float variables and literals for equality with ==, you need to be careful of the particular situation. As mentioned in a previous notebook, floating-point numbers do not have an exact representation. If the program performs some calculations, the results may not be identical. For instance -

1print("1.1 + 2.2 == 3.3:",1.1 + 2.2 == 3.3)
1.1 + 2.2 == 3.3: False

To work around this, you can check that the two numbers are within a given tolerance of each other. While it may appear that abs(f1 - f2) <= tolerance suffices, this approach can still be problematic given the magnitude of the numbers. Python now provides isclose(a,b) in the math module - math.isclose(). You can specify different tolerances as an optional parameter to that function.

1import math
2print("1.1 + 2.2 == 3.3:",math.isclose(1.1 + 2.2,3.3))
1.1 + 2.2 == 3.3: True

6.11. Suggested LLM Prompts#

  • Explain the purpose and syntax of if statements in Python, providing examples of different scenarios where they can be used, such as decision-making, flow control, and conditional execution of code blocks. Use a financial example.

  • Discuss the concept of relational operators in Python (e.g., ==, !=, >, <, >=, <=) and their role in evaluating boolean expressions within if statements. Include examples demonstrating their usage and how they can be combined using logical operators (and, or, not).

  • Create a financial scenario where nested if statements are necessary, and walk through the process of writing and understanding nested if-elif-else structures. Discuss best practices for managing complexity and readability when dealing with deeply nested conditions.

  • Present a real-world coding challenge or problem in finance that requires the use of if statements, relational operators, and potentially elif and else clauses. Guide the programmer through the process of analyzing the problem, identifying the necessary conditions, and implementing an appropriate solution using the concepts covered in the previous prompts.

  • Explore the concept of short-circuiting in Python’s logical operators (and, or) and how this behavior can be leveraged to write more efficient and concise conditional expressions.

6.12. Review Questions#

  1. What is the type and value of x?

    a = 0
    b = 10
    x = b or a
    
  2. Why is the order of if and elif clauses important?

  3. Explain short-circuit evaluation for and and or clauses.

  4. How are code blocks identified in Python?

  5. What is the difference between if/elif statement(s) and a series of if statements?

  6. Why is testing for equality with float numbers problematic? How do we work around such situations?

answers

6.13. Exercises#

  1. Paycheck
    Write a program that computes a simple weekly paycheck for an individual. Prompt the user to enter the number of hours worked and the pay rate. If an individual works over 40 hours, then the individual is paid at 1.5 times the hourly rate for the hours worked over 40. Print the initial total. Of course, the government taxes the individualʼs pay. Assume the tax rate is 20%. Print the amount withheld for taxes. Then print the net amount to be paid to the individual.

  1. Stock Gain (or loss)
    Write a program that allows the user to enter two successive closing prices for a stock. Compute the daily percentage gain or loss. If the gain was positive, print the message “The stock price increased by” and the percentage increase. If the gain was negative, print the message “The stock price decreased by” and the percentage decrease. Otherwise, print “No change to the stock price.”

  1. Body Mass Index(BMI) Caclulator
    BMI is a crude measurement calculated from the weight and height of a person. The medical field uses the value as a potential risk factor for several health issues as its quickly obtainable. For this exercise, you will prompt the user for the necessary values, calculate the BMI, and display the BMI with its associated category.

    \( BMI = \frac{mass}{height^2} \) where the mass is specified in kilograms and the height in meters.

    Category

    BMI

    underweight

    < 18.5

    normal weight

    18.5 - 24.9

    overweight

    25.0 - 29.9

    obese

    >= 30.0

    First, prompt the user the if they want to use imperial or metric units:

    Enter values in (i)mperial or (m)etric units: 
    

    The user will need to enter ‘i’ or ‘m’. If the user does not enter an appropriate value, use the built-in function, exit() to immediately stop the program. Use 1 as an argument value to the function. (While it will be discussed later, return values from programs/processes are used to tell the calling program or environment whether or not an error has occured. 0 signifies success, a non-zero integer values indicate some sort of an error.)

    Next if they select imperial, use these prompts:

    Enter the individual's weight in pounds:
    Enter the individual's height in inches:
    

    For metric, use these prompts

    Enter the individual's weight in kilograms:
    Enter the individual's height in meters:
    

    Calculate the BMI. To convert from poounds to kilograms, multiply by 0.453592. To convert from inches to meters, multiply by 0.0254. Display the BMI with the associated category in parenthesis. Do not trim or round the values.

    22.91 (normal weight)
    
  1. Failed short-circuit evaluation?
    In the following code block, why does it appear that the rules for the short-circuit evaluation are not followed? And the result is True?

1def test(num, result):
2    print ('evaluating', num, result)
3    return result
4
5print (test(1,"False") and test(2,"True"))
evaluating 1 False
evaluating 2 True
True