Designing Focused Functions
Introduction: One Job, Many Steps
Welcome back to Writing Complex Python Functions! We have arrived at the fifth unit, and the pieces we collected along the way are about to come together. So far, each function has done one small thing: branched, accumulated, filtered, or copied. Real work rarely arrives in such neat portions. A single request such as "summarize these prices" quietly contains validation, filtering, a loop, and several running totals at once.
Our program for this unit ships with one function, summarize_prices(prices, min_price=0), and two calls that print:
That function's body runs about eighteen lines, which instinctively feels like "too long." So here is the question that guides the whole unit: How do we tell a legitimately long function from one that should be split? The answer is not line count; it is the number of jobs.
The Four Regions of a Long Function Body
Let us meet the shipped function in full, then immediately stop reading it as eighteen unrelated lines.
Read from top to bottom, the body splits into exactly four regions: the docstring contract, the accumulator initializations, the loop body (skip plus updates), and the single post-loop return. Ask what the function does, and the answer is one sentence: It summarizes a list of prices. One job, four regions, many lines.
This shape is a reusable template. Any "walk a list and report on it" function can be poured into it, and keeping the regions in this same order is what makes a long body skimmable for the next person who opens the file.

