Ms. Roy’s practice check-in came back for a second round. She wanted the week’s total, the longest single session, and the number of days off — and she wanted the totals in hours and minutes, not decimals, because “3.1 hours” means nothing when you are planning a Tuesday. The first draft had the hours-and-minutes arithmetic written out three times. This one has it written once.
The program
# Practice-week summary for Ms. Roy, who plans next week from last
# week's minutes. Three small functions, each with one job.
def total_minutes(sessions):
total = 0
for minutes in sessions:
total = total + minutes
return total
def longest_session(sessions):
longest = sessions[0]
for minutes in sessions:
if minutes > longest:
longest = minutes
return longest
def as_hours_and_minutes(minutes):
hours = minutes // 60
rest = minutes % 60
return f"{hours} h {rest} min"
week = [45, 0, 60, 30, 0, 90, 25]
print("Last week's practice")
print(f"Total: {as_hours_and_minutes(total_minutes(week))}")
print(f"Longest: {as_hours_and_minutes(longest_session(week))}")
print(f"Days off: {week.count(0)}")Last week's practice
Total: 4 h 10 min
Longest: 1 h 30 min
Days off: 2
How it works
Nothing runs when Python reads a def — it only remembers the
definition. The program really begins at week = [...], and the three
print lines are the whole of it. That is the shape to aim for: a main
part short enough to read aloud, standing on functions with honest
names.
Each function takes what it needs as a parameter and hands back an
answer with return. None of them prints anything, which is what lets
them be combined:
as_hours_and_minutes(total_minutes(week)) works because the inner
call is finished and replaced by 250 before the outer call begins.
as_hours_and_minutes is the one that earns its keep. // gives whole
hours, % gives the leftover minutes, and this awkward little pair of
lines now exists in exactly one place. When Ms. Roy asks for 4h10
instead, you edit one function and every line of output changes.
week.count(0) is a reminder that you are not obliged to write
everything yourself — count is a method that lists already have, like
len, max, and abs. Reaching for the tool that exists is a skill,
not a shortcut.1
Change it
- One line. Change
as_hours_and_minutesto returnf"{hours}h{rest:02d}", and the total prints as4h10. The:02dpads the minutes to two digits, so five past four is4h05rather than4h5. - A few lines. Write a fourth function,
days_practised(sessions), that counts the sessions above zero and returns the count —5for this week. Then use it instead ofweek.count(0)and say “Days practised” in the output, which is the sentence a coach would rather read. - A real change. Add
last_week = [30, 30, 60, 0, 45, 60, 0]and print a summary for both weeks by calling the same three functions again with the other list. Nothing inside any function changes — that is what “reusable” means, and it is the reason Decomposition and Design treats functions as the unit you design in.
The ideas behind this page are in Functions and Parameters, Returns, and Scope; the reps are in Functions Practice.
Curriculum connection
A3.1
demonstrate the ability to use existing subprograms (e.g., random number generator, substring, absolute value) within computer programs;
Link to original
A3.2
write subprograms (e.g., functions, procedures) that use parameter passing and appropriate variable scope (e.g., local, global), to perform tasks within programs.
Link to original
B2.3
apply the principle of modularity to design reusable code (e.g., subprograms, classes) in computer programs;
Link to original
Footnotes
-
Every one of these functions is a subprogram in the curriculum’s vocabulary, whether you wrote it or Python did. The only difference is who maintains it. ↩