🎯 Learning Objectives
- Use
if,elif, andelseto make decisions in code - Understand how Python uses indentation to define blocks
- Write nested conditionals and know when to avoid them
- Use the ternary (conditional) expression for concise one-liners
- Apply
match/casefor structural pattern matching (Python 3.10+) - Follow best practices for clean, readable conditional logic
The if Statement
The if statement lets your program make decisions. Code inside the
if block runs only when the condition is True.
age = 20
if age >= 18:
print("You are an adult.")
print("You can vote.")
print("This always runs — it's outside the if block.")
basic_if.py
{}. The indented lines after the :
are the body of the if. When indentation returns to the previous level,
the block is over.
if / else
else provides an alternative block that runs when the condition is False:
temperature = 35
if temperature > 30:
print("It's hot! Stay hydrated.")
else:
print("Temperature is comfortable.")
if_else.py
if / elif / else
elif (short for "else if") lets you check multiple conditions in sequence.
Python evaluates them top to bottom and runs the first block whose
condition is True:
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
print(f"Score: {score} → Grade: {grade}") # Score: 85 → Grade: B
elif.py
Key rules
ifis required — it starts the chain.elifis optional — use as many as needed (0 or more).elseis optional — it's the catch-all for when nothing else matched.- Each block must contain at least one statement. Use
passas a no-op placeholder.
# pass as a placeholder
if condition:
pass # TODO: implement this later
else:
handle_other_case()
pass_placeholder.py
Nested Conditionals
You can put if statements inside other if statements:
age = 25
has_id = True
if age >= 18:
if has_id:
print("Entry allowed.")
else:
print("Please show your ID.")
else:
print("You must be 18 or older.")
nested.py
Flattening with combined conditions
# Instead of nesting:
if age >= 18 and has_id:
print("Entry allowed.")
elif age >= 18:
print("Please show your ID.")
else:
print("You must be 18 or older.")
flat.py
Ternary (Conditional) Expression
Python's one-line conditional expression — useful for simple assignments:
# Syntax: value_if_true if condition else value_if_false
age = 20
status = "adult" if age >= 18 else "minor"
print(status) # "adult"
# Use in f-strings
print(f"You are {'eligible' if age >= 18 else 'not eligible'}.")
# Use in function calls
print(max(a, b) if a != b else "equal")
# Don't overuse — keep it simple
# BAD: nested ternary (hard to read)
# result = "A" if x > 90 else "B" if x > 80 else "C"
# Better: use if/elif/else for complex logic
ternary.py
Structural Pattern Matching (match / case)
Python 3.10 introduced match/case — a powerful alternative
to long if/elif chains when checking a value against multiple patterns:
command = "quit"
match command:
case "start":
print("Starting...")
case "stop":
print("Stopping...")
case "quit" | "exit": # multiple patterns with |
print("Goodbye!")
case _: # _ is the wildcard (like else)
print(f"Unknown command: {command}")
match_basic.py
Pattern matching with structure
# Match on data structure shape
def handle_point(point):
match point:
case (0, 0):
print("Origin")
case (x, 0):
print(f"On X-axis at x={x}")
case (0, y):
print(f"On Y-axis at y={y}")
case (x, y):
print(f"Point at ({x}, {y})")
handle_point((3, 0)) # On X-axis at x=3
handle_point((0, 5)) # On Y-axis at y=5
handle_point((2, 7)) # Point at (2, 7)
# Guard conditions with 'if'
def classify_age(age):
match age:
case n if n < 0:
return "Invalid"
case n if n < 13:
return "Child"
case n if n < 18:
return "Teenager"
case _:
return "Adult"
match_advanced.py
match/case is more than a switch statement — it can
destructure tuples, lists, dicts, and even class instances. We'll see more advanced
patterns when we cover classes (Lesson 20).
Guard Clauses (Early Return)
A guard clause handles edge cases or invalid inputs at the top of a function, returning early. This keeps the main logic flat and readable:
# Without guard clauses — deeply nested
def process_order(order):
if order is not None:
if order["status"] == "active":
if order["total"] > 0:
# actual logic here
ship(order)
else:
raise ValueError("Empty order")
else:
raise ValueError("Inactive order")
else:
raise ValueError("No order")
# With guard clauses — flat and clear
def process_order(order):
if order is None:
raise ValueError("No order")
if order["status"] != "active":
raise ValueError("Inactive order")
if order["total"] <= 0:
raise ValueError("Empty order")
# Main logic — no nesting!
ship(order)
guard_clauses.py
Best Practices
# 1. Use truthiness directly
items = []
if not items: # ✓ Pythonic
print("Empty")
# if len(items) == 0: # ✗ Verbose
# 2. Avoid comparing to True/False explicitly
is_valid = True
if is_valid: # ✓
process()
# if is_valid == True: # ✗
# 3. Use 'is' for None checks
if result is None: # ✓
handle_none()
# if result == None: # ✗
# 4. Keep conditions simple — extract to variables
# Hard to read:
if user.age >= 18 and user.is_verified and not user.is_banned and user.balance > 0:
allow()
# Better:
is_eligible = user.age >= 18 and user.is_verified
is_active = not user.is_banned and user.balance > 0
if is_eligible and is_active:
allow()
# 5. Prefer positive conditions
if is_valid: # ✓ easier to understand
do_thing()
else:
handle_error()
# Avoid double negatives:
# if not is_invalid: # ✗ confusing
best_practices.py
Primary sources: Python Docs — if Statements · Python Docs — Pattern Matching
Ask your AI tutor! Not sure when to use match/case vs if/elif? Want help refactoring nested conditionals into guard clauses? Control flow is where programs become interesting — ask anything.
💻 Exercises
Write a script that takes a numeric score (0–100) and prints the letter grade: A (90–100), B (80–89), C (70–79), D (60–69), F (below 60). Also handle invalid scores (negative or above 100) with an error message.
Show solution
score = 85
if score < 0 or score > 100:
print("Invalid score!")
elif score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 70:
print("C")
elif score >= 60:
print("D")
else:
print("F")
Write a ticket pricing system. Base price is $10. Apply these rules in order: children (under 12) get 50% off, seniors (65+) get 40% off, students get 20% off (pass a boolean), weekends add a $2 surcharge (pass a boolean). Print the final price.
Show solution
age = 70
is_student = False
is_weekend = True
price = 10.00
if age < 12:
price *= 0.5
elif age >= 65:
price *= 0.6
elif is_student:
price *= 0.8
if is_weekend:
price += 2.00
print(f"Ticket price: ${price:.2f}")
# Ticket price: $8.00 (senior 40% off = $6, + $2 weekend)
Write code that takes a number n and prints:
"FizzBuzz" if divisible by both 3 and 5,
"Fizz" if divisible by 3 only,
"Buzz" if divisible by 5 only,
or the number itself otherwise. Test with n = 15, 9, 10, and 7.
Show solution
for n in [15, 9, 10, 7]:
if n % 3 == 0 and n % 5 == 0:
print("FizzBuzz")
elif n % 3 == 0:
print("Fizz")
elif n % 5 == 0:
print("Buzz")
else:
print(n)
# FizzBuzz
# Fizz
# Buzz
# 7