Small functions with one job
A long function usually does several jobs in a row: it parses input, checks it, computes something and formats the result. To change one job you have to read all of them, and you cannot test them apart.
Split it so that each function does one job and is named after it. The top function then reads as a summary of the steps.
def parse_prices(text):
parts = text.split(",")
return [float(part) for part in parts]
def format_money(amount):
return f"${amount:.2f}"
def receipt(text):
total = sum(parse_prices(text))
return format_money(total)
print(receipt("1.5, 2.25,3"))Signs a function wants splitting
- comments that announce sections, such as
# parseor# totals - blank lines between paragraphs of code
- a name with "and" in it, or no good name at all
- a loop that builds a value only the next block uses
Your task
Split report(text) into parse_scores(text), returning (name, score) pairs with int scores and blank lines skipped, average(scores), and best_student(scores), returning the first pair with the highest score. report must call all three and return exactly the same text as before.
The explanation opens here once every check passes.