Learn Without Walls
← Previous Lesson Lesson 4 of 4 Practice Problems →

Lesson 4.4: Nested Conditionals

What You'll Learn

What Are Nested Conditionals?

A nested conditional is an if statement placed inside another if statement. The inner if is only checked when the outer if condition is True.

Nested conditional: An if statement that appears inside the block of another if statement. Each level of nesting adds another layer of indentation.
has_ticket = True
age = 15

if has_ticket:
    print("You have a ticket.")
    if age >= 18:
        print("Welcome to the R-rated movie!")
    else:
        print("Sorry, this movie is for adults only.")
else:
    print("You need a ticket first.")
You have a ticket. Sorry, this movie is for adults only.

Notice how the inner if/else is indented one level deeper than the outer if. This creates a clear hierarchy of decisions.

Building Decision Trees

Nested conditionals let you build step-by-step decision trees where each choice leads to more specific choices.

Real-World Example: Shipping Calculator

country = "US"
weight = 3.5  # kg
is_member = True

if country == "US":
    if weight <= 2:
        shipping = 5.99
    elif weight <= 5:
        shipping = 9.99
    else:
        shipping = 14.99

    # Members get free shipping
    if is_member:
        shipping = 0
        print("Free shipping for members!")
else:
    if weight <= 2:
        shipping = 15.99
    else:
        shipping = 29.99

print(f"Shipping cost: ${shipping}")
Free shipping for members! Shipping cost: $0

Real-World Example: ATM Withdrawal

balance = 500
pin_entered = "1234"
correct_pin = "1234"
withdrawal = 200

if pin_entered == correct_pin:
    print("PIN accepted.")
    if withdrawal <= balance:
        if withdrawal > 0:
            balance -= withdrawal
            print(f"Dispensing ${withdrawal}")
            print(f"New balance: ${balance}")
        else:
            print("Amount must be positive.")
    else:
        print("Insufficient funds.")
else:
    print("Incorrect PIN.")
PIN accepted. Dispensing $200 New balance: $300

Tracing Through Nested Code

When reading nested conditionals, trace through them step by step. Ask yourself at each level: "Is this condition True or False?" Then follow the appropriate path.

x = 15
y = 8

if x > 10:                # Step 1: 15 > 10? YES
    if y > 10:            # Step 2: 8 > 10? NO
        print("Both large")
    else:                 # Step 3: Go to else
        print("x large, y small")  # This prints!
else:
    if y > 10:
        print("x small, y large")
    else:
        print("Both small")
x large, y small

The Problem with Deep Nesting

While nesting is powerful, too many levels of nesting makes code hard to read and maintain. A common guideline is to avoid more than 3 levels of nesting.

Code Smell: If your code has more than 3 levels of indentation from nesting, it is time to refactor. Deeply nested code is often called "arrow code" because of its triangular shape.
# BAD: Too deeply nested (hard to read)
if user_logged_in:
    if has_permission:
        if file_exists:
            if file_not_locked:
                if disk_space_available:
                    # Finally do something - 5 levels deep!
                    save_file()

Refactoring Nested Conditionals

There are several strategies to flatten nested code and make it more readable.

Strategy 1: Combine Conditions with and

# BEFORE: Nested
if age >= 18:
    if has_id:
        print("Entry allowed")

# AFTER: Flattened with and
if age >= 18 and has_id:
    print("Entry allowed")

Strategy 2: Early Return / Guard Clauses

# BEFORE: Deeply nested
if user_logged_in:
    if has_permission:
        if file_exists:
            process_file()
        else:
            print("File not found")
    else:
        print("No permission")
else:
    print("Not logged in")

# AFTER: Guard clauses (check failures first)
if not user_logged_in:
    print("Not logged in")
elif not has_permission:
    print("No permission")
elif not file_exists:
    print("File not found")
else:
    process_file()
Guard clause: A condition that checks for an invalid case and handles it early, allowing the "happy path" (the normal case) to proceed without extra nesting.

When Nesting Is Appropriate

Nesting is not always bad. It is appropriate when the inner decision genuinely depends on the outer decision and the logic is clearer expressed hierarchically.

Good Use of Nesting: Category-Specific Logic

product_type = "food"
is_organic = True
price = 4.99

if product_type == "food":
    # Food-specific logic
    tax_rate = 0.0  # No tax on food
    if is_organic:
        print("Organic food item")
        discount = 0.10  # 10% organic discount
    else:
        discount = 0.0
elif product_type == "electronics":
    # Electronics-specific logic
    tax_rate = 0.08
    discount = 0.0
else:
    tax_rate = 0.06
    discount = 0.0

final_price = price * (1 + tax_rate) * (1 - discount)
print(f"Final price: ${final_price:.2f}")
Organic food item Final price: $4.49

Try It Yourself!

Write a ticket pricing program. The base price is $12. Apply these rules:

Check Your Understanding

What will this code print?

temp = 25
raining = False

if temp > 20:
    if raining:
        print("Warm and rainy")
    else:
        print("Warm and dry")
else:
    if raining:
        print("Cold and rainy")
    else:
        print("Cold and dry")

Answer: Warm and dry

temp > 20 is True (25 > 20), so we enter the first block. raining is False, so we go to the inner else and print "Warm and dry".

Key Takeaways

← Logical Operators Lesson 4 of 4 Practice Problems →