0%

Plan, Build, and Test Programs · practice

Read Code Before Changing It

You will often change code that you did not write today. It may come from another person, an earlier version of you, documentation, or a project started several lessons ago.

This lesson deliberately steps away from the quiz engine for one transfer. If the working only helps with code you already know, it is not much of a method yet. Here, you will meet a small ratings summary as if it arrived on your desk this morning.

Do not begin by rewriting it into your preferred style. First build a working model of what it does.

Read from the outside in

Begin at the edges, where the meets the rest of the program:

  • the function name and ;

  • the returned or visible output;

  • one small example call.

Once those pieces make sense, inspect the body. This order gives the details somewhere to land.

Consider:

def summarize_distances(distances):
    total = 0

    for distance in distances:
        total += distance

    return {
        "count": len(distances),
        "total": total,
    }

From the outside, the function receives a and returns a . The dictionary has two fields.

Inside, one accumulator visits each distance. You can trace [3, 5]:

Momenttotal
before 0
after 33
after 58

The returned dictionary is therefore {"count": 2, "total": 8}.

Confirm the current behavior

Run the code before editing it. Add one temporary call or assertion if needed.

This gives you a baseline:

assert summarize_distances([3, 5]) == {
    "count": 2,
    "total": 8,
}

If the baseline already fails, you are not starting from the behavior you thought you were.

Locate the smallest change

Suppose the new requirement adds an "average" field. Ask:

  • Which value is already available?

  • Which new calculation is needed?

  • What happens for an empty list?

  • Which existing fields must remain unchanged?

You may need only a few lines. A complete rewrite creates more behavior to recheck.

Preserve the old contract while extending it

Add checks for the new field, but keep checks for "count" and "total". A feature is not complete if it silently breaks behavior that callers already rely on.

Reading unfamiliar code is not a speed-reading contest. The goal is to make one accurate change with evidence.

Before changing an unfamiliar function, what is the best first step?

Task

Read the starter summarize_ratings(ratings) before changing it. It currently returns the count, total, and average for a non-empty .

Extend the contract:

  • add "highest" with the largest rating;

  • for an empty list, return count 0, total 0, average None, and highest None;

  • preserve all existing fields and behavior.

Do not replace the returned with printed text. Keep the prepared call and print.

The printed dictionary must contain these fields and values; field order may differ:

{'count': 4, 'total': 14, 'average': 3.5, 'highest': 5}