Technology If, Elif, and Else | Python Tutorial

Learn with diagrams, code, systems and practical examples.

</>
TutorialsPythonIf, Elif, and Else
Core Python · Chapter 8

If, Elif, and Else

Choose which code should run based on conditions.

Why this matters

Real programs behave differently depending on input, state, or business rules.

Start with the idea

An if statement checks a condition. elif adds another condition if earlier ones did not match. else handles the remaining case.

IdeaUnderstand the purpose
CodeRun the smallest example
PracticeChange it yourself
SubjectVision learning pattern: understand the idea before memorizing syntax.

Small working example

Run this example first. Do not change several things at once; confirm the basic behavior, then experiment.

Python
score = 84

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
else:
    grade = "C or below"

print(grade)
Expected output
B
What to notice

The example is intentionally small. Focus on the chapter’s main idea before adding extra syntax or framework code.

Common beginner mistake

Mistake

Ordering broad conditions before specific ones so the specific branch can never run.

Better approach

Order conditions from most specific or highest priority to more general cases.

Quick recap

  • Branches express decisions.
  • Only the first matching branch runs.
  • Condition order matters.

Try it yourself

These are deliberately small. If you can complete them without copying the example, you are ready to continue.

  1. Create shipping rules for three order totals.
  2. Add a final else case for invalid input.

Core Python · next-day preparation

If, Elif, and Else: make one clear decision at a time

A program becomes useful when it can react to facts. Python’s if statement lets you ask a yes-or-no question and run a block only when that condition is true. elif lets you try another condition when the earlier one did not match, and else handles the remaining case.

Ordered branch decision flow Input facts move through the if condition, then the first elif condition, and finally the else fallback. Only the first true branch runs. factsorder total iftotal ≥ 75?true → free ship eliftotal ≥ 30?true → standard elsepickup
Original SubjectVision visual. Branch order is part of program behavior, not just formatting.

1. Start with the smallest useful branch

Suppose an order needs manual review when its total is unusually high. Begin with one condition before introducing a full chain.

order_total = 160

if order_total > 150:
    print("Manual review")

Expected output:

Manual review

The condition order_total > 150 is a Boolean expression. It evaluates to either True or False. If it is true, the indented block runs. If it is false, Python skips that block.

2. Use elif when the choices are mutually exclusive

A shipping method is a good example because one order should receive one final category. Put the highest-priority rule first, then the next rule, then a fallback.

order_total = 48

if order_total >= 75:
    shipping = "free"
elif order_total >= 30:
    shipping = "standard"
else:
    shipping = "pickup"

print(shipping)

Expected output: standard.

Python checks order_total >= 75 first. It is false, so Python checks the elif. That condition is true, so Python assigns "standard" and stops checking the remaining branches in this chain.

3. Branch order can silently change the answer

Predictable mistake: broad rule first
score = 96

if score >= 60:
    grade = "Pass"
elif score >= 90:
    grade = "Excellent"

The first condition already matches 96, so the more specific 90+ branch can never run.

Corrected version
score = 96

if score >= 90:
    grade = "Excellent"
elif score >= 60:
    grade = "Pass"
else:
    grade = "Review"

Put the narrower or higher-priority case before the broader case when the branches overlap.

4. Separate exclusive branches from independent checks

An if / elif / else chain chooses at most one branch. Two separate if statements are different: both can run.

One category

if temperature >= 30:
    label = "hot"
elif temperature >= 20:
    label = "mild"
else:
    label = "cool"

Use this when the outcomes compete and you want exactly one classification.

Two independent facts

if is_member:
    print("Member discount")

if has_coupon:
    print("Coupon applied")

Use separate checks when both facts can be true and both actions should happen.

5. Common beginner mistakes and fixes

if status == "paid" or "pending":

The second operand is a non-empty string, which is truthy. Write if status == "paid" or status == "pending":, or use membership such as if status in ("paid", "pending"):.

Using elif for independent actions

If both actions should be allowed to run, use two if statements. An elif is skipped after an earlier branch matches.

Missing the final fallback

An else is optional. Add one when “everything else” is a meaningful case that deserves explicit behavior.

