☰ Learn Python Tutorial Menu
Making Decisions: if / elif / else
Written by CSA mentors · Updated 26 Sept 2026 · 5 min read
A fraud team at a Karachi bank once shipped a rule that flagged every 2 am purchase of Rs 200 as high risk. The call centre was swamped by lunchtime. Nothing had crashed and no error was raised. One missing pair of parentheses in an if statement did it. Rules are the heart of data work (flag this, discount that, pass at 40 marks), and Python writes them with if, elif and else. We'll look at how they flow, how to combine conditions, and how that bank's mistake happens.
The basic if
amount = 125000
if amount > 100000:
print("Large transaction: needs manager approval")
print("Processing complete")
Notice three things. The condition ends with a colon. The line under it is indented four spaces, and that indented block is what runs when the condition is true. The last print is not indented, so it runs every time. Indentation isn't decoration in Python. It's what tells the interpreter which lines belong to the if.
if / elif / else
With several possibilities, chain them. Python checks each condition in order and runs only the first block whose condition is true. else catches whatever is left.
marks = 74
if marks >= 80:
grade = "A"
elif marks >= 70:
grade = "B"
elif marks >= 60:
grade = "C"
elif marks >= 40:
grade = "D"
else:
grade = "F"
print(f"Marks {marks} -> grade {grade}") # Marks 74 -> grade B
Order matters. Put marks >= 40 first and every passing student gets a D, because 74 satisfies it and Python stops looking. Most specific (or highest) test first.
Combining conditions
city = "Karachi"
order_total = 8500
is_member = False
if city == "Karachi" and order_total >= 5000:
shipping = 0
elif is_member or order_total >= 10000:
shipping = 150
else:
shipping = 300
print("Shipping:", shipping) # 0
and needs both sides true. or needs at least one. Python evaluates left to right and stops as soon as the answer is known (short-circuiting), which is why x != 0 and total / x > 2 is safe. The division never runs when x is zero.
Truthiness
An if doesn't need a comparison. Python treats a few values as false on their own. 0, 0.0, "", None, and empty collections such as [] and {}. Everything else counts as true.
remarks = ""
if remarks:
print("Has remarks")
else:
print("No remarks") # this runs
pending = [1042, 1043]
if pending:
print(len(pending), "orders pending")
Write if pending:, not if len(pending) > 0:. Reviewers at Lahore software houses will flag the long form in a code review.
Nested ifs, and when to flatten them
account_type = "savings"
balance = 45000
if account_type == "savings":
if balance >= 50000:
rate = 0.09
else:
rate = 0.07
else:
rate = 0.0
Nesting works, but past two levels nobody can follow it. Often and flattens it.
if account_type == "savings" and balance >= 50000:
rate = 0.09
elif account_type == "savings":
rate = 0.07
else:
rate = 0.0
The one-line if
For a simple choice between two values, Python has a compact form.
status = "PASS" if marks >= 40 else "FAIL"
label = "overdue" if days_late > 0 else "on time"
Use it only when both branches are short. Anything longer belongs in a normal if.
Two mistakes that never raise an error
| Mistake | Why it is wrong | Fix |
|---|---|---|
if status == "paid" or "settled": | "settled" is always true, so the whole test is always true | if status in ("paid", "settled"): |
if amount > "1000": | Comparing a number to text raises TypeError; comparing two strings compares alphabetically, so "9" > "1000" | Convert with int() first |
| Wrong indentation after the block | A line meant to run always is accidentally inside the if | Check the indent of every line |
The first one is the mistake we correct most often in homework. It reads like English, so it looks right. Python reads it as (status == "paid") or ("settled"), and a non-empty string is always true.
Worked example, a small rule engine
amount = 185000
hour = 2 # 2 am
country = "PK"
daily_count = 7
risk = "low"
if country != "PK":
risk = "high"
elif amount > 150000 and (hour < 6 or hour > 23):
risk = "high"
elif amount > 150000 or daily_count > 5:
risk = "medium"
print(f"Transaction risk: {risk}") # high
Back to the 2 am false alarms: The bank's first version of that middle rule was
if amount > 150000 or hour < 6 or hour > 23, with no parentheses. Any purchase before 6 am was high risk regardless of amount, so a Rs 200 top-up at 2 am woke up the fraud desk. Grouping the time check in parentheses and joining it to the amount check withandcut the false alerts to a trickle the same day. Precedence bugs in conditions are cheap to make and expensive to live with, so when you mixandandor, always add brackets.
Five things to keep
if,elif,else. The first true branch runs, the rest are skipped.- Colons and consistent four-space indentation define the blocks.
- Combine tests with
and,or,not, and bracket them when you mix them. - Empty strings, zero,
Noneand empty collections count as false. x in (a, b, c)is how you test several allowed values.
Homework
- Write a K-Electric slab calculator: units up to 100 cost Rs 12 each, 101 to 300 cost Rs 18 each for the units above 100, and units above 300 cost Rs 25 each. Print the bill for 342 units.
- Given
age,has_cnicandcity, print"eligible"if the person is 18 or older, has a CNIC, and lives in Punjab or Sindh (assume a variableprovince); otherwise print the first reason they fail. - Rewrite
if x > 0: sign = "positive"/else: sign = "non-positive"as a single conditional expression.
Lesson 6 of 26
Sign in to track your progress and earn learning points for every lesson you finish.
