Guard clauses and early return
Nested if statements push the real work to the right, and an else can end up a screen away from its condition. Handle the special cases first, each with its own return or raise, and the main path runs unindented at the end.
def shipping(order):
if not order["items"]:
return 0
if order["country"] != "UK":
return 20
if order["total"] >= 50:
return 0
return 5
order = {"items": ["mug"],
"country": "UK", "total": 30}
print(shipping(order))Each guard answers one question and gets out of the way. By the last line, the reader knows every special case has been dealt with.
- Invalid input goes first, and raises.
- Then the cases with a fixed answer.
- Then the general rule.
Guards also make a new rule easy to add: it is one more guard, not another level of nesting.
Your task
Rewrite ticket_price(age, day, member) with guard clauses, keeping every price and error. Then add a new rule: children under 3 get in free (price 0).
The explanation opens here once every check passes.