Built-in Functions: max() and min()
Collect all numbers from the user into a list using a while loop that terminates when the user enters a sentinel value like 'done'.
From Input to Answer
A program that finds the largest and smallest values from user input has two separate jobs. First, it collects numbers into a list. Second, after collection is complete, it examines that list with max() and min(). Keeping these jobs separate makes the program easier to trace and helps ensure that the sentinel value, such as done, is not treated as a number.
The loop builds the list. The calls to max() and min() happen after the loop, when the list contains all collected numbers.
What do you think happens?
A user enters 6, 2, 9, 3, 5, and then done. When should max() and min() be called?
Reveal answer
Answer: After done causes the loop to exit
The list must be complete before max() and min() are used to find the largest and smallest values.
Looping Until done
The input process repeats while the user is entering numbers. Each numeric input is converted to int or float and appended to the list. The sentinel value marks the end of the process: it tells the loop to stop, and it is not appended to the numeric list.
The important branch is the sentinel check. A number follows the append path and causes another input to be read. The sentinel follows the exit path. Because it exits before the append step, it never becomes part of the list examined by max() and min().
Tracing the Growing List
Consider the input sequence 6, 2, 9, 3, 5, and done. The list starts empty. Each number changes the list by adding one converted numeric value. When done is entered, the list does not change; instead, the loop exits. The completed list is therefore [6, 2, 9, 3, 5] immediately before max() and min() are called.
Six Inputs, One Completed List
Trace the list and identify the values found by max() and min() after the inputs 6, 2, 9, 3, 5, and done.
Start: The list is empty before any numeric input has been collected.
Collect numbers: The values 6, 2, 9, 3, and 5 are converted to numeric values and appended in that order.
Receive the sentinel: done tells the loop to exit. It is not appended to the list.
Analyze the completed list: max() and min() are called only after the loop exits, using the complete list [6, 2, 9, 3, 5].
max() identifies 9 as the largest value, and min() identifies 2 as the smallest value.
Using the Completed List
max() and min() both examine the same completed list, but they answer different questions. max() identifies the largest value in the list, while min() identifies the smallest value. Their position in the process matters: they are used after the while loop has finished collecting input, not during each repetition.
Calling max() or min() inside the input loop analyzes a partial list. The intended process is to finish collecting numbers first and analyze the complete list afterward.
Keeping the Sentinel Out
The sentinel has a control-flow role, not a data role. When the user enters done, the program should use it to leave the loop. It should not convert done to a number and should not append it to the list. The list passed to max() and min() must contain the collected numeric values only.
Debugging Collection Problems
Most problems in this pattern come from confusing input control with numeric data. Check each input at the point where it is received: determine whether it is the sentinel, and convert every non-sentinel input to int or float before appending it.
Calling max() or min() inside the loop.
The list is still being built, so the analysis happens before all user data has been collected.
Fix:
Wait until the loop exits, then call max() and min() on the complete list.Forgetting to convert user input to a number.
The list is intended to contain numeric values, but the input has not been converted to a numeric type.
Fix:
Convert each non-sentinel input to int or float before appending it.Adding the sentinel to the list.
The sentinel marks termination; it is not one of the numbers being analyzed.
Fix:
Check for the sentinel before conversion and appending, then exit the loop when it appears.Calling max() or min() before any numbers have been collected.
The list has no collected numbers to analyze.
Fix:
Handle the empty-list case before calling max() and min().
Practice the Trace
Trace this input sequence: 12, 4, 18, 7, done. Write the list after each numeric input. Then identify which value max() finds and which value min() finds. Finally, explain why done is absent from the list.
Hints
- Start with an empty list.
- Append only the numeric inputs.
- The sentinel ends the loop and is not appended.
- Call max() and min() only after the final list is complete.
A student says, “I will call max() and min() after every input so the program always knows the current answer.” Explain why this does not follow the intended collection pattern, and describe where the calls should be placed instead.
Hints
- Ask whether the list is complete after each input.
- Separate collecting data from analyzing the completed list.
Process Checklist
- Create a list for the numeric inputs.
- Read user input repeatedly with a while loop.
- Check whether the input is the sentinel, such as done.
- If it is a number, convert it to int or float and append it to the list.
- When the sentinel appears, exit the loop without appending it.
- After the loop, call max() and min() on the completed list.
- Handle the case where the list contains no collected numbers before analyzing it.
Key Takeaways
- Use a while loop to collect numbers until a sentinel such as done is entered.
- Convert every non-sentinel input to int or float before appending it to the list.
- Do not add the sentinel to the numeric list.
- Call max() and min() after the loop exits and the list is complete.
- Debug by checking input conversion, sentinel exclusion, call placement, and the empty-list case.