if...elif...else Programs
More than two answers, and only one of them wanted. The rungs are checked from the top down, the first true one wins, and everything below it is not looked at. That last part is what decides whether these programs work — so the order of the rungs is the thing to get right.
1Program 1 — positive, negative or zero
The program on the last page called zero negative. Fix it: three outcomes, three answers.
- one number,
num
- test
num > 0 - if that failed, test
num < 0 - if that failed too, it can only be zero
- one of three messages
# positive, negative or zero — three outcomes, so two tests and an else
num = int(input('Enter a number: '))
if num > 0:
print('The number is positive')
elif num < 0:
print('The number is negative')
else:
print('The number is zero')Enter a number: 0 The number is zero
Enter a number: -8 The number is negative
Notice there is no test for zero. There does not need to be: a number that is not above zero and not below it can only be zero, so the else has already worked it out. Three outcomes take two conditions, four take three, and so on — the last case always comes free.
2Program 2 — the grade for a percentage
90 and above is an A, 75 and above a B, 60 and above a C, 33 and above a D, and anything below that an F. Ask for the percentage and print the grade.
# the grade for a percentage — the first true rung wins
per = float(input('Enter the percentage: '))
if per >= 90:
grade = 'A'
elif per >= 75:
grade = 'B'
elif per >= 60:
grade = 'C'
elif per >= 33:
grade = 'D'
else:
grade = 'F'
print('Percentage:', per)
print('Grade:', grade)Enter the percentage: 95 Percentage: 95.0 Grade: A
Enter the percentage: 62 Percentage: 62.0 Grade: C
Enter the percentage: 20 Percentage: 20.0 Grade: F
per = float(input('Enter the percentage: '))float(), not int(), because 62.5 is a real percentage. It is also why the output prints 95.0 rather than 95 — float() keeps the decimal point even when there is nothing after it.
elif per >= 75:Read as 'otherwise, is it at least 75?'. It is only reached when per >= 90 was false, which is why it does not also need per < 90 written into it.
grade = 'B'Each branch stores the answer instead of printing it. That is what lets the two print() lines at the bottom run once, whatever the grade turned out to be.
per >= 75 and per < 90. By the time Python reaches that rung it already knows the percentage is below 90 — the rung above was false. Writing the upper limit in as well is not wrong, only twice the work and twice the chance of a typo.3The mistake everybody makes: the wrong order
Here is the same ladder with the rungs turned round. Every single test in it is correct on its own:
# the same ladder with its rungs in the wrong order
per = float(input('Enter the percentage: '))
if per >= 33:
grade = 'D'
elif per >= 60:
grade = 'C'
elif per >= 75:
grade = 'B'
elif per >= 90:
grade = 'A'
else:
grade = 'F'
print('Grade:', grade)Enter the percentage: 95 Grade: D
>=, they must go from the strictest down to the loosest.4Program 3 — the largest of three numbers
Ask for three numbers and print the largest. Equal numbers must not break it.
# the largest of three numbers
a = int(input('Enter the first number: '))
b = int(input('Enter the second number: '))
c = int(input('Enter the third number: '))
if a >= b and a >= c:
largest = a
elif b >= c:
largest = b
else:
largest = c
print('The largest number is', largest)Enter the first number: 34 Enter the second number: 91 Enter the third number: 27 The largest number is 91
The second rung looks too short — where is the comparison with a? It is not needed. Reaching that rung means the first was false, so a is not the biggest; the contest is between b and c alone. And the else needs no test at all, because if b is not at least c, then c is the answer.
>=, not >, in every rung. With three equal numbers, a > b is false, so the first rung would be skipped, and so would the second — the program would say c is the largest. It happens to be right, but only by luck. >= answers the question that was actually asked.5Program 4 — an electricity bill in slabs
The first 100 units cost ₹3 each, the next 200 cost ₹5 each, the next 200 cost ₹7 each, and anything beyond 500 units costs ₹9 each. Ask for the units used and print the bill.
- the units used,
units
- find which slab the reading falls in
- charge the full slabs below it, then the part-slab it lands in
- the units and the amount
# an electricity bill, charged in slabs: the first 100 units are the cheapest
units = int(input('Enter the units used: '))
if units <= 100:
amount = units * 3
elif units <= 300:
amount = 100 * 3 + (units - 100) * 5
elif units <= 500:
amount = 100 * 3 + 200 * 5 + (units - 300) * 7
else:
amount = 100 * 3 + 200 * 5 + 200 * 7 + (units - 500) * 9
print('Units used:', units)
print('Bill amount: Rs', amount)Enter the units used: 250 Units used: 250 Bill amount: Rs 1050
Enter the units used: 90 Units used: 90 Bill amount: Rs 270
Enter the units used: 620 Units used: 620 Bill amount: Rs 3780
Check the 250-unit run by hand, because this is the part that is misread: the first 100 units are charged at ₹3 (= 300) and only the remaining 150 at ₹5 (= 750). Total ₹1050. A slab rate applies to the units inside that slab, not to the whole reading — which is why every branch says units - 100 or units - 300 rather than units.
<= rather than >=. Whichever operator you use, the rule is the same: each rung must be reachable only when every rung above it has failed. Sort the boundaries and check them in order.6Program 5 — a four-function calculator
Show a menu of four operations, ask which one the user wants and which two numbers to use, and print the answer. Refuse to divide by zero, and say something sensible if the choice is not on the menu.
# a four-function calculator driven by a menu
print('1. Add')
print('2. Subtract')
print('3. Multiply')
print('4. Divide')
choice = int(input('Enter your choice (1-4): '))
a = float(input('Enter the first number: '))
b = float(input('Enter the second number: '))
if choice == 1:
print('Answer:', a + b)
elif choice == 2:
print('Answer:', a - b)
elif choice == 3:
print('Answer:', a * b)
elif choice == 4:
if b == 0:
print('Cannot divide by zero')
else:
print('Answer:', a / b)
else:
print('That is not a choice on the menu')1. Add 2. Subtract 3. Multiply 4. Divide Enter your choice (1-4): 3 Enter the first number: 12 Enter the second number: 8 Answer: 96.0
1. Add 2. Subtract 3. Multiply 4. Divide Enter your choice (1-4): 4 Enter the first number: 7 Enter the second number: 0 Cannot divide by zero
1. Add 2. Subtract 3. Multiply 4. Divide Enter your choice (1-4): 9 Enter the first number: 1 Enter the second number: 2 That is not a choice on the menu
Two things are new here. The rungs test == against fixed values rather than ranges, so their order does not matter — no choice can match two rungs. And the fourth rung contains a whole if…else of its own: eight spaces of indentation, sitting inside a branch that is itself indented by four.
else is the reason this program cannot be broken by its user. Somebody will type 9. Without a final else the program would end in silence, which the user reads as a crash. A ladder that a person types into should nearly always finish with an else that says what went wrong.b == 0 is checked before dividing, not after. a / b with b at zero raises ZeroDivisionError and the program stops there and then — there is no answer left to inspect afterwards. Guard first; divide second.7Recap
Checked top to bottom. The moment one is true, its block runs and every rung below it is skipped without being tested.
The else is the last outcome and needs no condition — three answers take two conditions, five take four.
With ranges (>= or <=) a loose test placed first swallows every value. With == against fixed values, order is free.
Anything a person types can be something you did not expect. The else is what tells them so instead of ending in silence.
- 1
Ask for a number from 1 to 7 and print the day of the week it stands for.
Hint · Seven rungs testing
==, and anelsefor anything else. Order is free here. - 2
Ask for a character and say whether it is a vowel, a consonant or not a letter at all.
Hint ·
ch.isalpha()answers the third question, and it has to be asked before the other two. - 3
Ask for income and work out tax: nothing up to ₹250000, 5% on the next ₹250000, and 20% above ₹500000.
Hint · The same slab shape as the electricity bill. Charge each slab on the part of the income inside it.
- 4
Ask for a BMI value and print
Underweight,Normal,OverweightorObese.Hint · The boundaries are 18.5, 25 and 30 — a job for
float(), and go strictest first. - 5
Ask for three sides and say whether the triangle is equilateral, isosceles or scalene.
Hint · All three equal first; then any two equal — three comparisons joined by
or.
A ladder tests per >= 33 first, then per >= 60, then per >= 90. A student scores 95. What grade do they get?
Why does the largest-of-three program not compare b with a on its elif rung?
In the electricity bill, why is the 250-unit charge 100 * 3 + 150 * 5 rather than 250 * 5?