1. control flow
How programs choose what to do
By default, code runs top-to-bottom in order. A control structure changes that flow.
In this module we focus on selection: your program asks a yes/no question and then chooses a path.
The yes/no question is called a condition. A condition is just a boolean expression: something Python can evaluate to either True or False.
A condition is a question:
age >= 18
“Is the age at least 18?” → True/False
If the condition is True, the if block runs. If it is False, Python skips that block.
| Condition (question) | Meaning |
|---|---|
| temperature_c < 0 | Is it below freezing? |
| score == 100 | Did I get a perfect score? |
| name != '' | Is the name not empty? |
| has_ticket and has_id | Do I have both things required? |
2. comparisons
Asking questions about data
Comparisons are the most common way to create boolean expressions. They compare two values and produce True or False.
- Equality:
==(equal),!=(not equal) - Ordering:
<,<=,>,>=
Common bug: `=` vs `==`
# Assignment (stores a value) score = 100 # Comparison (asks a question) is_perfect = (score == 100) # True
Question 1 of 4
Which operator checks equality in Python?
3. boolean logic
Combining conditions with AND, OR, and NOT
Real rules usually require more than one check. Boolean logic lets you combine multiple comparisons into one clear decision.
andmeans “both must be true”ormeans “at least one must be true”notmeans “flip the result”
Precedence rule of thumb (Python)
Python evaluates not first, then and, thenor. When you mix them, add parentheses so the code matches your English rule.
One more important idea is short-circuiting. In anand expression, if the left side is False, Python stops early (because the whole thing must be False). In an orexpression, if the left side is True, Python stops early (because the whole thing must be True).
Short-circuiting can prevent errors:
# Safe: only divides if denominator is not zero
if denominator != 0 and (numerator / denominator) > 2:
print("Big ratio")Question 1 of 4
Which condition correctly checks if `x` is 1 OR 2?
4. branching
`if`, `elif`, and `else`
The if statement chooses whether to run a block of code. Use elif (“else if”) for additional choices, and useelse for the fallback when nothing matched.
A key mental model: an if/elif/else chain is a list of gates. Python checks them top-to-bottom and takes the first gate that opens.
Example: grading (branching only)
score = 85
if score >= 90:
letter = "A"
elif score >= 80:
letter = "B"
elif score >= 70:
letter = "C"
else:
letter = "D"
print(letter)Question 1 of 3
In an `if/elif/else` chain, how many branches run for a single execution?
5. readability
Write conditions you can explain out loud
Code can be logically correct and still hard to read. Readability is not a “nice to have” — it prevents bugs.
Two powerful habits are:
- Name booleans like questions (example:
has_ticket,is_adult,is_banned) - Use helper booleans to make long conditions shorter and clearer
Refactor: same logic, clearer intent
# Harder to read
if (not is_banned) and (is_vip or ((age >= 18) and has_ticket and has_id)):
print("ALLOW")
# Easier to read
is_adult = age >= 18
has_normal_access = is_adult and has_ticket and has_id
can_enter = (not is_banned) and (is_vip or has_normal_access)
if can_enter:
print("ALLOW")Common conditional mistakes
if x == 1 or 2:(wrong) — compare both sides.- Mixing
and/orwithout parentheses. - Off-by-one thresholds:
>vs>=.
Finally, Python allows many values to act like booleans. For example, empty strings, 0, and empty lists behave like False. This is called truthiness. It can be convenient, but when you are learning, being explicit is often clearer.
Truthiness examples (Python)
# These act like False in an if-statement "" # empty string 0 # zero [] # empty list # These act like True "Ada" # non-empty string 42 # non-zero number [1, 2] # non-empty list
6. guided project
Decision Rules Engine (No Loops)
In this mini-project you'll build a tiny “decision engine” that returns 'ALLOW' or 'DENY' based on a few inputs. The goal is to practice translating rules into boolean logic and clean branching.
Keep it loop-free: write each test case as a separate function call. We want you to focus on decision-making first.
| Priority | Rule | Decision |
|---|---|---|
| 1 | If banned | DENY |
| 2 | Else if VIP | ALLOW |
| 3 | Else if adult AND ticket AND ID | ALLOW |
| 4 | Else | DENY |
English rules (decision table)
Start by writing the rules in a clear priority order.
1) If banned → DENY
2) Else if VIP → ALLOW
3) Else if adult AND ticket AND ID → ALLOW
4) Else → DENYBuild the Decision Engine
- 1.Create a function
decide_entry(age, has_id, has_ticket, is_vip, is_banned)that returns either'ALLOW'or'DENY'. - 2.Add a guard clause: if
is_bannedis True, return'DENY'immediately. - 3.Create a helper boolean
is_adult = age >= 18. - 4.Implement the VIP rule: if
is_vipis True, return'ALLOW'. - 5.Implement the normal entry rule: if
is_adult and has_ticket and has_id, return'ALLOW'. - 6.Finish with a final
return 'DENY'for everyone else. - 7.Write 8–10 test scenarios as separate calls (no loops). Include boundary cases like age 17 vs 18 and banned + VIP.