Chapter 3

Making Decisions

Every script so far has run the same lines every time, top to bottom. Real scripts branch: do one thing if something's true, another thing otherwise. This chapter is if, the tool that lets a script choose.

Booleans and comparisons

A boolean is a value that's either True or False, nothing else. Comparison operators produce one:

amount = 32.10
print(amount > 20)
print(amount == 20)
print(amount != 20)
Output
True
False
True

>, <, >=, <= compare size. == checks equality; note the double equals sign, since a single = is assignment, a completely different thing. != means "not equal."

amount = 8.75
print(0 < amount < 20)
Output
True

That's a chained comparison: Python reads it as "is amount greater than 0 and less than 20," which is exactly what it looks like.

and, or, and not combine or invert conditions:

category = "coffee"
amount = 4.50
print(category == "coffee" and amount < 10)
print(category == "coffee" or amount > 100)
print(not (amount > 100))
Output
True
True
True

and needs both sides true. or needs at least one. not flips a boolean.

if

An if statement runs a block of code only when its condition is True:

amount = 32.10

if amount > 20:
    print("That's a big expense.")
Output
That's a big expense.

Two things to notice. The line ends with a colon, :. And the line under it is indented, pushed in from the left margin. That indentation is not decoration, it's how Python knows which lines belong to the if. A block is a group of indented lines that all belong together, and this is the first of several places you'll meet the idea.

amount = 4.50

if amount > 20:
    print("That's a big expense.")

print("Done checking.")
Output
Done checking.

amount isn't over 20 this time, so the indented line never runs, and the script continues with whatever comes after the block, back at the original indentation level.

IndentationError

Python is strict about this. Mixing indentation or forgetting it entirely gives you an error, not a guess at what you meant:

amount = 32.10

if amount > 20:
print("That's a big expense.")

That's IndentationError: expected an indented block after 'if' statement on line 3. The fix is exactly what it says: indent the line under the if. This book indents with four spaces throughout, which is the common Python convention; any consistent amount works, as long as every line in the same block lines up and you don't mix tabs and spaces in one file. This error looks alarming the first time you see it and it's one of the easiest to fix once you know what it's telling you: look at the line number, add or align the indentation, run it again.

Try it

Write an if with the indented line missing entirely and run it, so you recognize this error the first time it happens for real.

elif and else

elif (short for "else if") checks another condition when the first one is false, and else catches everything else:

amount = 12.00

if amount > 20:
    print("That's a big expense.")
elif amount > 5:
    print("That's a normal expense.")
else:
    print("That's a small one.")
Output
That's a normal expense.

Python checks each condition in order and runs the first block that matches, then skips the rest. You can chain as many elifs as you need, and else is optional, but when you include it, it always comes last.

category = "coffee"

if category == "groceries":
    print("Food for the week.")
elif category == "coffee":
    print("A small treat.")
elif category == "transit":
    print("Getting around.")
else:
    print("Something else.")
Output
A small treat.

Truthy and falsy values

if doesn't strictly need a boolean. It accepts any value and asks whether Python considers it "truthy" or "falsy." Most values are truthy; a specific short list counts as falsy: 0, 0.0, "" (an empty string), [] (an empty list, Chapter 5), {} (an empty dict, Chapter 6), and None.

note = ""

if note:
    print(f"Note: {note}")
else:
    print("No note.")
Output
No note.
note = "flat white"

if note:
    print(f"Note: {note}")
else:
    print("No note.")
Output
Note: flat white

if note: reads naturally as "if there's a note," and it works whether note is a string, a list, or a number, without writing out note != "" explicitly. You'll see this idiom constantly in real Python code, including later in this book, and it's worth being able to read on sight even before Chapter 5 and Chapter 6 introduce the empty-list and empty-dict cases directly.

A one-line if, for a simple choice

When an if/else only ever picks between two values to assign or print, Python has a compact form, a conditional expression, that fits on one line:

amount = 32.10
label = "big expense" if amount > 20 else "normal expense"
print(label)
Output
big expense

Read it in order: the value if true, the condition, the value if false. It's the same logic as a full if/else with two branches, each just one value, and it's worth reaching for only when both sides genuinely are one short value; anything longer is clearer as a regular if.

Practice

Try each of these before you read the solution under it.

  1. Given amount = 45.00, print "over budget" if it's greater than 40, otherwise print "within budget".
  2. Given category = "transit" and amount = 12.00, print True only if the category is "transit" and the amount is at most 15.
  3. Given amount = 8.75, use if/elif/else to print "small" for 5 or under, "medium" for over 5 up to 20, and "large" for anything above that.
  4. Given note = " " (just spaces), decide whether if note: would treat it as truthy or falsy, then check by running it. If the result surprises you, .strip() it first and try again.

Solutions

1.

amount = 45.00

if amount > 40:
    print("over budget")
else:
    print("within budget")
Output
over budget

2. Both conditions have to hold, so and is the right tool.

category = "transit"
amount = 12.00

print(category == "transit" and amount <= 15)
Output
True

3. Each elif only runs if every condition above it was false, so amount <= 5 doesn't need repeating in the "medium" branch.

amount = 8.75

if amount <= 5:
    print("small")
elif amount <= 20:
    print("medium")
else:
    print("large")
Output
medium

4. A string of just spaces is not empty, so it's truthy, which is easy to miss if you only think of "empty" as "looks empty."

note = "  "
print(bool(note))
print(bool(note.strip()))
Output
True
False

bool() converts a value to its truthy/falsy boolean directly, useful for checking without an if. note.strip() turns the spaces-only string into a genuinely empty one, "", which is falsy.

Where this leaves you

You can compare values, combine conditions with and/or/not, and branch a script with if/elif/else. You've also met indentation properly and seen what it looks like when it's missing. Chapter 4 uses that same block idea to repeat work instead of choosing between paths.