Functions Help Organize Code
Learning Objectives
- You can identify duplicated logic in a script.
- You can explain why duplication is a problem that grows over time.
- You can describe what a function does at the conceptual level, before learning the syntax.
Functions are a tool for solving problems that scripts run into as they grow. By the end of the chapter, you should be able to look at your study log program and say what is wrong with it — not “it does not work,” but “it is harder to read than it needs to be, and here is why”.
A Look Back at the Study Log
Here is a cleaned-up version of what your study log might have looked like at the end of the last part. Read it from top to bottom.
print("=== Study Log ===")print()
subjects = []minutes_list = []
while True: subject = input("Subject (or 'done' to finish): ").strip().lower() if subject == "done": break
minutes_text = input("For how many minutes? ").strip() minutes = int(minutes_text)
subjects.append(subject) minutes_list.append(minutes)
if minutes < 15: print(f" Short session on {subject} -- every bit counts.") elif minutes <= 90: print(f" Solid session on {subject}.") else: print(f" Long session on {subject} -- remember to take breaks!") print()
print("=== Summary ===")
if len(minutes_list) == 0: print("No sessions logged today.")else: total = 0 for m in minutes_list: total += m average = total / len(minutes_list)
longest = minutes_list[0] for m in minutes_list: if m > longest: longest = m
print(f"Sessions: {len(minutes_list)}") print(f"Total minutes: {total}") print(f"Average session: {average:.1f} minutes") print(f"Longest session: {longest} minutes")It works. It does what the project chapter asked for. But notice how many different jobs are happening in this one piece of code. Reading top to bottom, the program:
- Prints a header.
- Sets up two parallel lists.
- Runs an input loop until the user is done.
- Inside the loop, reads input, converts the minutes to a number, appends to the lists, and decides which response to print.
- Outside the loop, totals the minutes, computes the average, finds the longest session, and prints a summary.
That is at least five distinct jobs. They are all written into one continuous block, in a particular order that the reader has to follow. If you wanted to point at “the part of the program that finds the longest session,” you would have to point at about five specific lines inside a larger else-branch and explain that those lines are the relevant ones.
Spot the separate job
0 / 5 points
The study log script does several jobs in one long block. Which option names a useful boundary: one part of the script that has its own responsibility?
The Cost of Duplication
Suppose you decide that the same “short / solid / long” classification should also appear in the summary, after each session is listed. The natural way to do this without functions is to copy the if/elif/else from inside the loop and paste it into the summary section, like this:
for i in range(len(minutes_list)): m = minutes_list[i] s = subjects[i] if m < 15: label = "short" elif m <= 90: label = "solid" else: label = "long" print(f" {s}: {m} min ({label})")Now the classification rule lives in two places. If you ever decide to move the “long” threshold from 90 minutes to 120 minutes, you have to find and update both places. If you only find one, the two parts of the program disagree about what counts as a long session — and the program will produce inconsistent output. There is no error, no traceback, just quiet wrongness.
This is the cost of duplication. It is small the day you write the duplicate. It grows every time the program changes. The number of places where the same idea is written down is the number of places that have to stay in sync, forever, by hand.
Duplication and thresholds
0 / 5 points
The same short / solid / long classification rule is copied into two places. If the long-session threshold changes from 90 to 120 minutes, what should happen?
A common rule of thumb — the rule of three — is that if you have to copy and paste a piece of code more than twice, it is time to make a function. The first time you write the code, it is not duplication. The second time, it is still not duplication — it is a sign that the code is important enough to be repeated. The third time, it is duplication — you have written the same thing three times, and now you have three places to keep in sync.
The Cost of Tangle
Even without duplication, a long script is hard to read because the reader has to track many things at once. Look at the summary section of the study log. There are three different jobs squeezed into one block: totalling, averaging, and finding the longest. They share a list and a length, but they have nothing else to do with each other. Yet they sit side by side, with the names total, average, and longest all live at the same time.
total = 0for m in minutes_list: total += maverage = total / len(minutes_list)
longest = minutes_list[0]for m in minutes_list: if m > longest: longest = mThe reader has to hold all of them in mind to understand any one of them. If you want to know just “how is the longest session found?”, you have to scan past the totalling code to get to the loop you care about, and then scan past it again to read what happens after.
There is a classic programming problem called the rainfall problem, where students encounter the “tangle”. Computing education literature has shown that it can be challenging to novice programmers. Dividing the problem into parts using functions can make it much more approachable. For discussion on the broader topic of program composition, see e.g. break statement considered.
Functions give you boundaries. Inside the function, the relevant names are the only names that exist. Outside the function, only the function’s inputs and output matter. The reader can choose to look inside if they want to, or trust the name and move on if they do not. That trade-off — read the inside, or trust the outside — is what makes long programs readable.
Name the helper function
0 / 5 points
Suppose this code were moved into a helper function:
total = 0for amount in rainfall: total += amountaverage = total / len(rainfall)Which function-style label best describes what the code is responsible for?
What a Function Does, Conceptually
A function is a named piece of code that takes some inputs and produces an output. The rest of the program can use it without knowing how it works inside.
You have used functions already. For example,
input,int, and all the other built-in functions you have used.
The analogy that often helps is math. You have used functions in algebra without thinking of them as syntax. When you write square(5), you expect 25 back. You do not particularly care whether square is implemented as 5 * 5 or 5 ** 2 or by looking it up in a table. The name tells you what it does. The call gives you the value. The implementation is somewhere else, and most of the time, you do not have to look at it.
Programming functions work the same way. They have a name. They take some inputs (called arguments). They produce a value (called the return value). The code that uses the function gets to be short, because it talks in terms of names rather than implementations:
print(f"Total: {total_minutes(minutes_list)}")print(f"Longest: {longest_session(minutes_list)}")These two lines, once total_minutes and longest_session are defined, replace several lines of accumulator and track-the-best loops from the study log program. The loops still exist — they just live inside the functions, where the rest of the program does not have to look at them.
Function concept
0 / 5 points
What does a function name let the rest of the program do?
Functions have costs and benefits. A function adds a name to learn, parameters to remember, and an extra step of indirection between cause and effect. For a script that only does one thing once, in one place, a function is overhead.
This is why the course did not introduce functions until this part. The programs that we have written so far were often small enough that one continuous script was the right choice. The cost of organizing them into functions would have been larger than the benefit.
The judgment call — when is the code big enough to deserve functions? — is something you will get a feel for across the course. A useful default: if you find yourself about to copy and paste a block of code, that is a function. If you find yourself describing a piece of code with phrases like “and then this part does…” and “and then this other part does…”, those parts are functions.
Check Your Understanding
- Look at the study log code at the top of this chapter. Name three distinct jobs the program does, and roughly which lines correspond to each.
- Suppose the “long session” threshold should change from 90 minutes to 120 minutes. In the version with a duplicated classification, how many places would have to change? In a version with a function, how many?
- What do “name”, “input”, and “output” mean in the context of a function? Use the math analogy if it helps.
AI Study Aid
Create a chapter diagram
We're looking into to what extent AI-generated diagrams could help with studying.
Use this study aid to generate an AI-generated visual summary of the material you just studied.
Each diagram style emphasizes the content in a different way, so you can choose the focus
that feels most useful.
Using the diagram generator is voluntary and does not affect your course progress. We encourage
you to try it out and see if it helps, but it's totally up to you! Your answers help us understand
how to make better study aids in the future.