Hiding invalid input inside a normal else

If invalid data should be rejected, validate it explicitly. Do not let an impossible or malformed value quietly fall into a normal business category.

Repeating a complicated condition

Name a meaningful Boolean such as is_free_shipping when the rule is used repeatedly or needs explanation.

Nesting when a flat chain is clearer

Prefer a readable if / elif / else chain when several mutually exclusive cases are on the same level.

6. Realistic walkthrough: route a delivery request

Imagine a small delivery tool with three facts: whether the address is valid, whether same-day capacity exists, and whether the order total qualifies for free standard delivery.

address_valid = True
same_day_capacity = False
order_total = 82

if not address_valid:
    result = "fix address"
elif same_day_capacity:
    result = "same-day delivery"
elif order_total >= 75:
    result = "free standard delivery"
else:
    result = "standard delivery fee"

print(result)

Expected output: free standard delivery.

Notice the order. Invalid addresses are handled first because the rest of the routing logic should not matter until the input is usable. Then same-day capacity has priority. Only after those cases do we consider the order-total rule.

7. Prediction practice

  1. Set order_total = 75 in the shipping example. Which branch runs, and why?
  2. Swap the 30+ and 75+ checks. What wrong result becomes possible?
  3. Change same_day_capacity to True. Which later conditions are no longer evaluated?
  4. Write a branch chain for a support ticket: urgent, normal, or incomplete input.

Quick recap

  • if starts a conditional decision.
  • elif adds another condition only when earlier branches did not match.
  • else handles the remaining case and has no condition.
  • In one chain, Python executes only the first matching branch.
  • Branch order matters whenever conditions overlap.

Next chapter: Loops — repeat work without duplicating code.

Official references used

Trace lab · predict before reveal

Trace the decision before you trust the result

Branching mistakes are often hard to spot because every individual condition looks reasonable. The reliable habit is to trace the chain in order: evaluate one condition, decide whether it is true, and stop as soon as a branch in the chain runs. Use these exercises to practise that habit before relying on intuition.

Trace 1: overlapping thresholds

total = 95

if total >= 50:
    label = "standard reward"
elif total >= 90:
    label = "premium reward"
else:
    label = "no reward"

print(label)
Predict, then reveal

The output is standard reward. The 50+ condition is true first, so Python runs that branch and never evaluates the 90+ elif. If premium orders should receive a different result, the 90+ rule belongs first.

Trace 2: independent facts are not one ladder

is_member = True
has_coupon = True

if is_member:
    print("member benefit")
elif has_coupon:
    print("coupon benefit")
Predict, then reveal

Only member benefit prints. The elif belongs to the same exclusive chain, so it is skipped after the member branch matches. If the requirements say both benefits can apply, use two separate if statements.

Trace 3: validate before normal business branches

quantity = -2

if quantity >= 10:
    message = "bulk order"
elif quantity >= 1:
    message = "regular order"
else:
    message = "empty order"

print(message)
Predict, then reveal

The code prints empty order, but that may be a domain bug: -2 is not the same situation as zero. Add an explicit invalid-input branch such as if quantity < 0: before the normal order categories. Branch code should reflect meaningful domain states, not merely force every value into some label.

Trace 4: short-circuit facts can simplify a branch

user = None

if user is not None and user.is_admin:
    result = "admin"
else:
    result = "standard"

print(result)
Predict, then reveal

The output is standard. Because user is not None is false, Python does not evaluate user.is_admin. This connects the previous Booleans chapter to branching: build a safe condition first, then decide what branch should run.

Decision checklist: before you add another elif

QuestionIf yesIf no
Are these outcomes mutually exclusive?An if / elif / else chain may fit.Consider independent if statements.
Can two conditions both be true?Order the higher-priority or narrower case first.Order still matters for readability, but overlap is less risky.
Can input be invalid?Handle invalid state explicitly before normal categories.Keep the branch model focused on real outcomes.
Is the condition getting hard to read?Name a Boolean or extract a helper function.Keep the small condition close to the decision.

Mini-project: route a support request

Build a small triage function using four facts: whether required contact information exists, whether the issue is a security incident, whether the customer is blocked from working, and whether the request is informational. First write the priority order in plain English. Then turn that order into one readable branch chain.

