Programming in Python · Lesson 6
Decision Control Structures
If, if-else, nested-if, and elif structures, relational operators, Boolean expressions, fall through, and the logical operators and, or, and not.
Lesson purpose
Until now, every program the class has written runs top to bottom, one statement after another. This lesson introduces decision control structures, which let a program choose which statements to run based on a condition. Students learn the four decision patterns (if-then, if-then-else, nested-if, and else-if), the relational operators used to build conditions, Boolean expressions and the Boolean data type, and the logical operators and, or, and not.
The logic will be familiar to students who know C# and JavaScript. Emphasize the Python-specific syntax: a colon ends every condition line, indentation (not braces) defines each block, the keyword is elif (not else if), the logical operators are the words and, or, and not (not &&, ||, !), and True and False are capitalized.
Learning objectives
By the end of the lesson, students should be able to:
- Describe the purpose of control structures and identify algorithms that require decisions.
- Illustrate if-then and if-then-else structures with flowcharts and pseudocode.
- Identify the conditional statement in an if-then structure and code it in Python.
- Differentiate between the
=operator and the==operator. - List, define, and identify the relational operators in example expressions.
- Write Boolean expressions and initialize Boolean variables, and distinguish a Boolean expression from the Boolean data type.
- Code if-then-else structures and trace the flow of nested-if and else-if structures.
- Explain fall through in the context of decision control structures.
- Identify logical operators, use truth tables for
andandor, and usenotto negate a Boolean value.
1. Control structures
Why programs need decisions
Consider an automated phone system: “Press or say 1 to connect to an account agent; press 2 to troubleshoot your cable service…” If that program ran strictly in sequence, every caller would be asked for a name, connected to an agent, sent to the cable troubleshooter, sent to the Internet troubleshooter, and then disconnected, no matter which option they chose.
The book’s sequential version of the algorithm:
Output "Press or say 1 to connect to an account agent."
Output "Press or say 2 to troubleshoot your cable service."
Output "Press or say 3 to troubleshoot your Internet service."
Output "Press or say 0 to quit."
Ask for customer's name.
Ask for customer's account number.
Provide current account status.
Connect to next available agent.
Connect user to automated cable troubleshooter.
Connect user to automated Internet troubleshooter.
Make sure the user really wants to quit.
Output goodbye message.
Clearly this should not be sequential. A caller with an Internet problem who presses 3 should go directly to the Internet troubleshooter.
Check for understanding: How many distinct branches should this algorithm have? Four, one for each menu option: 1, 2, 3, and 0.
Key terms
- A control structure alters the sequential execution of statements in a program.
- A decision control structure alters the sequential flow by branching to specific statements based on a condition or decision.
Decision logic is everywhere
Decision control structures make programs seem intelligent because they respond to user input, and they let programs handle data differently based on its value. Book examples to discuss:
- Deciding who is eligible to vote based on age and citizenship
- Determining whether a polynomial has zero, one, or two real roots
- Assigning a letter grade based on a quiz score
- Deciding whether to apply a bank service charge based on the account balance
- Running a furnace or air conditioner based on room temperature
- Checking whether a number is odd or even with modulo division
- Offering free shipping based on the amount purchased or VIP status
Quick activity: ask students to state the condition in each example (for instance, age >= 18, number % 2 == 0).
2. The if-then structure
Flowchart and pseudocode
A simple voice system might tell callers to press 1 when they are ready to connect to an agent. In a flowchart, the decision is a diamond containing a question (the condition):
- When the answer is
True, an arrow leads to one or more statements in the conditional block. - When the answer is
False, the flow bypasses the conditional block.
This logic is an if-then structure, like “If it is raining, I will need an umbrella.” In pseudocode, statements on the True branch are indented:
if the choice is 1 then
connect user to an agent
show the message "Bye"
The if-then structure is built on a conditional statement, which directs program flow to the correct set of statements when a condition is True. When the user presses 1, the program connects to an agent. When the condition is not True (the user presses 9, for example), the program skips the block and continues sequentially, ending with “Bye.”
Python syntax
if condition:
statement
if condition:
statement1
statement2
Rules and best practices:
- Place a colon after the condition.
- Indent every statement that belongs to the if block.
- Indent all statements in the block the same amount. The standard is four spaces.
C#/JavaScript connection: Python has no braces and no required parentheses around the condition. Indentation is not just style in Python; it is how the language knows which statements belong to the block. Inconsistent indentation causes an IndentationError or, worse, silently changes the logic.
Example: simple voice response
print("Press 1 when you are ready to")
choice = input("connect to an account agent: ")
if choice == "1":
print("You chose option " + choice)
print("Connecting you now")
print("Bye")
Sample run:
Press 1 when you are ready to
connect to an account agent: 1
You chose option 1
Connecting you now
Bye
- Line 2 stores the user’s input.
input()always returns a string, so the condition compares against the string"1"(in quotes). You could instead convert withint()and compare with1. - Line 3 is the conditional statement. If it is
True, lines 4 and 5 run. - Line 6 is not indented, so it runs no matter what.
Check for understanding: What happens if the user presses a number other than 1? The two indented lines are skipped, and the program displays only Bye.
3. Relational operators
== versus =
The condition if choice == "1": uses a double equal sign. == is the equal operator; it checks whether two operands are equal. It is completely different from =, the assignment operator, which stores a value in a variable.
choice = 1
if choice = 0: # incorrect: SyntaxError
print("choice is zero")
if choice == 1: # correct
print("choice is one")
Using = in a condition produces a syntax error (IDLE and VS Code flag it). This is a helpful difference from C-family languages, where if (x = 0) can sometimes compile and cause a hidden bug.
The full set
A relational operator specifies a comparison between two operands. Operands can be two literals (7 and 9), two variables (airtime and limit), or one variable and one literal (airtime and 1000).
Examples where airtime = 1056:
| Operator | Description | Example | Result |
|---|---|---|---|
== |
Equal to | airtime == 1056 |
True |
airtime == 566 |
False |
||
!= |
Not equal to | airtime != 1056 |
False |
airtime != 566 |
True |
||
< |
Less than | airtime < 2000 |
True |
2000 < airtime |
False |
||
> |
Greater than | airtime > 56 |
True |
56 > airtime |
False |
||
<= |
Less than or equal to | airtime <= 1056 |
True |
airtime <= 29 |
False |
||
>= |
Greater than or equal to | airtime >= airtime |
True |
airtime >= 2000 |
False |
Talking points:
- Watch the order of operands:
airtime < 2000and2000 < airtimeare different questions. - The “or equal to” operators are written with the
=second:<=,>=. There is no=<or=>. - Python does not have JavaScript’s
===. Python’s==never converts types, so"1" == 1is simplyFalse.
Using != to validate input
Relational operators give flexibility when writing conditions. For example, != can validate input:
Prompt the user to press 1 to connect to an agent
Obtain the user's choice
if the value in choice is not 1
display an error message
print("Press 1 when you are ready to")
choice = input("connect to an account agent: ")
if choice != "1":
print("You chose option " + choice + "\n")
print("Invalid input" + "\n")
Sample run:
Press 1 when you are ready to
connect to an account agent: 9
You chose option 9
Invalid input
The "\n" concatenated to each message adds an extra blank line after it (a review of escape sequences from Lesson 5).
4. Boolean expressions and the Boolean data type
Boolean expressions are formed from relational operators and operands, and they evaluate to True or False. For example, choice != "1" is True when the customer does not select 1 and False when the customer does.
Boolean expressions and Boolean data have something in common: both carry a value of True or False. The difference is in how they are used:
- A Boolean expression is typically used as part of a conditional statement.
- The Boolean data type (
bool) is used when declaring or assigning a variable.
vip = True
In memory, Boolean variables hold 0 for False and 1 for True. Theoretically a Boolean needs only one bit, but actual storage varies by language.
In Python, True and False must be capitalized. Writing true produces a NameError. (Contrast with C# and JavaScript, which use lowercase true and false.)
vip = True
if vip:
print("Transferring you to the VIP agent.")
Check for understanding: What is the Boolean variable? What is the conditional statement? What is the Boolean expression?
- Boolean variable:
vip - Conditional statement:
if vip: - Boolean expression:
vip(by itself, the variable is the expression)
You could write if vip == True:, but comparing a Boolean variable to True is redundant. The variable already holds True or False, so if vip: is the preferred Python style.
A Boolean variable can also store the result of a Boolean expression:
purchase = 150.00
qualifies = purchase > 100.00 # qualifies holds True
5. The if-then-else structure
Suppose a voice system offers two options: press 1 to connect to an agent, or press 0 to quit. In the flowchart, both the True and False branches contain statements, and the program follows exactly one of them.
A decision coded as two possible paths is an if-then-else structure. Python uses the keyword else for the alternative path.
if condition:
statement1
statement2
else:
statement3
statement4
Rules and best practices:
- Place
elseon its own line, at the same indent level as theif. - Put a colon immediately after
else, with no condition.
print("Press 1 when you are ready to")
print("connect to an account agent.")
print("Press anything else to quit.")
choice = input()
if choice == "1":
print("You chose option 1.")
print("Connecting you now.")
else:
print("You chose to quit.")
print("Bye.")
Sample run:
Press 1 when you are ready to
connect to an account agent.
Press anything else to quit.
0
You chose to quit.
Bye.
- The if block contains two statements; the else block contains two statements.
- Exactly one block runs. The else block catches every input that is not
"1", not just"0". - This could be written as two separate if statements, but if-then-else is clearer and evaluates the condition only once.
6. Nested-if structures
Sometimes a program must make a decision within a decision. Example: after the caller chooses the Quit option, the system asks, “Are you sure?” and either disconnects or sends the caller to the help desk. Decisions within decisions are called nested-if structures.
print("Press 1 to connect to an account agent.")
print("Press 0 to quit.")
choice = input()
if choice == "0":
print("Are you sure you want to quit?")
sure_thing = input()
if sure_thing == "y":
print("Okay, you're sure. Disconnecting.")
else:
print("Connecting you to the help desk.")
else:
print("You chose option 1.")
print("Connecting you now.")
- The outer decision (line 4) checks for the Quit option.
- The inner decision (lines 7 through 10) runs only when the outer condition is
True. It uses a second indent level. - The final
else(line 11) lines up with the outerif, so it pairs with the outer decision.
Check for understanding: Which lines are the inner level of the nested-if? The inner if sure_thing == "y": and its else, plus their indented statements.
Trace practice: have students predict the output for inputs 0 then y, 0 then n, and 1. Note that "Y" (uppercase) goes to the help desk; Lesson 5’s lower() method fixes that: if sure_thing.lower() == "y":.
7. The else-if structure
For more than two options, use an else-if structure. Python combines else and if into one keyword: elif.
if condition1:
statement1
elif condition2:
statement2
elif condition3:
statement3
statement4
else:
statement5
Rules and best practices:
- Begin with an
ifstatement. - Use
eliffor each subsequent condition. - Use
elsefor the final “none of the above” case (optional, but recommended for catching bad input).
print("Press 1 to connect to an account agent.")
print("Press 2 to troubleshoot your cable.")
print("Press 3 to troubleshoot your Internet.")
print("Press 0 to quit.")
choice = input()
if choice == "0":
print("Bye.")
elif choice == "1":
print("Transferring you to an account agent.")
elif choice == "2":
print("Connecting you to a cable technician.")
elif choice == "3":
print("Connecting you to an Internet specialist.")
else:
print("Invalid input.")
Sample run:
Press 1 to connect to an account agent.
Press 2 to troubleshoot your cable.
Press 3 to troubleshoot your Internet.
Press 0 to quit.
3
Connecting you to an Internet specialist.
Check for understanding: What is the output if a customer enters 2? Enters 7?
2:Connecting you to a cable technician.7:Invalid input.(no condition matched, so theelseruns)
C#/JavaScript connection: elif replaces else if. Python also has a match statement (added in Python 3.10) that resembles switch, but if/elif/else is the standard tool and what this course uses.
8. Fall through
Why use an else-if structure instead of a series of separate if statements?
- In a series of plain
ifstatements, every condition is evaluated, and each true one runs. - In an else-if structure, conditions are evaluated only until one is true. The remaining
elifandelsebranches are skipped.
if choice == 1:
print("One")
elif choice == 2:
print("Two")
elif choice <= 2:
print("Daisy")
else:
print("Stop")
Ask: What is the output when the user enters 2? Output:
Two
Even though choice <= 2 is also true, that branch never runs because the elif choice == 2 branch already matched.
Fall through means execution continues into the next conditional statement within a structure. If this code fell through, the output would be Two Daisy. Python’s else-if structure has no fall through, so you need to order your conditions carefully: put the most specific conditions first.
Connection: C and JavaScript switch statements fall through unless you add break. C# refuses to compile implicit fall-through between non-empty case sections. Python’s if/elif never falls through.
Contrast demo: rewrite the example as three separate if statements and have students predict the output for 2 (Two, then Daisy).
9. Conditional logical operators
A simple condition such as choice == 1 contains one relational operator. A conditional logical operator combines the outcomes of two or more Boolean expressions. Python’s logical operators are the keywords and, or, and not.
The and operator
Suppose valid menu choices are 0, 1, 2, 3, and 9. Anything greater than 3 other than 9 is invalid:
choice = int(input())
if choice > 3 and choice != 9:
print("Invalid input.")
Correction to the book’s snippet: the book writes
choice = input()and then compareschoice > 3. In Python 3 that raisesTypeError: '>' not supported between instances of 'str' and 'int', becauseinput()returns a string. Convert withint()before comparing to a number, as shown above.
How Python evaluates the condition when choice contains 7:
- Evaluates
choice > 3, which isTruebecause 7 > 3. - Evaluates
choice != 9, which isTruebecause 7 != 9. - Evaluates
True and True, which isTrue. - The result is
True, and the output isInvalid input.
Check for understanding: What happens if choice contains 9? choice > 3 is True, but choice != 9 is False, so True and False is False and nothing is printed.
The and operator requires both conditions to be true. A table summarizing all possible outcomes of a logical operation is a truth table:
choice > 3 |
choice != 9 |
choice > 3 and choice != 9 |
|---|---|---|
True |
True |
True |
True |
False |
False |
False |
True |
False |
False |
False |
False |
choice = 9
if choice > 3 and choice != 9:
print("Invalid input.")
else:
print("Valid input.")
Output:
Valid input.
The or operator
The or operator requires only one of the conditions to be true. Example: an online store offers free shipping on purchases over $100.00 or to VIP club members. If both conditions are true, the result is still True.
purchase > 100.00 |
vip |
purchase > 100.00 or vip |
|---|---|---|
True |
True |
True |
True |
False |
True |
False |
True |
True |
False |
False |
False |
purchase = 80.00
vip = True
if purchase > 100.00 or vip:
print("Free shipping!")
Output:
Free shipping!
The purchase is under $100, but vip is True, so the whole expression is True.
Combining operators with parentheses
When one condition uses more than one logical operator, use parentheses so the logic is carried out in the intended order:
if (vip == True and purchase >= 100) or free_shipping_coupon == True:
print("Free shipping!")
Someone gets free shipping if they are a VIP with a purchase of at least $100, or if they have a coupon. (Following the Boolean-variable advice from Section 4, this can be written more cleanly as if (vip and purchase >= 100) or free_shipping_coupon:.)
Python evaluates not first, then and, then or, but parentheses make the intent clear to anyone reading the code.
The not operator
The not operator is the negation operator. It flips a Boolean value: not True is False, and not False is True. Sometimes it is easier to express a condition in terms of what you do not want to be true.
Check for understanding: Write the Boolean expression for “a coupon can be applied if the item isn’t on clearance and it isn’t jewelry.”
if not clearance and not jewelry:
print("Coupon applied.")
Symbols vs. keywords
- Python
andcorresponds to&&inC#and JavaScript. - Python
orcorresponds to the double-pipe operator inC#and JavaScript. - Python
notcorresponds to!inC#and JavaScript.
Using the C#/JavaScript symbols in Python is a syntax error. Like C# and JavaScript, Python short-circuits: in a and b, if a is False, b is never evaluated; in a or b, if a is True, b is never evaluated.
Preview (not in this module’s reading): Python allows chained comparisons such as 1 <= choice <= 3, which means 1 <= choice and choice <= 3.
Classroom application
- Branch count. Give students a menu with five options. Have them draw the flowchart, count the branches, and then write the
if/elif/elsecode. - Assignment vs. equality. Show
if score = 100:and have students predict and read the error message, then fix it. - Grade assigner. Ask for a quiz score (use
int(input(...))) and print A, B, C, D, or F with anelifchain. Then reverse the order of the conditions (check>= 60first) and discuss why every passing score becomes a D. This makes the “no fall through, order matters” point concrete. - Odd or even. Use
number % 2 == 0in an if-then-else to classify a user-entered integer. - Are you sure? Extend the nested-if example so that
y,Y,yes, andYESall disconnect, usinglower()andor. - Truth-table fill-in. Give
purchaseandvipvalues and have students fill in the result column forandandorbefore running the code.
Common misconceptions
- “
=and==are interchangeable.”=assigns;==compares. Using=in a condition is a syntax error in Python. - “
input()gives me a number.” It always returns a string. Compare to"1", or convert withint()before comparing to1or using>/<. - “Indentation is just for readability.” In Python it defines the block. Misaligned lines either cause an
IndentationErroror change which statements are inside theif. - “
elseneeds a condition.”else:never has a condition; it catches everything the earlier conditions did not. - “Python uses
else if.” The keyword iselif. - “Every true
elifruns.” Only the first true branch runs; the rest are skipped (no fall through). - “
trueandfalsework.” Python requiresTrueandFalse. - “Use the
C#symbols for and/or.” Python usesand,or, andnot. - “
if vip == True:is required.” A Boolean variable can be tested directly:if vip:. - “
ormeans exactly one.”orisTruewhen either or both operands areTrue.
Lesson summary
- A control structure alters the sequential execution of statements. A decision control structure branches to specific statements based on a condition.
- Decision control structures include if-then, if-then-else, nested-if, and else-if.
- Decision structures begin with a conditional statement such as
if choice == 1:, ending in a colon, followed by an indented block. - Conditional statements use relational operators:
==,!=,>,<,>=, and<=. - Use
==(equal operator), not=(assignment operator), in conditions. - Relational operators and operands form Boolean expressions that evaluate to
TrueorFalse. - Boolean expressions are used in conditions; the Boolean data type is used in declarations and assignments. A Boolean variable can serve as a Boolean expression by itself.
elseprovides the alternative path;elifadds additional conditions.- Python’s else-if structure has no fall through: only the first true branch runs.
- The logical operators
andandorbuild compound conditions, summarized in truth tables;notnegates a Boolean value.
Course Notes