Week 5: Functions, Tuples, and Documentation
🎯 Objectives
Last week your programs learned to choose. This week they get taken apart.
Everything you have written so far has been one list of statements with a single path through it. A function is a piece of that list with a name on it, which runs only when something calls it, receives values when it is called, and hands a value back when it finishes. That one idea drags four more in behind it, which is why this is the densest week in the course: values going in as parameters, a value coming back with return, names that exist only inside the function that made them, and the tuple, which is how a function hands back more than one value at once.
None of it is hard to type. What takes the week is getting used to the fact that your program now has more than one place where things happen, and that a name means different things in different places.
By the end of the week you should be able to:
- Define and call functions with parameters, arguments, and return values, and trace how control passes from a call into a function and back again.
- Explain the difference between local and global scope, and say which names a function can see.
- Use a tuple to group a small, fixed set of values — an
(x, y)coordinate, or several values returned from one function — and unpack a returned tuple into separate variables. - Try a function out on sample inputs by putting your test code under an
if __name__ == "__main__"block. - Write a docstring for a function that names its arguments and what it returns, and read it back with
help().
Quiz 2 is next week, and it is not the kind of quiz you have taken
Quiz 2 is next Wednesday or Thursday depending on your section, 25 minutes, covering Weeks 4 and 5, with no AI.
It is on a computer. You will be given a problem you have not seen, and you will write, run, and submit a working program in 25 minutes. Quiz 1 asked you to read code; this one asks you to produce it, which fails in completely different ways — a typo that costs you four minutes, a function you started typing before you knew what it should return, a program that works on the one input you tried.
So the studying that counts this week happens at a keyboard, with a timer, and with your notes shut. Reading about functions is worth about twenty minutes. Writing them is worth the rest.
First, a five-minute self-check
Answer these before you look anything up, and no Shell. Nothing here is graded; the point is to find out which items on the menu below deserve your time.
- What is the difference between a parameter and an argument?
-
What does this print, and why?
-
In
result = biggest(a, b), which runs first: the call tobiggest, or the assignment toresult? - A function contains the line
count = 0. After the function ends, can the rest of the program seecount? - What are the type and the length of the value returned by
return "dog", 3? - Write the line that takes the value returned by
date_analysis(2, 12, 25)and puts its three parts into three separate variables. - Why is testing code put under
if __name__ == "__main__":rather than just written at the bottom of the file?
If 2, 4, and 5 were comfortable, go straight to the two keyboard activities near the end of the menu. If they were not, items 2 through 4 are what the first half of the menu is for.
📚 Study menu
Class covers three things this week: defining and calling functions with parameters and return values on Monday, scope and docstrings and the debugger on Wednesday, and tuples, multiple return values, and __main__ testing on Friday.
This is a menu, not an assignment. Nobody does all of it. But this week is the last one before a quiz that asks you to write a program from nothing, so at least one item you pick should be one where you are typing, not reading.
If you only have an hour
- Ten minutes. The self-check above, then the W3Schools Python Functions page.
- Fifteen minutes. The scope drill in the Shell, below. It is the shortest item here and it is where the hidden marks are.
- Twenty-five minutes. Write Ex5.2 or Ex5.3 from the practice page from scratch, timed, with no AI.
- Ten minutes. Take whatever you just wrote and check it against the three questions at the end of "Write the docstring first."
Read about it
All three books put functions in one chapter and tuples somewhere else, so every option below is two short runs rather than one. Pick whichever book you got on with last time; the third is a skim you can add to either of the others.
Python for Everybody — 5. Functions and 11. Tuples
- Sections 5.1 Function calls, then 5.6 through 5.11 in order: adding new functions, definitions and uses, flow of execution, parameters and arguments, fruitful and void functions, and why functions.
- 5.10 Fruitful functions and void functions is the one to read twice. It is the section that explains where
Nonecomes from. - Then 11.1 Tuples are Immutable, 11.2 Comparing Tuples, and 11.3 Tuple Assignment.
How to Think Like a Computer Scientist — 6. Functions and the tuple sections inside 10. Lists
- 6.1 Functions, 6.2 Functions that Return Values, 6.4 Variables and Parameters are Local, 6.6 Functions can Call Other Functions, 6.7 Flow of Execution Summary, 6.8 Using a Main Function, 6.9 Program Development, and 6.10 Composition.
- Then 10.27 Tuples and Mutability, 10.28 Tuple Assignment, and 10.29 Tuples as Return Values. Those three live inside the Lists chapter; go to them directly rather than reading the chapter.
- 6.8 is the closest any of the three books comes to explaining
if __name__ == "__main__", and 6.9 Program Development is the best advice in any of them about how to build a program with several functions in it, which is what Quiz 2 asks for. - This book's CodeLens boxes step through a call one line at a time and draw the frames, which is worth more on this week's material than on any week so far.
W3Schools — the reference-style skim
- Python Functions, plus its Python Arguments and Python Scope subpages.
- Python Tuples and its Unpack Tuples subpage.
Where to stop reading, and what the books leave out
Skip TCS 6.3, Unit Testing, and TCS 6.5, The Accumulator Pattern. The first needs assert and pytest, which arrive together in Week 8; the second needs loops, which is next week. Both are short and both will make more sense with the thing they depend on already in place.
Skip PY4E 5.2 through 5.5 — built-in functions, type conversion, math, and random. You did the first three in Week 2 and random is Week 9.
On W3Schools, stop after the Scope page. The subpages after it — *args/**kwargs, Decorators, Lambda, Recursion, Generators — are all real Python and none of them are in this course. The same warning applies to the tuple subpages after Unpack: Loop, Join, and Tuple Methods all want material you do not have yet.
None of the three books writes docstrings the way this course requires them. They use short one-liners or nothing at all, and the Google style with Args: and Returns: sections is what ruff grades you on. For that, the model is the example at the top of the practice page, not the books.
Trace a call, not a program
Until this week, tracing a program meant reading down the page. It does not any more: execution jumps into a function, runs its body, and comes back to the middle of the line that called it, carrying a value with it. Getting that jump-and-return wrong is the single biggest source of confusion in the next month, and the debugger makes it visible.
Take date_types.py or color_utils.py from this week's practice problems and pick one call.
On paper, write the line numbers in the order Python actually executes them, and every time you enter a function, indent.
Beside each parameter, write the value that arrived in it; beside each return, write the value going back and the line it goes back to.
Then run it in Thonny with Ctrl+F5, set a breakpoint on the call, and use Step into rather than Step over. Watch the new frame appear in the variables pane when you enter the function and disappear when it returns. That frame appearing and disappearing is local scope; everything else on this page about scope is a description of that picture.
Three things worth deliberately watching for:
- The line that calls a function is not finished when the call starts.
print(f"{kilometers_to_miles(5):.1f}")runs the function, gets a number back, and only then formats and prints it. - A function that ends without a
returnstill returns —None— and the caller gets it. - Two functions can both have a parameter called
valuewithout having anything to do with each other.
Find out where a name lives
This is the shortest item on the menu and the one most likely to show up on the quiz as a program that runs and does the wrong thing. Open the Shell, type each of these, and predict the result before you press Enter.
Three different outcomes: a NameError, an UnboundLocalError, and a program that works.
Write down, in one sentence each, the rule that separates them.
What you should be able to state without hesitating afterward:
- A name created inside a function belongs to that function and is gone when it ends.
- A function can read a name from the file it lives in, but assigning to that name inside the function creates a new, local one instead of changing the original.
- Which is why
count = count + 1inside a function fails before it does anything: the assignment madecountlocal, so the read on the right has nothing to read. - The way a function changes something for its caller is to
returna value and have the caller store it. That is the whole mechanism. - Two functions with the same parameter name are not sharing anything.
Write the docstring first
This sounds like a documentation chore and it is actually a design technique, which is why it is on the menu in a quiz week.
Pick any three problems — two from the practice page that you have not done yet, and one you make up.
For each one, write only the def line and the docstring, with the Args: and Returns: sections filled in and the body left empty.
Do not write the body at all yet.
Then look at what you wrote and answer three questions about each:
- Does the
Returns:line name one type, or did you find yourself writing "a number, orNoneif…"? The second is a sign the function is doing two jobs. - Are all the values the body will need in the parameter list? If the body is going to reach for something that is not there, you have found a bug before writing a line of code.
- Could somebody else write the body from your docstring alone, without asking you anything?
Now write the bodies, and notice how much of the thinking was already done. This is the habit that makes 25 minutes enough on Quiz 2: the minutes people lose are almost never spent typing.
Afterward, run ruff check on the file, and then help() on your own functions in the Shell to read back what you wrote.
Turn last week's programs into functions
You already have a folder of working programs that are written the old way, which makes them the cheapest practice material available.
Open Week04 and take pet_age.py, steel.py, and closer.py.
Each one reads input, decides something, and prints.
Split each into two parts: a function that takes the inputs as parameters and returns the answer without printing anything, and a main block that does the reading, calls the function, and does the printing.
The programs should behave exactly as they did before, which is the point — you can check yourself against last week's specs. What changes is that the decision is now in a piece you can test on twenty inputs from the Shell in a minute, without typing at a prompt twenty times.
Then do the thing that only becomes possible after the split: import your module in the Shell and hammer the function directly.
>>> from pet_age import pet_human_age
>>> pet_human_age("dog", 1)
>>> pet_human_age("cat", 1)
>>> pet_human_age("parrot", 4)
Separating "work out the answer" from "talk to the user" is the most valuable habit in this course, and this is the cheapest possible way to acquire it.
Rehearse Quiz 2 under the clock
Quiz 2 hands you a problem you have not seen and 25 minutes on a computer. The only honest rehearsal is to do exactly that, and to do it before Tuesday so there is time to act on what goes wrong.
Pick something you have not already solved — the two Extra Challenges at the bottom of the practice page are there for this, and Clock time is about the right size — and set a timer for 25 minutes.
Close your notes, close every AI tool, open nothing but Thonny.
Write it, test it under if __name__ == "__main__" on at least three inputs, and stop when the timer stops.
Then work out where the time actually went.
It is almost never the def line.
It is deciding what the function should return after starting to write it, or a ruff complaint found in the last two minutes, or ten minutes of debugging that turned out to be a missing return.
Those are all fixable and they are only visible under a clock.
Do at least one of these with somebody else if you can. Write a small function specification — a name, its parameters, what it returns — and trade with a classmate, then implement each other's. An ambiguous specification is obvious the moment somebody else has to work from it, and never obvious when you wrote it yourself. No one to trade with? Write two specifications today and implement one of them on Thursday, by which time you will have forgotten what you meant. Studying together is encouraged all semester; the quizzes and anything you submit for a grade are yours alone.
Try an AI tutor
Functions are where AI is most useful and most dangerous in the same breath. Useful, because it will explain scope patiently as many times as you need. Dangerous, because the most common bug this week — a function that computes a value and forgets to return it — is one an AI will silently fix while "explaining" your code, so you never find out that you make that mistake.
Three prompts that keep the work on your side of the table:
"Give me a program with two functions that call each other, about fifteen lines. Then give me an empty trace table with columns for line number, function, variable, and value, and do not fill it in. After I fill it in, check my table one row at a time and tell me only which rows are wrong, not why."
"Here is a function specification: [paste your def line and docstring]. Do not write the function. Instead give me five calls with the arguments and the return values you would expect, including the awkward cases, and say why each one is worth testing."
"Here is a function I wrote: [paste it]. Do not rewrite it, do not tell me whether it is correct, and do not fix anything. Tell me, in one sentence, what value it returns for the input [x], and then wait."
That third one is the antidote to the silent fix: it will not repair the missing return if you have told it to report rather than to help, and watching it say "it returns None" about code you thought was finished is worth more than being handed the corrected version.
The skepticism to carry this week is about scope. Ask an AI to fix a function that cannot update a global and there is a good chance it reaches for the global keyword, because that is the shortest answer and there is a lot of code on the internet that does it. It is not what this course wants, it is not what the quiz wants, and it is not what working programmers do. The answer is a parameter and a return.
✍️ Reflection
Instructions
Download the Week 5 reflection template, type your answers into it, and submit the completed document.
The first three questions are quick; the short answers are the ones that matter. Question 4 is the one to spend time on this week — Quiz 2 is in a few days, and it is the question that changes what you do between now and then. A few sentences each is plenty. Be specific and be honest.
1. What did you do this week? (Check all that apply.)
- Read the sections listed for one or more of the textbooks
- Traced a function call on paper, then stepped into it with Thonny's debugger
- Ran the scope drill in the Shell and wrote down the rules
- Wrote docstrings before bodies for three functions
- Rewrote one or more Week 4 programs as a function plus a main block
- Wrote a program from scratch under a timer, with no AI
- Traded a function specification with a classmate
- Asked an AI tutor to drill me, or to suggest test cases
- Something else (tell us in the short answers)
2. Roughly how much time did you spend on CS 149 outside of class this week?
- Under 1 hour
- 1–2 hours
- 3–4 hours
- 5–6 hours
- 7+ hours
3. Quiz 2 is next week, on a computer, with no AI. How ready do you feel to write a working program from a specification in 25 minutes?
- Ready — I have done it once already under a timer
- Probably fine, but I have not tried it timed
- I can follow along when I read code, but writing from nothing is hard
- Not ready, and I know which part is missing
- Not ready, and I am not sure what is missing
4. What did you change about the way you study after Quiz 1, and has it worked? Last week you named one thing that worked and one that did not. Say what you actually did differently this week, and whether it made a difference you can point to — a specific thing you can now do that you could not do on Monday. Then say what you will do in the two days before Quiz 2, keeping in mind that this one asks you to produce a working program rather than to read one.
5. Give one function this week that did not do what you expected. Write what you expected, what actually happened, and the rule you were using that turned out to be wrong — about scope, about return, about tuples, or about where a call goes next. The wrong rule is the useful part. Then say which of this week's objectives feels shakiest and what you plan to do about it before the quiz.
6. What is one thing you want gone over in class? Be as specific as you can: "why count = count + 1 fails inside a function" is useful, and "functions" is not. Answer this even if you feel confident, by naming the thing you would least like to be handed on Quiz 2. Class time gets spent on whatever shows up most often in these answers.
7. Did you use an AI tool this week, and did it build your understanding or replace it? The honest test for this week is concrete: with no notes and nothing open but Thonny, could you write a module with two functions, one of which calls the other, and a working main block in 25 minutes? If a video, article, or tutorial made something click, drop the link and one line on why it helped; we collect these to improve the study menu for future students.
8. Paste one or two programs you wrote outside of class this week. Pick the ones with the most functions in them, and include the docstrings — they are part of the program now.