Classroom Glossary Public page

Week 2: Control Flow

1,395 words

Programs that decide. You learn if, while, for, and loop control (break, continue). The lab is a guess-the-number game that loops until the player wins or runs out of tries.


Theme

A program with no control flow runs every line, top to bottom, once, and exits. That is fine for the temperature converter you wrote in week 1. Most useful programs do something more interesting: they repeat actions, they make decisions based on input, they stop early when a condition is met. Control flow is the syntax that lets a program do those three things.

This week the syntax is: if, elif, else, while, for, break, continue. That is the entire vocabulary of control flow in Python. There is no switch statement; there is no do-while. The minimalism is deliberate; Python's design philosophy (write import this in the REPL for the full Zen of Python) prefers a small set of constructs that compose cleanly over a large set of specialized ones.

The week's lab is a guess-the-number game. You pick a random number between 1 and 100; the player guesses; you say "too high," "too low," or "right." The player has a bounded number of tries. The game ends when the player wins or runs out. That is if + while + break in one tool.

By the end of week 2 you can: write any combination of if/elif/else, use while for "keep going until," use for for "iterate over a sequence," recognize when an infinite loop has happened (and how to interrupt it with Ctrl-C), and use break / continue for the small minority of cases where they are clearer than a restructured loop.

Reading list (~1 hour)

  1. Matthes, Python Crash Course 2nd ed., Ch 5 ("If Statements") and Ch 7 ("User Input and While Loops"). Matthes' Ch 7 has the canonical "while loop with a sentinel value" example; FND-102's Lab 2 is structurally similar.
  2. Sweigart, Automate the Boring Stuff with Python 2nd ed., Ch 2 ("Flow Control") at https://automatetheboringstuff.com/2e/chapter2/. Free online. Sweigart's truthiness rules and his explanation of Boolean operators (and, or, not) are the clearest in the genre.
  3. Allen B. Downey, Think Python 2nd ed., Ch 5 ("Conditionals and Recursion") at https://greenteapress.com/thinkpython2/html/thinkpython2006.html and Ch 7 ("Iteration") at https://greenteapress.com/thinkpython2/html/thinkpython2008.html. Downey's distinction between "definite iteration" (for) and "indefinite iteration" (while) is the framing FND-102 borrows.

Lecture outline (~1.5 hours, 2 sessions of ~50 min)

Session 1: Conditions and decisions

Section 1.1: Boolean expressions

  • An expression that evaluates to True or False is a Boolean expression.
  • Comparison operators: == (equal), != (not equal), <, >, <=, >=. All return a bool.
  • == vs =: x = 5 assigns; x == 5 compares. The single equals sign is a syntax error in a condition (Python catches it at parse time, unlike C).
  • Boolean operators: and, or, not. Lowercase. Short-circuit evaluation: False and anything does not evaluate anything; True or anything does not either. Useful when anything would raise an error: if x is not None and x > 0: is safe.
  • Truthiness: every value in Python has a Boolean interpretation. 0, 0.0, '' (empty string), [] (empty list), {} (empty dict), None, and False are all "falsy." Everything else is "truthy." This means if my_list: is a clean way to check "is the list non-empty" without writing if len(my_list) > 0:.

Section 1.2: if, elif, else

  • The basic form:
    if condition:
        do_thing()
    
  • Indentation matters. Python uses indentation as syntax; the convention is 4 spaces per level. The lecture session-1 demo will spend 5 minutes on IndentationError because every student will hit it.
  • else runs when if's condition is False:
    if x > 0:
        print('positive')
    else:
        print('non-positive')
    
  • elif chains multiple conditions (only one branch runs):
    if x > 0:
        print('positive')
    elif x < 0:
        print('negative')
    else:
        print('zero')
    
  • elif is short for "else if." Most languages have this; some (Bash) spell it elif, some (C) write else if, some (Pascal) write else if. Python's elif is the same idea.
  • Nested if inside if is legal but usually a sign the logic should be flattened. Prefer and / or for compound conditions.

Section 1.3: The match statement (Python 3.10+)

  • Python added structural pattern matching in 3.10. It looks like switch in other languages but does more.
  • Basic form:
    match command:
        case 'start':
            start_engine()
        case 'stop':
            stop_engine()
        case _:
            print(f'unknown command: {command}')
    
  • FND-102 uses if/elif/else as the default; match is forward-stretch (mention in lecture, do not require in lab). When you need it, Real Python has a clean intro at https://realpython.com/structural-pattern-matching/.

Session 2: Loops

Section 2.1: while loops

  • "Keep doing this until the condition is False":
    count = 0
    while count < 10:
        print(count)
        count += 1
    
  • The += operator is "augmented assignment": count += 1 is short for count = count + 1. Also works with -=, *=, /=, etc.
  • The loop body is responsible for changing the condition. If you forget the count += 1, the loop runs forever.
  • Infinite loops are a fact of life. Ctrl-C interrupts a running Python program with KeyboardInterrupt. You will use it dozens of times this course.
  • while True: is a legitimate idiom for "loop forever (until something inside calls break)." Used in event loops, REPLs, and games.