A useful order might be: reject incomplete requests first; route security incidents to the security queue; route work-blocking issues to urgent support; otherwise route the request to normal support. Do not copy that order blindly—explain why each branch has its position.

has_contact = True
is_security_incident = False
is_blocking = True

if not has_contact:
    queue = "needs information"
elif is_security_incident:
    queue = "security"
elif is_blocking:
    queue = "urgent support"
else:
    queue = "normal support"

print(queue)

Expected output: urgent support. Now change two facts so more than one condition could be true. Predict which branch wins before running the code, then decide whether that priority matches the business rule.

Practice tasks

  1. Write a three-level battery message: critical, low, or okay. Make the narrowest threshold run first.
  2. Rewrite an if / elif chain as two independent if statements and explain how the possible outputs change.
  3. Create one invalid-input case that deserves its own branch instead of falling into else.
  4. Take one long condition and replace part of it with a named Boolean. Explain whether that improved the code.

Quick reference

Which Python branching shape should I use?

Choose the shape of the decision before writing the conditions. This keeps mutually exclusive outcomes separate from independent actions and makes branch order easier to explain.

IntentPatternReasonCommon mistake
One optional actionifNo competing outcome is needed.Adding an empty or artificial else.
Exactly two outcomesif / elseEvery valid input belongs to one side.Using two independent checks and allowing both actions.
One result from several categoriesif / elif / elseOnly the first matching branch runs.Putting a broad condition before a narrower one.
Several actions may all happenseparate if statementsEach fact is checked independently.Using elif and skipping later actions.
Reject unusable input firstvalidation ifBad input should not fall into a normal category.Letting a catch-all else hide an invalid state.

Independent actions

if is_member:
    apply_member_discount()

if has_coupon:
    apply_coupon()

Both facts can be true, so both actions may run.

One prioritized result

if input_needs_fixing:
    route = "fix input"
elif is_urgent:
    route = "urgent"
else:
    route = "normal"

Only one final route is wanted, so the order is part of the program behavior.

Branch coverage planner

Test the edges, not only the happy path

For a ladder such as order_total >= 75, one example above the threshold is not enough. Use this small matrix to choose test inputs that expose ordering, boundary, validation and fallback mistakes before they reach production.

Case to testExample inputWhat should happenBug this can reveal
Just below a thresholdorder_total = 74Do not enter the >= 75 branch.Using >, >=, or the wrong threshold unintentionally.
Exactly on a thresholdorder_total = 75Enter the >= 75 branch.Off-by-one boundary logic.
Two conditions are both truesame_day_capacity = True, order_total = 100The earlier same-day branch wins if the ladder is intentionally prioritized.A broad or high-priority branch being placed in the wrong order.
Invalid domain inputorder_total = -1Validation should reject it before normal delivery categories.A catch-all else disguising bad input as a valid state.
No explicit condition matchesValid input below every special ruleThe final else should represent the intended ordinary case.An incomplete ladder or an else that is doing too many unrelated jobs.

Try it: run the overlapping and threshold cases in the Which branch wins? explorer below, predict the branch first, then compare the result with this matrix.

Next action: choose the branching shape here, then trace one concrete input through the conditions before running the program.

Interactive practice

Which branch wins?

Change the facts, then watch Python's first-match rule choose exactly one route. This is the same reasoning you should do before you run a real if / elif / else chain.

Delivery facts

Current result

free standard delivery

The address is valid, same-day capacity is false, and the order total qualifies for the 75+ branch.

Useful for a study note, code review, or asking someone to predict the branch before you show the answer.

The order Python checks

  1. if not address_valid → fix address
  2. elif same_day_capacity → same-day delivery
  3. elif order_total >= 75 → free standard delivery
  4. else → standard delivery fee
Show the equivalent Python
Copy this as a starting point, then replace the delivery facts with your own domain rules.
if not address_valid:
    result = "fix address"
elif same_day_capacity:
    result = "same-day delivery"
elif order_total >= 75:
    result = "free standard delivery"
else:
    result = "standard delivery fee"