Saltar a contenido

03 - Decisions and Loops

What this session is

About an hour. You'll learn how to make your program decide between options (with if) and how to make it repeat something (with for and while). These two things are the building blocks of every program that does anything more than print a fixed message.

This page is also where you meet Python's defining feature: indentation matters. We'll come back to that.

Decisions with if

The world's smallest decision:

age = 18
if age >= 18:
    print("adult")
else:
    print("minor")

Run it. You'll see adult.

Now change age = 18 to age = 15 and run again. You'll see minor.

What's happening:

  • if age >= 18: - the colon ends the condition line.
  • The indented block that follows runs only when the condition is true.
  • else: - the indented block under it runs when the condition was false.

Notice: no curly braces, no end if. The indentation IS the block. The colon at the end of if/else is required.

Indentation is the syntax

This is the thing other-language programmers find weirdest about Python. There's no way around it: indentation defines structure.

A typical convention is 4 spaces per level. Most editors do this when you press Tab. Stick to 4 spaces; mix tabs and spaces and Python will (rightly) complain.

if x > 0:
    print("positive")
    print("still inside the if")
print("outside the if")

The two print calls under if are inside its block (4 spaces in). The third is outside (no indentation). Run it with x = 5 and x = -1 to see the difference.

You'll meet indentation everywhere from now on. After 30 minutes of writing Python, it'll feel natural.

Comparison operators

The operators that produce True/False:

Operator Meaning
== equal to
!= not equal to
< less than
<= less than or equal to
> greater than
>= greater than or equal to

A common mistake: writing = (one equals sign) when you mean == (two). = is assignment; == is comparison. Python catches the error immediately in if blocks - you can't write if x = 5: because it isn't valid syntax.

Chaining decisions with elif

Python uses elif (short for "else if"):

score = 75
if score >= 90:
    print("A")
elif score >= 80:
    print("B")
elif score >= 70:
    print("C")
else:
    print("F")

Reads top to bottom. First condition that's true wins; everything else is skipped. If none match, the else block runs.

Combining conditions: and, or, not

Python spells these as words, not symbols:

Operator Meaning Example
and both true age >= 18 and has_license
or at least one true is_weekend or is_holiday
not flip true/false not is_ready
age = 25
has_license = True
if age >= 18 and has_license:
    print("can drive")

(Other languages use &&, ||, !. Python's word form is more readable.)

Truthy and falsy values

A useful Python quirk: many values can be tested directly with if, without an explicit comparison.

name = ""
if name:                    # treated as False when empty
    print(f"hello, {name}")
else:
    print("name is empty")

These count as falsy: - False - None (Python's "nothing" value) - 0, 0.0 - "" (empty string) - [] (empty list), {} (empty dict), () (empty tuple), set() (empty set)

Everything else is truthy. So if my_list: is the idiomatic way to say "if my_list has any items." if name: means "if name is non-empty." You'll see this everywhere in Python code.

Repetition: for (over things)

Python's for loop is for iterating over a collection:

fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

Output:

apple
banana
cherry

fruit is the loop variable - each time through, it takes the next value from fruits. We'll meet lists properly in page 06; for now, recognize [ ... ] as a list.

To iterate a fixed number of times, use range:

for i in range(5):
    print(i)

Output: 0, 1, 2, 3, 4. (range(5) produces 0, 1, 2, 3, 4 - five numbers starting at 0.)

You can also specify start and stop:

for i in range(1, 6):    # 1, 2, 3, 4, 5
    print(i)

for i in range(0, 10, 2):  # 0, 2, 4, 6, 8 (step of 2)
    print(i)

Repetition: while (until)

while loops keep going while a condition stays true:

n = 10
while n > 0:
    print(n)
    n = n - 1

This prints 10, 9, 8, ..., 1. The body has to do something that changes the condition, otherwise the loop runs forever. (Forever loops are sometimes useful - for waiting on events - and you exit them with break.)

Breaking out: break and continue

break stops the loop entirely. continue skips to the next iteration.

for i in range(1, 11):
    if i == 5:
        break          # stop the whole loop when i is 5
    if i % 2 == 0:
        continue       # skip the print for even numbers
    print(i)

Output: 1, 3. Why?

  • i=1: not 5, not even → print 1.
  • i=2: not 5, even → continue (skip print).
  • i=3: not 5, not even → print 3.
  • i=4: even → skip.
  • i=5: break → stop entirely.

Putting it together

A program that classifies numbers 1 to 10:

for i in range(1, 11):
    if i % 2 == 0:
        print(i, "even")
    else:
        print(i, "odd")

Type and run. Read the output. Read the code. Look at each line and ask: which line produced this output?

Exercise

In a new file called classify.py:

Write the classic FizzBuzz. For each number from 1 to 20:

  • If divisible by 3, print Fizz instead of the number.
  • If divisible by 5, print Buzz instead.
  • If divisible by both 3 and 5, print FizzBuzz.
  • Otherwise print the number.

Hint: check the "both 3 and 5" case first. Why? Think about what would happen if you checked "divisible by 3" first.

Expected output starts:

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
...

Don't move on until your program prints exactly the right thing.

What you might wonder

"Why no parentheses around the condition?" Python's grammar doesn't need them. if (age >= 18): works (the parens are just grouping) but feels noisy. The convention is no parens unless you need them for grouping a complex expression.

"Why and/or/not instead of &&/||/!?" Python's design favors readability. Symbols save keystrokes; words read aloud better. Python has &, |, ~ too - but those are bitwise operators (for working with binary numbers), not logical operators. Don't mix them up.

"What's None?" Python's "no value" - like null in other languages. Used to signal "this variable hasn't been set" or "this function had no result to return." We'll meet it again in pages 04 and 07.

"What about switch/case statements?" Python didn't have them for decades. As of 3.10, there's match/case (called "structural pattern matching"). For beginners, if/elif/else chains do the same job and are clearer. We'll see match if it comes up in real code.

Done

You can now: - Make a program take different actions based on conditions (if, elif, else). - Combine conditions with and, or, not. - Recognize truthy and falsy values (if my_list: idiom). - Iterate a collection with for x in things:. - Iterate a fixed number of times with for i in range(...). - Repeat until a condition fails with while. - Exit a loop early with break, skip an iteration with continue. - Read and respect Python's indentation rules.

You now have the basic shapes that every program is built from. The next page is the abstraction that lets your programs stay short as they get bigger: functions.

Next: Functions →

Comments