Section 2.2: for loops

  • "Do this for each item in a sequence":
    for fruit in ['apple', 'banana', 'cherry']:
        print(fruit)
    
  • for walks any iterable: a list, a string (yields one character at a time), a range, a file, a dictionary (yields keys).
  • The range() function is the canonical "do something N times":
    for i in range(10):
        print(i)  # prints 0, 1, 2, ..., 9
    
  • range(start, stop) is half-open: range(1, 11) yields 1 through 10 (the stop value is excluded). This is consistent with Python's slice convention; you will see it again in week 4.
  • range(start, stop, step) lets you skip: range(0, 100, 10) yields 0, 10, 20, ..., 90.
  • "Should I use while or for?" Rule of thumb: if you know the number of iterations (or are walking a collection), use for. If you are looping until a condition becomes True, use while.

Section 2.3: Loop control (break, continue)

  • break exits the current loop immediately:
    for n in range(100):
        if found(n):
            break
    
  • continue skips to the next iteration of the current loop:
    for n in range(100):
        if n % 2 == 0:
            continue  # skip even numbers
        print(n)
    
  • Both break and continue apply to the innermost enclosing loop. They do not break out of nested loops. (Python has no labeled-break; you typically refactor into a function and return instead.)
  • Use sparingly. A loop with break is sometimes clearer than the equivalent while not done: rewrite; sometimes it is not. Pick the form that reads more clearly.

Section 2.4: The random module

  • The standard library's random module is your week-2 friend. Quick tour:
    import random
    random.randint(1, 100)        # random int between 1 and 100 inclusive
    random.choice(['a', 'b', 'c']) # pick one element
    random.shuffle(my_list)         # shuffle in-place
    
  • For Lab 2 you will use random.randint(1, 100) to pick the target number.
  • Cryptographic random is a different module (secrets); for games and tests, random is fine.

Labs (~90 minutes)

Lab 2: Guess-the-Number Game (labs/lab-2-guess-the-number.md)

  • Goal: build a CLI game where the player guesses a number 1-100; the program responds with "too high," "too low," or "correct"; the player has a bounded number of tries
  • Time: ~90 minutes
  • Artifact: lab-2-guess.py in ~/fnd-102/lab-2/, committed to Git

Independent practice (~4 hours)

  1. FizzBuzz (30 min). The interview classic. For numbers 1 to 100: print "Fizz" if divisible by 3, "Buzz" if divisible by 5, "FizzBuzz" if divisible by both, the number otherwise. Write it in 10 lines or fewer. (If you have done this before, time yourself; should take <5 minutes.)

  2. Truthiness drills (30 min). In the REPL, predict and verify:

    bool(0), bool(0.0), bool(''), bool([]), bool({}), bool(None), bool(False)
    bool(1), bool(0.1), bool('hello'), bool([0]), bool({'a': 1})
    

    What pattern do you see? Why are these the rules?

  3. A nested loop (45 min). Write a program that prints a 10x10 multiplication table. Use two nested for loops. Format the output so the columns line up (f-string with width specifier: f'{n:4d}' right-aligns n in a 4-character field).

  4. Loop control practice (30 min). Modify your FizzBuzz: use continue to skip multiples of 7. So the output should print FizzBuzz / Fizz / Buzz / numbers normally, except numbers divisible by 7 should be skipped entirely (the line is not printed).

  5. Lab 2 polish (90 min). After completing the base Lab 2: add a "would you like to play again?" prompt after a win or loss. Use a while True: with a break on 'n'. This is forward-pointer to the loop idioms you will use in week 9.

  6. Optional stretch (60 min). Write a number-guessing game where the COMPUTER guesses YOUR number. You think of a number 1-100; the computer asks "is it greater than 50?" You answer y / n; the computer narrows in. This is binary search; the computer should win in 7 guesses or fewer.

Reflection prompts (~30 minutes)

  1. You learned while and for. For your Lab 2 (guess-the-number), why is while the right choice? Could you have used for instead? What would have changed?
  2. Python uses indentation as syntax. Most other languages use braces ({ }). Which do you prefer for readability? Did the indentation rule cause you any errors this week?
  3. if my_list: (truthiness check) vs if len(my_list) > 0: (explicit comparison). Both work. Which would you write? Why?
  4. break and continue are sometimes called "non-structured" control flow because they make a loop harder to reason about. Were either of them genuinely necessary in your Lab 2? Could you have rewritten the loop without them?
  5. One thing from this week you want to know more about?

Tool journal (week 2)

  • if, elif, else: decision-making
  • while, for: looping
  • break, continue: loop control
  • range(): generate sequences of integers
  • random module: randint, choice, shuffle
  • Ctrl-C: interrupt a running Python program (survival skill)
  • +=, -=, *=, /=: augmented assignment

What comes next

Week 3 introduces functions. Your Lab 2 guess-the-number game is probably one long script with all the game logic inline; week 3's lab asks you to refactor it into named functions with docstrings. Functions are the first tool you have for organizing code so it stays readable as it grows.