Chapter 7 — Conditionals: Teaching a Program to Make Decisions

Series B2 — Python Language Foundations

NoteIn this chapter, you will:
  • Use if, elif, and else so a program picks its own road
  • Understand indentation, an important Python rule
  • Choose one of many possibilities with match and case
  • Avoid the divide-by-zero error you met in Chapter 6
  • Build a fish-pond status checker

All scripts for this chapter are in the kode/ch07/ folder. On the web version, you can also download them all at once (zip).

In Chapter 6, your program could answer True or False. But that answer wasn’t used for anything yet. In this chapter, the answer becomes a decision: if the fish are heavy enough, then harvest; otherwise, wait. This is exactly the choice ingredient from Chapter 2.

if: do something only when the condition is true

01_if_basic.py
# Chapter 7 - if: do something only when the condition is true
weight_g = 520

if weight_g >= 500:
    print("The fish are ready to harvest")
    print("Write it in the harvest book")

print("Check finished")   # not indented: always carried out
The fish are ready to harvest
Write it in the harvest book
Check finished

Notice three things:

  1. After the condition comes a colon :.
  2. The lines that belong to the if are indented (in this book, 4 spaces). The two indented print lines are carried out only when the condition is true.
  3. The last line is not indented, so it is carried out always, whether the condition was true or false.
NoteREMEMBER

In Python, indentation is not decoration: it shows which lines belong to the if. Other languages use curly braces; Python uses indentation. Use 4 spaces consistently.

else: the second road

What if the condition is false? Add else (“otherwise”):

02_if_else.py
# Chapter 7 - if ... else: two roads
water_ph = 5.8

if water_ph < 6:
    print("pH too low: add lime")
else:
    print("pH is fine")
pH too low: add lime

The value 5.8 is less than 6, so the if road is chosen. Only one of the two roads is carried out, never both.

elif: many roads

Sometimes there are more than two choices. elif (short for else if, “otherwise, if…”) chains the next condition:

%%{init: {"flowchart": {"diagramPadding": 40}}}%%
flowchart TD
  A(["Cow weight"]) --> B{"500 kg or more?"}
  B -- "Yes" --> K1["Grade A"]
  B -- "No" --> C{"400 kg or more?"}
  C -- "Yes" --> K2["Grade B"]
  C -- "No" --> D{"300 kg or more?"}
  D -- "Yes" --> K3["Grade C"]
  D -- "No" --> K4["Not fit for sale"]

Flow for choosing a cow’s grade: conditions are checked from the top, stopping at the first true one.

03_elif.py
# Chapter 7 - if ... elif ... else: many roads (practice numbers)
weight_kg = 450

if weight_kg >= 500:
    grade = "Grade A"
elif weight_kg >= 400:
    grade = "Grade B"
elif weight_kg >= 300:
    grade = "Grade C"
else:
    grade = "Not fit for sale"

print(f"A {weight_kg} kg cow is: {grade}")
A 450 kg cow is: Grade B

Python checks the conditions from top to bottom, and stops at the first true one. Since 450 ≥ 400 but not ≥ 500, the result is Grade B.

WarningWARNING

The order of conditions matters. If you wrote weight_kg >= 300 first, a 450 kg cow would go straight into Grade C, because 450 ≥ 300 is also true. Arrange them from the strictest condition.

TipTIP

The grade limits in this example are only practice numbers. In a real project, keep limits like these in well-named variables (for example grade_a_limit_kg) so they are easy to change in one place.

Combining conditions

The and, or, and not operators from Chapter 6 can be used directly inside an if:

04_combined_conditions.py
# Chapter 7 - Combined conditions with and / or
diameter_cm = 45
height_m = 20
healthy = True

if diameter_cm >= 40 and healthy:
    print("The tree is fit to be felled")
elif height_m > 25 or not healthy:
    print("The tree needs checking first")
else:
    print("The tree is left to grow")
The tree is fit to be felled

Trace it: diameter 45 ≥ 40 and the tree is healthy, so the first condition is true and the other two are not even checked.

