runtime
50 / 250
lesson 50 Fundamentals Integration · beginner

Build a small program from functions

A real program reads data, checks it, computes something and reports it. Giving each step its own function makes the program easy to test, change and read from the top down.

You'll be able to
  • Plan a program as steps: validate, compute, report
  • Write one function per step and connect them with return values
  • Keep the input data unchanged while producing a new result
The idea

Every program in this course so far has had the same skeleton, even when it wasn't written down: some data comes in, bad data is caught, something is computed, and a result goes out. Writing each of those steps as its own function makes the skeleton visible. The bottom of the program then reads like a plan, and each function can be checked on its own with a couple of inputs.

Run each example to see what it prints. Running examples doesn't count toward progress.

example-1.py · A gradebook in four steps
def valid_score(score):
    """Return True for a whole-number score from 0 to 100."""
    return score is not None and 0 <= score <= 100

def letter(score):
    """Return the letter grade for a valid score."""
    if score >= 90:
        return "A"
    if score >= 80:
        return "B"
    if score >= 70:
        return "C"
    if score >= 60:
        return "D"
    return "F"

def grade_all(scores):
    """Return (name, letter) for valid scores and the names with invalid ones."""
    graded = []
    invalid = []
    for name, score in scores:
        if valid_score(score):
            graded.append((name, letter(score)))
        else:
            invalid.append(name)
    return graded, invalid

def report(graded, invalid):
    for name, grade in graded:
        print(f"{name:<6}{grade}")
    if invalid:
        print("check:", invalid)

scores = [("Ana", 92), ("Ben", 58), ("Chen", 104), ("Dara", 71), ("Eli", None)]
graded, invalid = grade_all(scores)
report(graded, invalid)

The second program is a restock report. Its steps are: apply the day's sales to a copy of the stock (the original is the morning's record and must not change), find what has fallen below its reorder level, and work out how many packs to order. A while loop (see Loops & Iteration) rounds up to whole packs.

example-2.py · End-of-day restock report
def apply_sales(stock, sales):
    """Return a new stock dictionary after the sales; unknown products are ignored."""
    after = stock.copy()
    for product_id, units in sales:
        if product_id in after:
            after[product_id] = after[product_id] - units
    return after

def packs_needed(units, level, pack_size):
    """Return how many packs bring units back up to at least level."""
    packs = 0
    while units + packs * pack_size < level:
        packs = packs + 1
    return packs

stock = {"P0607": 30, "P0208": 8, "P0659": 12}
levels = {"P0607": 20, "P0208": 10, "P0659": 5}
sales = [("P0607", 14), ("P0208", 3), ("P0999", 1), ("P0659", 2)]
after = apply_sales(stock, sales)
for product_id, units in after.items():
    packs = packs_needed(units, levels[product_id], 6)
    if packs > 0:
        print(f"{product_id}: {units} left, order {packs} packs")
print(stock["P0607"], after["P0607"])

When to use it: for any program longer than a screen. Name the steps first, then write a function for each. Mistakes to avoid:

  • One function that validates, computes and prints at once: it can't be reused or checked.
  • Changing input data inside a step when the caller still needs the original: copy first.
  • Steps that communicate through outer names instead of parameters and return values.
Review
  • Plan the program as steps (validate, compute, report) and write one function per step.
  • Connect steps with parameters and return values; only the report prints.
  • Copy input data before changing it when the caller still needs the original.
  • Next module: string algorithms: cleaning, splitting, searching, counting and validating text.
Practise this

Loading your progress…

To master this lesson, solve both challenges without hints or the answer, and pass the concept check.

Build a small program from functions — Fundamentals Integration · Runtime