Lesson 4 • Beginner

    Control Flow: Making Decisions in Python

    Learn how to make your programs smart by having them make decisions based on conditions.

    What You'll Learn in This Lesson

    • How if, elif, and else make programs make decisions
    • How comparison operators (==, >, <) work in conditions
    • How to combine conditions with and, or, not
    • Nested if statements for complex logic
    • The one-line ternary if expression
    • Real-world examples like grade checkers and age validators

    What is Control Flow?

    Control flow is how your program decides what code to run based on conditions. Without it, programs would just run line by line, doing the same thing every time.

    With control flow, your program can:

    • Check if a user is old enough to vote
    • Show different messages based on a score
    • Validate passwords
    • Make games react to player choices

    Real-world analogy:

    Think of control flow like a traffic light. The light checks conditions (time, sensors) and decides whether to show green, yellow, or red. Your program works the same way!

    🧠 How Python Reads Conditions: The Mental Model

    Before writing a single line of control flow, build this mental model — it explains every behaviour you'll encounter.

    Rule 1: Python reads conditions top to bottom

    It checks the first if, then each elif in order. The moment one is True, it runs that block and skips all the rest.

    Rule 2: Only ONE branch ever runs

    Even if multiple conditions would be True, only the first True branch executes. This is why order matters when writing elif chains.

    Rule 3: else is the safety net

    else has no condition — it runs when none of the above conditions were True. It's optional but gives your program a guaranteed fallback.

    Watch how order changes the result:

    ❌ Wrong order — catches everything at 90+:

    score = 95
    
    if score >= 60:
        grade = "C"   # ← This runs first!
    elif score >= 80:
        grade = "B"   # Never reached
    elif score >= 90:
        grade = "A"   # Never reached
    
    print(grade)  # "C"  — WRONG

    ✅ Correct order — highest first:

    score = 95
    
    if score >= 90:
        grade = "A"   # ← This runs!
    elif score >= 80:
        grade = "B"
    elif score >= 60:
        grade = "C"
    
    print(grade)  # "A"  — CORRECT

    When using >= ranges, always check the most specific / highest condition first.

    1. The if Statement

    The if statement is the simplest form of control flow. It checks a condition and runs code only if that condition is True.

    # Syntax:

    if condition:

    code to run if True

    PartDescription
    ifKeyword that starts the condition check
    conditionAn expression that evaluates to True or False
    :Required colon at the end of the line
    Indented codeCode that runs only if condition is True (4 spaces)

    Try It: Basic if Statement

    Change the age value and observe which lines print

    Try it Yourself »
    Python
    # Simple if statement
    age = 18
    
    if age >= 18:
        print("You can vote!")
        print("You're an adult!")
    
    print("This always prints")
    
    # Try changing age to 15 and see what happens!

    2. The if-else Statement

    What if you want to do something different when the condition is False? Use else to specify an alternative action.

    # Syntax:

    if condition:

    code if True

    else:

    code if False

    If condition is True:

    Run the first block, skip the else block

    If condition is False:

    Skip the first block, run the else block

    Try It: if-else Statement

    See how else provides an alternative path

    Try it Yourself »
    Python
    # if-else example
    temperature = 25
    
    if temperature > 30:
        print("It's hot outside!")
        print("Stay hydrated!")
    else:
        print("The weather is nice.")
        print("Enjoy your day!")
    
    # Try: Change temperature to 35

    3. The if-elif-else Chain

    When you have more than two possibilities, use elif(short for "else if") to check multiple conditions.

    # Syntax:

    if condition1:

    code for condition1

    elif condition2:

    code for condition2

    elif condition3:

    code for condition3

    else:

    code if none are True

    Try It: Grading System

    Classic example of multiple conditions

    Try it Yourself »
    Python
    # Grading system example
    score = 85
    
    if score >= 90:
        grade = "A"
        print("Excellent work!")
    elif score >= 80:
        grade = "B"
        print("Good job!")
    elif score >= 70:
        grade = "C"
        print("Not bad!")
    elif score >= 60:
        grade = "D"
        print("You passed.")
    else:
        grade = "F"
        print("Need improvement.")
    
    print(f"Your grade: {grade}")
    
    # Try different scores: 95, 75, 55

    4. Comparison Operators in Conditions

    Conditions use comparison operators to compare values. These always return True or False.

    OperatorMeaningExampleResult
    ==Equal to5 == 5True
    !=Not equal to5 != 3True
    >Greater than10 > 5True
    <Less than3 < 7True
    >=Greater than or equal5 >= 5True
    <=Less than or equal4 <= 4True

    5. Combining Conditions with Logical Operators

    You can combine multiple conditions using logical operators:and, or, and not.

    OperatorDescriptionExample
    andBoth conditions must be Trueage >= 18 and has_id
    orAt least one condition must be Trueage < 12 or age > 65
    notReverses the conditionnot is_banned

    Try It: Logical Operators

    Combine multiple conditions

    Try it Yourself »
    Python
    # Combining conditions
    age = 25
    has_ticket = True
    is_vip = False
    
    # Using 'and' - both must be True
    if age >= 18 and has_ticket:
        print("Welcome to the concert!")
    
    # Using 'or' - at least one must be True
    if age < 12 or age > 65:
        print("You get a discount!")
    else:
        print("Regular price applies.")
    
    # Using 'not' - reverses the condition
    if not is_vip:
        print("Please use the regular entrance.")
    
    # Try changing the values!

    Truthy and Falsy Values: Conditions Without ==

    You don't always need to write == True or != "". Python evaluates any value as either truthy or falsy in a condition — and knowing this makes your code cleaner and more Pythonic.

    Falsy values — treated as False

    • 0 — the integer zero
    • 0.0 — the float zero
    • "" — empty string
    • [] — empty list
    • None — no value
    • False — boolean False

    Truthy values — treated as True

    • 1, -5, 3.14 — any non-zero number
    • "hello" — any non-empty string
    • [1, 2] — any non-empty list
    • True — boolean True

    Practical truthy/falsy patterns:

    # Checking if a variable has a value
    name = ""
    if name:                       # Same as: if name != ""
        print(f"Hello, {name}!")
    else:
        print("No name provided")  # ← This runs
    
    # Checking if a number is non-zero
    score = 0
    if not score:                  # Same as: if score == 0
        print("You haven't scored yet!")
    
    # Checking if a list has items (you'll learn lists soon)
    items = []
    if items:
        print("Cart has items")
    else:
        print("Your cart is empty")  # ← This runs
    
    # 'None' check — very common in real code
    result = None
    if result is None:
        print("No result yet — still processing")

    6. Nested If Statements

    You can put an if statement inside another if statement. This is called nesting and is useful for complex decisions.

    Try It: Nested Conditions

    Multiple layers of decision making

    Try it Yourself »
    Python
    # Nested if example
    age = 25
    has_id = True
    
    if age >= 18:
        print("You're old enough.")
        if has_id:
            print("ID verified. Entry allowed!")
        else:
            print("Please show your ID.")
    else:
        print("Sorry, you must be 18 or older.")
    
    # The inner if only runs if the outer if is True

    🛡️ Guard Clauses: Writing Cleaner Conditions

    Deeply nested if statements are hard to read. Professional Python developers use a technique called guard clauses — checking for bad conditions early and exiting, which keeps the main logic flat and readable.

    ❌ The "pyramid of doom" — deeply nested:

    def process_order(user, cart, payment):
        if user:
            if user["verified"]:
                if cart:
                    if len(cart) > 0:
                        if payment:
                            print("Order placed!")
                        else:
                            print("No payment")
                    else:
                        print("Cart empty")
                else:
                    print("No cart")
            else:
                print("Not verified")
        else:
            print("No user")

    5 levels deep — hard to follow, easy to make mistakes

    ✅ Guard clauses — flat and readable:

    def process_order(user, cart, payment):
        if not user:
            print("No user")
            return
    
        if not user["verified"]:
            print("Not verified")
            return
    
        if not cart or len(cart) == 0:
            print("Cart empty")
            return
    
        if not payment:
            print("No payment")
            return
    
        print("Order placed!")  # Clean!

    Each failure exits early — main logic is at ground level

    The rule: reject bad cases first

    Check for invalid input, missing data, or error conditions at the top. Once you've handled those, write the main happy-path logic without nesting. This is standard practice in professional codebases — it's called the early return pattern.

    You'll use return properly when you learn functions in a later lesson. For now, just understand that flat code beats nested code.

    7. Indentation: Python's Secret Sauce

    Indentation is not optional in Python! It tells Python which code belongs to which block. Use 4 spaces (or 1 tab) for each level.

    Correct

    if age >= 18:
        print("Adult")
        print("Can vote")

    Wrong

    if age >= 18:
    print("Adult")  # Error!

    Common Indentation Errors:

    • IndentationError: expected an indented block - Missing indentation after colon
    • IndentationError: unexpected indent - Random indentation where not needed
    • IndentationError: unindent does not match - Mixing tabs and spaces

    Common Mistakes to Avoid

    Using = instead of ==

    if x = 5: is wrong. Use if x == 5:

    Forgetting the colon :

    if x == 5 is wrong. Add colon: if x == 5:

    Wrong capitalization of True/False

    true and TRUE don't work. Use True and False

    Putting elif after else

    else must always come last in a chain

    8. The Ternary Operator (One-Line If)

    Python has a shorthand way to write simple if-else statements in one line. This is called the ternary operator or conditional expression.

    # Syntax:

    value_if_true if condition else value_if_false

    Try It: Ternary Operator

    Write compact conditional expressions

    Try it Yourself »
    Python
    # Normal if-else
    age = 20
    if age >= 18:
        status = "Adult"
    else:
        status = "Minor"
    print(status)
    
    # Same thing with ternary operator
    age = 20
    status = "Adult" if age >= 18 else "Minor"
    print(status)
    
    # Practical example
    score = 75
    result = "Pass" if score >= 60 else "Fail"
    print(f"Result: {result}")

    🔀 match / case — Python's Modern Switch Statement (Python 3.10+)

    Python 3.10 introduced match/case — a cleaner way to check a value against multiple exact options. Think of it as a smarter, more readable alternative to a long elif chain when you're matching against specific values.

    Old way — elif chain:

    command = "quit"
    
    if command == "start":
        print("Starting...")
    elif command == "stop":
        print("Stopping...")
    elif command == "pause":
        print("Pausing...")
    elif command == "quit":
        print("Quitting...")
    else:
        print("Unknown command")

    New way — match/case:

    command = "quit"
    
    match command:
        case "start":
            print("Starting...")
        case "stop":
            print("Stopping...")
        case "pause":
            print("Pausing...")
        case "quit":
            print("Quitting...")
        case _:
            print("Unknown command")

    The case _: at the bottom is the wildcard — it matches anything that didn't match above (equivalent to else).

    match/case with multiple values per case:

    day = "Saturday"
    
    match day:
        case "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday":
            print("It's a weekday — get to work!")
        case "Saturday" | "Sunday":
            print("It's the weekend!")
        case _:
            print("That's not a day of the week")

    The | symbol means "or" inside a case — very handy for grouping related values.

    9. Practical Examples

    Example 1: Login Validator

    Login Validator

    Validate username and password

    Try it Yourself »
    Python
    # Simple login system
    correct_username = "admin"
    correct_password = "secret123"
    
    # Simulated user input
    entered_username = "admin"
    entered_password = "secret123"
    
    if entered_username == correct_username and entered_password == correct_password:
        print("Login successful! Welcome!")
    else:
        print("Invalid username or password.")
    
    # Try changing the entered values

    Example 2: Number Classifier

    Number Classifier

    Classify numbers by sign and parity

    Try it Yourself »
    Python
    # Check if a number is positive, negative, or zero
    number = -5
    
    if number > 0:
        print(f"{number} is positive")
    elif number < 0:
        print(f"{number} is negative")
    else:
        print("The number is zero")
    
    # Bonus: Check if even or odd
    if number != 0:
        if number % 2 == 0:
            print("And it's even!")
        else:
            print("And it's odd!")

    Example 3: Age Classifier

    Age Classifier

    Categorize by age group

    Try it Yourself »
    Python
    # Classify age into categories
    age = 25
    
    if age < 0:
        print("Invalid age!")
    elif age < 13:
        print("Child")
    elif age < 20:
        print("Teenager")
    elif age < 60:
        print("Adult")
    else:
        print("Senior")
    
    # Try different ages: 5, 15, 35, 70

    🌍 Real-World Control Flow Patterns

    The same handful of patterns appear in almost every real program. Recognise them and you'll be able to write production-quality logic from day one.

    Pattern 1: Input validation — reject bad data first

    username = "Al"
    password = "abc"
    
    if len(username) < 3:
        print("Username must be at least 3 characters")
    elif len(password) < 8:
        print("Password must be at least 8 characters")
    elif " " in username:
        print("Username cannot contain spaces")
    else:
        print("Account created successfully!")

    Validate before processing. Always check for invalid states first and give the user clear, specific feedback.

    Pattern 2: Range banding — categorise a value

    bmi = 22.5
    
    if bmi < 18.5:
        category = "Underweight"
        advice   = "Consider eating more nutritious food"
    elif bmi < 25.0:
        category = "Healthy weight"
        advice   = "Keep up your current lifestyle!"
    elif bmi < 30.0:
        category = "Overweight"
        advice   = "Consider more physical activity"
    else:
        category = "Obese"
        advice   = "Please consult a healthcare professional"
    
    print(f"BMI: {bmi} — {category}")
    print(f"Advice: {advice}")

    Range banding is used everywhere: credit scores, age groups, tax brackets, shipping rates, difficulty levels.

    Pattern 3: Default value — use a fallback if nothing set

    # User may or may not have set a display name
    display_name = ""
    username     = "alice_99"
    
    # Use display_name if it exists, otherwise fall back to username
    name_to_show = display_name if display_name else username
    print(f"Welcome, {name_to_show}!")  # "Welcome, alice_99!"
    
    # Common pattern: default settings
    user_language = None
    language = user_language if user_language else "English"
    print(f"Language: {language}")  # "Language: English"

    Pattern 4: Feature flags — enable/disable behaviour

    # Control features with simple booleans
    DEBUG_MODE    = True
    SHOW_ADS      = False
    PREMIUM_USER  = True
    
    if DEBUG_MODE:
        print("[DEBUG] Application started")
    
    if PREMIUM_USER:
        print("Enjoy your ad-free experience!")
    elif SHOW_ADS:
        print("[Ad: Learn Python Fast!]")
    
    message = "Premium member" if PREMIUM_USER else "Free tier"
    print(f"Account: {message}")

    Feature flags let you turn functionality on/off with a single variable change — widely used in production software for A/B testing and gradual rollouts.

    Mini-Project: Smart Shopping Discount Calculator

    This project uses every control flow concept from this lesson — if/elif/else, logical operators, truthy/falsy, ternary, and nested conditions — to solve a real business problem.

    Concepts used:

    • if/elif/else chains
    • Logical operators (and/or)
    • Truthy/falsy checks
    • Ternary for labels
    • Nested conditions
    • Comparison operators
    # Smart Shopping Discount Calculator
    item_price   = 85.00
    quantity     = 3
    is_member    = True
    promo_code   = "SAVE10"
    VALID_CODES  = ["SAVE10", "SUMMER20", "WELCOME5"]
    
    # === Validate inputs ===
    if item_price <= 0:
        print("Error: price must be greater than zero")
    elif quantity <= 0:
        print("Error: quantity must be at least 1")
    else:
        subtotal = item_price * quantity
    
        # === Apply bulk discount ===
        if quantity >= 10:
            bulk_discount = 0.15    # 15% for 10+
        elif quantity >= 5:
            bulk_discount = 0.10    # 10% for 5+
        elif quantity >= 3:
            bulk_discount = 0.05    # 5% for 3+
        else:
            bulk_discount = 0.00    # No bulk discount
    
        # === Member discount ===
        member_discount = 0.08 if is_member else 0.00
    
        # === Promo code discount ===
        if promo_code and promo_code in VALID_CODES:
            if promo_code == "SUMMER20":
                promo_discount = 0.20
            elif promo_code == "SAVE10":
                promo_discount = 0.10
            else:
                promo_discount = 0.05
        else:
            promo_discount = 0.00
            if promo_code:
                print(f"Note: '{promo_code}' is not a valid promo code")
    
        # === Calculate total (discounts don't stack beyond 25%) ===
        total_discount = min(bulk_discount + member_discount + promo_discount, 0.25)
        discount_amount = subtotal * total_discount
        final_price = subtotal - discount_amount
    
        # === Display receipt ===
        membership_label = "Member" if is_member else "Guest"
        print("=" * 35)
        print(f"  RECEIPT ({membership_label})")
        print("=" * 35)
        print(f"Item price:     £{item_price:.2f}")
        print(f"Quantity:       {quantity}")
        print(f"Subtotal:       £{subtotal:.2f}")
        print(f"Bulk discount:  {bulk_discount*100:.0f}%")
        print(f"Member discount:{member_discount*100:.0f}%")
        print(f"Promo discount: {promo_discount*100:.0f}%")
        print(f"Total saved:    £{discount_amount:.2f} ({total_discount*100:.0f}%)")
        print(f"TOTAL:          £{final_price:.2f}")
        print("=" * 35)

    Challenge — extend it:

    Can you add a check that prints "Free delivery!" if final_price >= 50? What about adding a loyalty points calculation: 1 point per £1 spent, but double points for members?

    💡 Thinking in Conditions: How Developers Design Logic

    Writing correct if/elif/else logic is a skill. Here's the thinking process professionals use when turning requirements into code.

    Step 1: List all possible outcomes

    Before writing a single line, ask: "What are all the different things that could happen?" Write them in plain English first.

    # Requirement: categorise a user's subscription
    # Outcomes:
    # - No subscription → show free tier
    # - Basic plan → show basic features
    # - Pro plan → show pro features + no ads
    # - Admin → show all features + admin panel

    Step 2: Identify edge cases

    What happens with invalid, unexpected, or extreme values? Always ask:

    • What if the input is empty or None?
    • What if a number is negative or zero?
    • What if the user hasn't set something yet?
    • What's the maximum/minimum allowed value?

    Step 3: Decide the order

    For range checks: put the most specific condition first. For validation: check the most likely failure first. For priority: most important condition at the top.

    Step 4: Test with examples

    Manually trace through your code with at least 3 test values — one for each branch, plus one edge case. Ask: "What value do I need to reach the else?" If you can't answer, your logic might have a gap.

    Summary: Quick Reference

    ConceptWhat It DoesSyntax
    ifRuns code if condition is Trueif x > 0:
    elseRuns if the if condition is Falseelse:
    elifChecks another conditionelif x > 5:
    andBoth conditions must be Trueif a and b:
    orAt least one must be Trueif a or b:
    notReverses the conditionif not a:
    TernaryOne-line if-elsex if cond else y

    What's Next?

    Now that you can make decisions, it's time to learn about loops! Loops let you repeat code multiple times, which is essential for:

    • Processing lists of items
    • Running code until a condition changes
    • Creating interactive programs
    🎉

    Lesson 4 complete — your programs can now make decisions!

    You've mastered if, elif, else, logical operators, nested conditions, and the ternary expression. Your programs are no longer just top-to-bottom scripts — they can respond to different situations.

    🚀 Up next: Loops — make Python repeat tasks automatically instead of copy-pasting code.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service