Protecting a program from errors

In Chapter 6 you saw ZeroDivisionError. Now we can prevent it: check first before dividing.

05_check_divide_by_zero.py
# Chapter 7 - Avoiding the ZeroDivisionError from Chapter 6
fish_count = 1250
pond_count = 0

if pond_count == 0:
    print("Pond count is 0: division cancelled")
else:
    print(f"Fish per pond: {fish_count // pond_count}")
Pond count is 0: division cancelled

This “check first, then act” pattern will be used often. Chapter 12 teaches another, more general way to handle errors.

match and case: choosing one of many values

When you compare one variable against many possible values, a chain of elif gets long. Python offers match and case:

06_match_case.py
# Chapter 7 - match / case: choosing one of many possible values
# (feed amounts are practice numbers, not advice)
animal = "goat"

match animal:
    case "cow":
        feed_kg = 25
    case "goat" | "sheep":
        feed_kg = 4
    case "chicken":
        feed_kg = 0.12
    case _:
        feed_kg = None

if feed_kg is None:
    print("Animal type not registered")
else:
    print(f"Feed for {animal}: {feed_kg} kg per head per day")
Feed for goat: 4 kg per head per day
  • match animal: means “look at what is in this variable”.
  • Each case is one possibility. The | sign means or (goat or sheep take the same road).
  • case _: catches everything else, like else.
  • is None is the way to compare with None (the “empty” value from Chapter 5).

match/case is available from Python 3.10. It is far more powerful than shown here: it can match the shape of data (for example a list holding two numbers). For Series B2, just use it to choose by a single value.

A trap: forgetting to indent

07_wrong_indent.py
# Chapter 7 - A mistake: forgetting to indent after if
weight_g = 520
if weight_g >= 500:
print("The fish are ready to harvest")
  File "07_wrong_indent.py", line 4
    print("The fish are ready to harvest")
    ^^^^^
IndentationError: expected an indented block after 'if' statement on line 3

IndentationError means “I expected an indented line after the if”. The message even names the line number of the if that demands the indentation. The cure: move the print line inward by 4 spaces.

Running Project B2: pond status

Now we give the pond calculator from Chapter 6 the ability to decide:

08_pond_status.py
# Chapter 7 - Running project B2: pond status from average weight
# (the 500 g and 400 g limits are practice numbers)
avg_weight_g = float(input("Average fish weight (grams): "))

if avg_weight_g >= 500:
    status = "READY TO HARVEST"
elif avg_weight_g >= 400:
    status = "ALMOST READY: check again next week"
else:
    status = "STILL GROWING"

print(f"Pond status: {status}")
Average fish weight (grams): 460
Pond status: ALMOST READY: check again next week

With an average weight of 460 grams, the program answers ALMOST READY. Try running it with other numbers (for example 520 and 300) to see the three different roads.

Exercises

  1. Write a program that asks for the pond water temperature (a decimal number) and prints “Too cold” if below 25, “Too hot” if above 32, and “Good temperature” otherwise. (The limits 25 and 32 are practice numbers.)
  2. Change 03_elif.py so the cow’s weight is asked through input(). Test with 520, 350, and 200.
  3. Make a program that asks for a plant’s age in days and prints the stage: “Seedling” (0–14), “Vegetative” (15–45), “Flowering” (46–70), or “Harvest” (over 70). These are made-up numbers for practice.
  4. Challenge: change 06_match_case.py so animal is asked through input(), and add one new kind of animal. What happens if the user types Cow with a capital C?

Chapter Summary

  • if / elif / else make a program pick a road. Only one road is carried out.
  • A colon follows the condition, and the content is indented (4 spaces). Indentation is part of Python’s grammar.
  • Python checks conditions from top to bottom; arrange them from the strictest.
  • and, or, not combine conditions.
  • match / case chooses by a single value; case _ catches the rest.
  • Check before dividing, so you don’t hit ZeroDivisionError.

Next, in Chapter 8: decisions can be made. Now we teach the program to repeat work: check every pond, add up the whole harvest, without writing the code dozens of times.