A function called process_student_data reads a CSV file, calculates each student's average, converts averages to letter grades, and prints a formatted report. What is the primary design problem?
AThe function name is too long and should be shortened
BThe function violates single responsibility — it does four distinct things that should each be separate functions
CThe function should use global variables instead of reading files internally
DThere is no problem — combining all steps in one function makes the code easier to follow
Single responsibility means a function should have one reason to exist and one reason to change. process_student_data has at least four: file parsing, average calculation, grade conversion, and formatting. If the CSV format changes, or the grade scale changes, the function must change for reasons unrelated to each other. Separate functions — parse_file, calculate_average, to_letter_grade, print_report — can each be tested and modified independently.
Question 2 Multiple Choice
The same 12-line calculation logic appears in three different places in a program. What is the most important reason to extract it into a single function?
ATo reduce the total line count and make the file smaller
BSo that fixing a bug in the logic only requires one change, not three
CFunctions run faster than inline code, improving performance
DTo prevent other programmers from reading the calculation logic
The most important benefit is that a bug fix propagates everywhere. If the calculation has an error and it appears in three places, fixing it in one place leaves the other two broken. With a single function, fixing the logic once fixes it everywhere the function is called. Reducing line count is a secondary benefit; the primary benefit is correctness and maintainability.
Question 3 True / False
Small functions that each do mainly one thing are inefficient in real programs and should be avoided in favor of fewer, larger functions.
TTrue
FFalse
Answer: False
This is a persistent misconception. In practice, the overhead of a function call is negligible in almost all programs — modern compilers and interpreters optimize it away. Small, single-responsibility functions are the foundation of readable, testable, maintainable code. The benefits far outweigh any theoretical performance cost that is nearly always immeasurable.
Question 4 True / False
If you find yourself writing a comment like '# now calculate the average' before a block of code, that block is likely a good candidate to extract into a named function.
TTrue
FFalse
Answer: True
A comment explaining what a block of code does is a signal that the block could be a function with that description as its name. Instead of a comment '# calculate the average,' you write a function called calculate_average() and call it — the code becomes self-documenting. This heuristic is a practical guide to finding natural decomposition boundaries in existing code.
Question 5 Short Answer
What does 'single responsibility' mean for a function, and why does it make the function easier to test in isolation?
Think about your answer, then reveal below.
Model answer: Single responsibility means a function has one clearly defined job — one input-to-output transformation — and one reason to change. For example, calculate_average(scores) takes a list of numbers and returns their mean. It knows nothing about files, letter grades, or formatting. Because it has a single, well-defined purpose, you can test it by passing in a list of numbers and checking the output — no file system or other functions needed. A function with multiple responsibilities requires setting up all those contexts to test any one of them, making testing complex and error-prone.
Testability is one of the strongest arguments for decomposition. When a function does one thing, you can write a test that verifies exactly that one behavior. When a function does five things, a test failure might be caused by any of the five, and you must set up all five contexts to run the test at all.