Recap and Feedback
In this part, you learned to give pieces of behavior names, pass information into functions, return results, reason about local state, validate user input, and test calculation logic independently from the rest of a program.
The central design questions are now:
What is this function responsible for? What information does it need? What should it return or change? How can I check that behavior?
The Dice Combos example added one more question:
Can a larger rule use the result of a smaller function?
Putting the Ideas Together: Reading Tracker
The final programming exercise combines the ideas from this part in a small reading tracker. Read its handout for the function contracts, accepted input, and required output.
The program separates its work into three layers:
read_sessions() ↓ sessionscalculation functions ↓ returned resultsprint_summary(...)main() connects these steps. The input function asks for session lengths and handles invalid input. The calculation functions receive the collected list, return their results, and leave the list unchanged. The presentation function displays the summary. You can test the calculations separately by calling them with lists you choose.
Suggested Workflow
Build and check one layer at a time:
- Read every function contract and identify its parameters, return value or output, empty case, and allowed effects.
- Implement the calculation functions first. Test ordinary, boundary, one-item, and empty cases, and check that the input list remains unchanged.
- Implement and check the presentation function using known result values.
- Implement the input function. Keep sentinel recognition, integer conversion, and positive-number validation as separate decisions, and test recovery from several invalid attempts.
- Connect the functions in
main()only after the individual responsibilities work. - Run complete examples, including stopping immediately and entering invalid input before valid input.
This order makes a failure easier to locate: first establish that each part satisfies its contract, and only then test the connections among the parts.
Reading tracker
0 / 40 points
Complete a reading tracker whose input, calculations, and presentation are divided into functions.
Implement the five functions and the coordinating main() function in the starter. Keep the provided import guard so that the calculation functions can be imported for testing without starting the interactive program.
read_sessions() takes no arguments. Use while True for the input process because the number of attempts is not known in advance. Repeatedly ask with the prompt Minutes, or done: . Ignore surrounding whitespace. Any capitalization of done, such as DONE or Done, stops input before conversion and is not stored; use break for this sentinel. Otherwise, use int(...) to convert the text and accept only integers greater than zero.
Keep the try block focused on integer conversion and check whether the converted value is positive separately. This makes it clear which operation may fail and which values the program accepts.
If conversion raises ValueError, or if the integer is zero or negative, print exactly:
Please enter a positive integer or done.After either kind of invalid response, ask again without storing it. You can use continue to begin the next attempt. Return a list containing only the accepted positive integers. Catch ValueError specifically so that unrelated errors are not treated as invalid input.
The calculation functions must return their results, print nothing, and leave sessions unchanged:
total_minutes(sessions)returns the total, or0for an empty list.longest_session(sessions)returns the largest value, or0for an empty list.count_long_sessions(sessions, minimum_minutes)returns how many values are greater than or equal to the supplied boundary, or0for an empty list. Use the parameter rather than hard-coding30inside this function.
print_summary(session_count, total, longest, long_count) prints exactly four lines. For a nonempty session list, the format is:
Sessions: 3Total minutes: 80Longest session: 45Long sessions: 1If session_count is 0, print Longest session: none on the third line. The other empty results are numeric zero.
Finally, main() must call read_sessions, calculate all three results with the calculation functions, use 30 as the long-session boundary, and pass the session count and results to print_summary.
For example, the responses 20, 45, 15, and done produce the four-line nonempty summary above. Entering done immediately produces:
Sessions: 0Total minutes: 0Longest session: noneLong sessions: 0Test immediate stopping, sentinel capitalization and whitespace, invalid text followed by valid input, zero and negative input, a one-item list, a session exactly at 30 minutes, an empty list, and a longest value that is not first.
Explain the Design
When the program works, step back from its individual lines and explain why its responsibilities are separated. The following exercise asks you to connect specific input, calculation, testing, and empty-case decisions to the program’s behavior. Being able to explain those choices is part of being able to maintain the program.
Review the reading tracker design
0 / 10 points
A reading tracker has these function contracts:
read_sessions()asks for session lengths in minutes until the user entersdone, ignoring surrounding whitespace and capitalization in that command. It converts other entries withint, accepts only positive integers, and returns them in a list. Invalid entries produce a message and another attempt.total_minutes(sessions)returns the total, or0for an empty list.longest_session(sessions)returns the largest value, or0for an empty list.count_long_sessions(sessions, minimum_minutes)counts values greater than or equal to the supplied minimum, returning0for an empty list.print_summary(session_count, total, longest, long_count)displays the four supplied results. When the session count is zero, it displaysnonefor the longest session and numeric zeros for the other results.main()connects these functions, using30as the long-session minimum.
The calculation functions receive lists of positive integers, print nothing, and leave the lists unchanged.
In a response of about five to seven sentences, explain why these responsibilities are separated. Include all of the following:
- why
donemust be recognized before attemptingint(text); - what happens after invalid text, zero, or a negative number;
- why the calculation functions are easier to test than the interactive input function;
- how
longest_session([])and the printed empty summary represent the no-session case differently; - one revealing calculation test, including its input, expected result, and the mistake it could expose.
Base the explanation on the specified program behavior, not only on general statements such as “functions make code cleaner.”
Check Your Understanding
- What is the difference between a parameter and an argument?
- What is the difference between printing a result and returning it?
- Why can mutating a list object through a parameter be visible to the caller, while assigning another integer to a parameter changes only the function’s local name?
- What does an
assertstatement check? - Why should tests be based on intended behavior rather than copied from the implementation?
Feedback
Finish the part with the short reflection and feedback form below.
Reflection and feedback
0 / 5 points
Consider the following statements and answer them based on your experiences from studying the materials and working on the assignments in this part. When answering the numeric statements, answer them so that value 1 means that you strongly disagree with the statement, and value 7 means that you strongly agree with the statement. Please be as honest as possible when answering. The feedback will be used to improve the course.
Looking Ahead
Lists let you store several values, and functions let you organize the behavior that processes them. But a list such as:
student = ["Ada", 42, "Computer Science"]still relies on remembering what each position means.
In Part 4, you will focus on organizing data. Dictionaries and other structured representations will let programs give names and relationships to the information they store.