MGU Computer Science Series — Computer Science Foundations
Part II: Programming Foundations
Functions · Parameters · Return Values · Decomposition · Reuse
Chapter 9 of 28
MGU Computer Science Series  ·  Computer Science Foundations  ·  Library Textbook Edition

Chapter 9:
Functions,
Decomposition,
and Reuse

How to name, define, and call reusable blocks of code — and why organizing programs into functions makes them easier to read, test, and change

■ Part II: Programming Foundations ■

■ 10 Sections  •  Chapter 9 of 28 ■

Follows Chapter 8: Conditionals, Loops, and Control Flow  ·  Prepares students for Chapter 10: Debugging, Testing, and Program Design

Purpose and Overview

Programs grow quickly. A program that solves a real task can stretch from a handful of lines to hundreds in short order — and as it grows, keeping all of its logic in a single flat sequence becomes harder and harder to manage. Reading it requires following every detail at once. Testing it means running the whole thing. Changing one part risks breaking another. Functions are the tool that makes large programs manageable.

A function is a named block of instructions that can be called by name wherever its work is needed. Instead of repeating instructions, a program calls the function. Instead of reading every detail at once, a reader sees the function's name and understands its purpose at a high level. Functions make programs easier to write, easier to understand, easier to test, and easier to improve.

Chapter 9 introduces functions from the ground up: how to define them, how to call them, how to pass information in through parameters, how to receive results back through return values, and how to keep variables safely local to the functions that create them. The chapter then connects functions to the larger habits of decomposition and reuse — habits that experienced programmers apply every day regardless of the language or project they are working on.

Opening Question

A recipe contains twelve distinct steps: mixing flour, activating yeast, kneading dough, shaping loaves, and more. If someone asks you to explain the process, reading all twelve pages aloud is overwhelming. A better answer names the steps: "Mix the dough, let it rise, shape it, bake it." Programs face exactly the same challenge — and functions are the solution. By the end of this chapter, you will understand why naming pieces of a program is one of the most powerful ideas in all of computing.

10Sections
10Objectives
17Key Terms
12+Code Examples

Learning Objectives

  1. 1Explain what a function is and describe the problems it solves in program organization.
  2. 2Read and write a function definition, identifying its name, parameters, and body.
  3. 3Trace a function call, following the flow of execution into the function body and back.
  4. 4Distinguish parameters from arguments and explain how values are passed into functions.
  5. 5Write functions that use return values to send results back to the caller.
  6. 6Explain local variables and describe the basic concept of scope.
  7. 7Apply decomposition to break a complex problem into well-named functions.
  8. 8Recognize opportunities for code reuse and explain why reuse produces more reliable programs.
  9. 9Describe the qualities of a well-designed function: clear name, single purpose, appropriate length.
  10. 10Read programs organized with a main function pattern and trace the flow of calls between functions.

Sections at a Glance

Sections 9.1 – 9.3
What Functions Are and How to Define and Call Them
Why Functions Matter · Defining Functions · Calling Functions

Why Functions Matter

Imagine that you are baking bread for the first time. You follow a recipe that runs twelve pages. Each page describes a different step: mixing flour, activating yeast, kneading dough, shaping loaves, adjusting the oven. The recipe works, but if someone asks you to explain the process, reading all twelve pages aloud is overwhelming. A better answer is to say: "I mix the dough, let it rise, shape it, and bake it." Each phrase names a step without describing every detail inside it.

Programs face the same problem. A program that solves a real task quickly grows beyond a few lines. If every instruction is written out in one flat sequence, the program becomes hard to understand, hard to test, and hard to change. When something goes wrong, finding the mistake in four hundred consecutive lines is exhausting. When the program needs to perform the same task twice, rewriting the same instructions twice introduces the chance of inconsistency.

Functions solve this problem. A function is a named block of instructions that can be called by name whenever its work is needed. Instead of repeating instructions, a program calls the function. Instead of reading every detail, a reader sees the function's name and understands its purpose.

What Functions Allow a Programmer to Do

Organize — Give a name to a group of related instructions.

Reuse — Call those instructions multiple times without rewriting them.

Test — Test one piece of the program independently of the others.

Maintain — Replace or improve one piece without rewriting everything else.

Read — Understand the program at a high level before diving into details.

Functions are not a new idea invented for programming. People use the same idea constantly. A recipe names steps. An instruction manual names procedures. A job description names responsibilities. In each case, a name stands for a collection of actions that can be referenced and repeated. In programming, functions make large programs possible — not because each line is visible at once, but because the program is organized into named pieces that each make sense on their own.

Defining Functions

Before a function can be used, it must be defined. A function definition gives the function a name and specifies the instructions it will carry out.

In Python-style notation, a function definition looks like this:

Python — Function Definition
def greet(): print("Hello!") print("Welcome to Computer Science Foundations.")

Reading this definition carefully: the word def signals that a function definition is beginning. greet is the name of the function — chosen by the programmer to describe what it does. The parentheses () come after the name and will hold parameters when needed. The colon : ends the definition line. The indented lines underneath are the body of the function — the instructions that will run when it is called.

Definition ≠ Execution

The function definition does not run the instructions. Defining a function is like writing a recipe: the recipe sits on the shelf until someone follows it. A function definition sits in the program until the function is called.

Pseudocode Notation

Not every computer science course uses Python. Throughout this book, pseudocode describes algorithms in plain, language-neutral terms. Here is the same function in pseudocode notation:

Pseudocode — Function Definition
FUNCTION greet PRINT "Hello!" PRINT "Welcome to Computer Science Foundations." END FUNCTION
Naming Convention

Choose function names that describe what the function does. A reader who sees greet() or calculate_area() immediately understands the purpose. A name like f() or do_thing() forces the reader to search for the body to understand anything.

Calling Functions

Defining a function creates it. Calling a function runs it. In Python-style notation, a function call uses the function's name followed by parentheses:

Python — Defining and Calling
def greet(): print("Hello!") print("Welcome to Computer Science Foundations.") greet() greet() greet()
Output
Hello! Welcome to Computer Science Foundations. Hello! Welcome to Computer Science Foundations. Hello! Welcome to Computer Science Foundations.

The function is defined once and called three times. Each call runs the full body of the function. This is the first major benefit of functions: write once, call many times.

Concept Example 9.3.1
What happens during a function call
  • Step 1The main program reaches a function call: greet().
  • Step 2Execution pauses at that point and jumps to the body of the greet function.
  • Step 3All instructions in the body run in order: the two print statements execute.
  • Step 4The function ends and execution returns to the line immediately after the original call.
Key idea: the program remembers where it was before calling the function, so it can continue from that point afterward.
Order Matters in Python

In Python, a function must be defined before it is called. Calling greet() before writing def greet(): produces an error. The correct approach places all definitions above the calls that use them.

Practice 9.1 – 9.3Concept Check
  1. In your own words, describe the difference between defining a function and calling a function.
  2. What does "write once, call many times" mean? Give an example situation where this would be useful.
  3. A program defines a function called show_title() with three print statements in its body. If the function is called five times, how many total print statements execute?
  4. Why must a function be defined before it is called in Python?
  5. Write a function called print_separator() that prints a line of twenty dashes. Then write three calls to it.
Sections 9.4 – 9.5
Parameters, Arguments, and Return Values
Passing Data In · Sending Results Back

Parameters and Arguments

The functions seen so far do the same thing every time they are called. That is useful, but limited. Most functions need to work with different data depending on the situation. A parameter is a variable listed in the function definition that represents information the function needs. When the function is called, the programmer supplies an argument — an actual value — for each parameter.

Python — Function with a Parameter
def greet_person(name): print("Hello, " + name + "!") print("Welcome to the course.") greet_person("Amara") greet_person("Jerome") greet_person("Sun Li")
Output
Hello, Amara! Welcome to the course. Hello, Jerome! Welcome to the course. Hello, Sun Li! Welcome to the course.

Each call passes a different argument. The parameter name takes the value of the argument for that call. The function's body uses name as a variable, so the output changes depending on what is passed in.

TermWhere It AppearsWhat It IsExample
ParameterFunction definitionA variable that receives a value when the function is calleddef greet(name): — name is the parameter
ArgumentFunction callThe actual value passed to the functiongreet("Amara") — "Amara" is the argument

Multiple Parameters

A function can have more than one parameter. Parameters are separated by commas in the definition. Arguments are matched to parameters by position — the first argument goes to the first parameter, the second argument to the second parameter, and so on.

Python — Two Parameters
def introduce(name, city): print(name + " is from " + city + ".") introduce("Fatima", "Lagos") introduce("Marcus", "Detroit") introduce("Yuki", "Osaka")
Output
Fatima is from Lagos. Marcus is from Detroit. Yuki is from Osaka.
Worked Example 9.4.1
A function with arithmetic — tracing the parameter
  • Program def double(number): result = number * 2 print(result) double(5) double(12) double(100)
  • TraceFirst call: number = 5, result = 10. Second call: number = 12, result = 24. Third call: number = 100, result = 200.
  • Output10 24 200
The same instructions run three times with three different values of the parameter.
Argument Order Matters

Arguments are matched by position. If a function expects (name, age) and you call it with ("Jordan", 25), then name = "Jordan" and age = 25. Reversing them to (25, "Jordan") causes name = 25 and age = "Jordan" — almost certainly wrong.

Practice 9.4Parameters and Arguments
  1. In the definition def calculate_price(quantity, unit_price, discount):, identify each parameter.
  2. Write a call to calculate_price with 5 items, a unit price of 12.99, and a 10% discount.
  3. In def describe(animal, sound): print("A " + animal + " says " + sound + ".") — after the call describe("cat", "meow"), what values do animal and sound hold?
  4. Write a function called multiply that takes two parameters and prints their product. Write three calls to it with different arguments.
  5. Explain in your own words why the distinction between parameter and argument matters.

Return Values

The functions seen so far have performed actions — printing output. But many functions need to return a result that the rest of the program can use. A return value is the result that a function sends back to whoever called it. In Python, the return statement specifies what value to send back.

Python — Return Instead of Print
def double(number): return number * 2 result = double(7) print(result)
Output
14

The call double(7) runs the function with argument 7. The function computes 7 * 2 = 14 and returns 14. That returned value is stored in the variable result. Return values can also be used directly in expressions: print(double(5) + double(3)) adds two return values together before printing.

Worked Example 9.5.1
A practical return value — temperature conversion
  • Function def celsius_to_fahrenheit(c): return (c * 9 / 5) + 32
  • Usage boiling = celsius_to_fahrenheit(100) freezing = celsius_to_fahrenheit(0) body_temp = celsius_to_fahrenheit(37)
  • Result 212.0°F 32.0°F 98.6°F
  • Key ideaThe conversion formula appears once — inside the function — even though it is applied three times. One change fixes all three conversions.
The function computes the result and returns it. The caller stores and uses the value without needing to know the formula.
What Return Does

1. It sends a value back to the caller.

2. It immediately ends the function's execution. Any instructions after a return statement inside a function will not run.

None — If a function ends without a return statement, Python automatically returns the special value None, which means "no value."

Function TypeWhat It DoesWhen to Use It
Action functionPrints output, modifies a variable, or performs a taskWhen the program needs to do something, not compute something
Value functionComputes a result and returns it for the caller to useWhen the result will be stored in a variable or used in an expression
Practice 9.5Return Values
  1. What is the difference between a function that prints a result and a function that returns a result? Give one situation where returning is more useful.
  2. In def mystery(n): return n * n - 1 — what value is stored in x after x = mystery(5)?
  3. Rewrite this function so it returns the result instead of printing it: def triple(n): print(n * 3)
  4. Write a function called average that takes two numbers and returns their average. Then call it three times with different inputs.
  5. What does a function return if it has no return statement? How would this cause a problem if the caller tries to use the result?
Sections 9.6 – 9.8
Local Variables, Decomposition, and Reuse
Scope · Breaking Problems Apart · Writing Once, Using Many Times

Local Variables and Scope at an Introductory Level

When a function runs, it can create its own variables. These are called local variables because they exist only inside the function. When the function ends, local variables disappear. The region of a program where a variable can be accessed is called its scope. A local variable is in scope inside its function and out of scope everywhere else.

Python — Local Variable
def compute_area(length, width): area = length * width # 'area' is a local variable return area result = compute_area(6, 4) print(result) # print(area) # ERROR: 'area' does not exist outside the function
Output
24

Inside compute_area, the variable area is created and used. When the function returns, area no longer exists. Code outside the function cannot access area — it is local to the function. Parameters behave exactly like local variables: they exist inside the function for the duration of that call and disappear when the function returns.

The Workspace Model

Imagine each function call as a separate desk drawer that opens when the function starts and closes when it ends. Everything inside the drawer — local variables, parameters — is available while the drawer is open. When the drawer closes, everything inside disappears. The main program has its own workspace at a different level, separate from all function drawers.

Why Scope Protects Programs

If every function shared its variables with every other function, a change inside one function could accidentally affect another. Local variables are a protection mechanism: they keep functions self-contained. When reading a function, a programmer knows that local variables belong entirely to that function — there is no need to search the whole program to understand what they contain.

Practice 9.6Scope Questions
  1. What is a local variable? What does it mean for a variable to be "in scope"?
  2. A function defines a variable called count in its body. Can code outside the function access count? Explain why or why not.
  3. In def show_double(x): doubled = x * 2; print(doubled) — which variables are local to show_double?
  4. Explain in your own words why local scope makes functions easier to understand and test.
  5. What error would this code produce? def calculate(): answer = 42 calculate() print(answer)

Decomposition with Functions

Decomposition is the practice of breaking a complex problem into smaller, named parts that are easier to understand and solve separately. Functions are the primary tool for decomposition in programming. Instead of writing a large block of code to do everything at once, a programmer identifies the distinct tasks, writes a function for each one, and then assembles those functions into a whole.

A Program Without Decomposition

Python — Flat, Undecomposed
print("==============================") print("Welcome to the Number Adder!") print("==============================") a = int(input("Enter the first number: ")) b = int(input("Enter the second number: ")) total = a + b print("The sum is: " + str(total)) print("==============================") print("Thank you for using the program.") print("==============================")

The Same Program with Decomposition

Python — Decomposed into Functions
def print_banner(message): print("==============================") print(message) print("==============================") def get_number(prompt): return int(input(prompt)) def add(a, b): return a + b def main(): print_banner("Welcome to the Number Adder!") a = get_number("Enter the first number: ") b = get_number("Enter the second number: ") total = add(a, b) print("The sum is: " + str(total)) print_banner("Thank you for using the program.") main()

This version is longer, but it is better organized. print_banner handles all banner printing — change it once and both banners change. get_number handles input with a prompt parameter. add handles the arithmetic. main describes the overall structure in plain, readable steps. The main function reads almost like a sentence: print a banner, get two numbers, add them, show the result, print another banner.

A Useful Test for Decomposition

If you cannot summarize what a function does in one sentence, it may be doing too much. Consider breaking it into smaller functions. Good decomposition produces functions that each do one thing well, have a clear descriptive name, are small enough to read quickly, and can be tested independently.

Reusing Code

One of the strongest arguments for functions is code reuse. When a task needs to be performed in more than one place, a function performs that task once and is called wherever it is needed. Repetition is not merely inconvenient — it is dangerous. Each copy of repeated logic is an opportunity for inconsistency. If the logic needs to change, every copy must be found and corrected. Missing one produces different behavior in different parts of the program.

Comparison Example 9.8.1
Repeated formula vs. function call
  • Repeated temp1_f = (25 * 9 / 5) + 32 temp2_f = (0 * 9 / 5) + 32 temp3_f = (100 * 9 / 5) + 32 Formula appears three times. A typo in any copy produces a silent error.
  • Function def celsius_to_fahrenheit(c): return (c * 9 / 5) + 32 temp1_f = celsius_to_fahrenheit(25) temp2_f = celsius_to_fahrenheit(0) temp3_f = celsius_to_fahrenheit(100) Formula appears once. One change fixes all three.
Reuse makes programs shorter, clearer, and more reliable.

The idea of code reuse extends far beyond individual programs. Programming languages come with libraries — collections of pre-written functions that programmers can call without writing them. Python's standard library includes functions for working with numbers, formatting dates, reading and writing files, generating random numbers, and sorting data. When a Python program calls len("hello"), it is reusing a function that someone else wrote and tested. The programmer reuses that function without seeing or managing its internal code. The skills developed in this chapter — clear functions, good names, parameters and return values — are the same skills used in large-scale reuse.

Practice 9.7 – 9.8Decomposition and Reuse
  1. What is decomposition? How do functions support it?
  2. A program needs to print a formatted receipt header in four different places. Should the header logic be repeated four times or placed in a function? Explain your reasoning.
  3. Describe how you would decompose a grade calculator program into functions. Name at least three functions and describe what each one does.
  4. What is a library? How does a library extend the idea of code reuse beyond a single program?
  5. A student writes the same formula in six places throughout a program. Later, they discover the formula has a mistake. Why is this harder to fix than if the formula had been placed in a function?
Sections 9.9 – 9.10
Designing Clear Functions and Programs
Good Names · Single Purpose · Main Function Pattern · Functions Calling Functions

Designing Clear Functions

Writing a function that works is the first goal. Writing a function that is also clear, well-named, and easy to use is the professional standard. The habits in this section separate programs that merely run from programs that can be understood, maintained, and trusted.

Choose Names That Describe the Task

A function's name is a promise to the reader about what it does. Compare f(x) — which tells nothing — with square(x), which tells everything. Good function names are usually verbs or verb phrases for functions that perform actions, and descriptive noun phrases or adjective phrases for functions that compute values.

PatternExamplesWhy It Works
Verb phrase for actionsprint_report(), save_file()Describes what the function does
Verb + noun for computationscalculate_average(scores), convert_to_celsius(f)Names the result being produced
is_ or has_ prefix for checksis_valid_email(address), has_duplicates(list)Signals a True/False return value

Write Functions That Do One Thing

A function should have a clear, single purpose. If a function does too many different things, it becomes hard to test, hard to reuse, and hard to understand. Consider separating a function that both computes a total and formats and prints a receipt into two functions: one that returns the total, one that prints the formatted output. Each function can then be tested, reused, and understood on its own.

Keep Functions Short Enough to Read at Once

A function that fits on one screen — roughly 20 to 30 lines — is usually easier to understand than a longer one. When a function grows much longer than that, it often signals that it contains more than one distinct task and could be decomposed further. This is a guideline, not an absolute rule. But brevity is a goal worth aiming for.

Write a Purpose Comment When the Name Is Not Enough

Python — Purpose Comment
def adjust_score(raw_score, curve): # Adds the curve to the raw score and clamps the result to a maximum of 100. adjusted = raw_score + curve if adjusted > 100: adjusted = 100 return adjusted

The comment explains the clamping behavior, which the name adjust_score does not fully convey. Brief, purposeful comments at the start of a function body are a professional habit — they explain what the function does, especially when the behavior has a constraint or nuance that the name alone cannot capture.

Test Functions with Specific, Known Inputs

Python — Testing a Function
# Test the celsius_to_fahrenheit function print(celsius_to_fahrenheit(0)) # Should be 32 print(celsius_to_fahrenheit(100)) # Should be 212 print(celsius_to_fahrenheit(-40)) # Should be -40 print(celsius_to_fahrenheit(37)) # Should be 98.6

When a function is finished, test it by calling it with inputs whose correct outputs are already known. If the function returns the right results for known inputs, the programmer gains confidence that it works. If a result is wrong, the problem is isolated to that one function — not buried in a large program.

Functions in Larger Programs

The concepts in this chapter come together in programs of meaningful size. Functions allow a programmer to manage complexity: to think at a high level when reading the structure, and at a detailed level when working on individual pieces. Two patterns make this possible in practice.

The Main Function Pattern

Many programs organize their top-level logic into a function called main. The main function describes what the program does step by step, using calls to other functions for each step. Reading main gives a full picture of the program's logic without showing any of the details.

Python — Main Function Pattern
def main(): display_welcome() scores = collect_scores() average = calculate_average(scores) display_results(average) display_farewell() main()

Each function call names a step. A reader who wants to understand the details of one step looks at that function's definition. This layered structure — high-level description at the top, detailed implementation below — is exactly how large real-world programs are organized.

Functions Calling Functions

Python — Functions Calling Other Functions
def greet_all(names): for name in names: greet_one(name) def greet_one(name): message = build_greeting(name) print(message) def build_greeting(name): return "Hello, " + name + "!" greet_all(["Amara", "Jerome", "Sun Li"])
Output
Hello, Amara! Hello, Jerome! Hello, Sun Li!

Here greet_all calls greet_one, which calls build_greeting. Each function does one clear job. The call stack — the record of which functions are currently running and where each will return — tracks this chain of calls. When build_greeting returns, execution goes back to greet_one. When greet_one returns, execution goes back to greet_all.

Looking Ahead

Functions are the foundation of every programming skill built in later courses. Data structures courses use functions to process collections of data. Web development courses use functions to handle user interactions. Software engineering courses use functions as the basic unit of testing, documentation, and collaboration. The habits developed here — naming well, one purpose per function, using parameters and return values, decomposing problems — are habits that experienced programmers apply every single day.

Practice 9.9 – 9.10Design and Larger Programs
  1. What are four qualities of a well-designed function? Give a brief explanation for each.
  2. Explain the main function pattern. Why is it a useful organizational approach?
  3. Write a main function for a program that: greets the user, asks for their name, and prints a personalized message. Define the three helper functions it would call.
  4. A program contains three functions: collect_data, process_data, and display_results. Describe the call stack as the program runs from start to finish.
  5. Why does testing individual functions before combining them into a full program make debugging easier?

Chapter Summary

Key Terms Review

function
A named block of instructions that can be called by name whenever its work is needed.
function definition
The code that creates a function by giving it a name, specifying its parameters, and writing its body.
function call
An instruction that runs a function by name, optionally supplying arguments.
body
The indented instructions inside a function definition that run when the function is called.
parameter
A variable listed in a function definition that receives a value when the function is called.
argument
The actual value supplied to a function when it is called. Matched to parameters by position.
return value
The result that a function sends back to the caller using the return statement.
return statement
An instruction that specifies the value to send back and immediately ends the function's execution.
local variable
A variable created inside a function that exists only for the duration of that function call.
scope
The region of a program where a variable can be accessed. Local variables are in scope only inside their function.
decomposition
The practice of breaking a complex problem into smaller, well-named parts that are easier to solve separately.
code reuse
Writing a piece of logic once and calling it wherever needed, rather than repeating the instructions.
modular design
Organizing a program as a collection of separate, well-defined functions that each perform one task.
call stack
The record of which functions are currently running and where each one will return when it finishes.
def keyword
The Python keyword that begins a function definition.
library
A collection of pre-written functions that programmers can call and reuse without writing them from scratch.
main function pattern
An organizational approach in which a main function describes the program's top-level logic through named function calls.

Function Tracing Practice

For each program, trace the execution step by step and write what the program prints. Work through the code by hand — do not run it.

Tracing Exercise 1Simple calls and repetition
def say_hello(): print("Hello!") def say_goodbye(): print("Goodbye!") say_hello() say_goodbye() say_hello()

→ Trace the output.

Tracing Exercise 2Return values and expressions
def add_ten(n): return n + 10 result = add_ten(5) print(result) print(add_ten(20)) print(add_ten(result))

→ Trace the output. Pay close attention to the last line.

Tracing Exercise 3Two parameters
def greet(name, time_of_day): print("Good " + time_of_day + ", " + name + "!") greet("Fatima", "morning") greet("Marcus", "evening") greet("Yuki", "afternoon")

→ Trace the output.

Tracing Exercise 4Functions calling other functions
def square(n): return n * n def sum_of_squares(a, b): return square(a) + square(b) print(sum_of_squares(3, 4)) print(sum_of_squares(1, 1))

→ Trace the output. Notice that sum_of_squares calls square.

Tracing Exercise 5Boolean return values
def is_even(n): if n % 2 == 0: return True else: return False print(is_even(4)) print(is_even(7)) print(is_even(0))

→ Trace the output.

Common Errors

Error 1 — Calling before defining
result = double(5) # Error: double is not defined yet def double(n): return n * 2

Fix: Move the function definition above the call, or restructure so all definitions come first.

Error 2 — Wrong number of arguments
def add(a, b): return a + b result = add(3) # Error: add() requires 2 arguments, only 1 given

Fix: Supply the correct number of arguments to match the number of parameters.

Error 3 — Expecting a return value from a void function
def show(n): print(n * 2) # Prints but does not return result = show(5) # result will be None, not 10 print(result + 1) # Error: cannot add 1 to None

Fix: If the program needs to use the result in an expression, add a return statement.

Error 4 — Accessing a local variable outside its function
def calculate(): answer = 42 calculate() print(answer) # Error: 'answer' not defined outside the function

Fix: Use a return statement to send the value out of the function, and store it in a variable in the calling code.

Error 5 — Reversed argument order
def describe(name, age): print(name + " is " + str(age) + " years old.") describe(25, "Jordan") # Prints: 25 is Jordan years old.

Fix: Arguments must be supplied in the same order the parameters are defined. name comes first, then age.

Error Analysis Practice

Each program contains one or more errors. Identify each error, explain what is wrong, and write a corrected version.

Error Analysis 1Missing colon
def greet(name) print("Hello, " + name) greet("Amara")

→ What is wrong? Write the corrected version.

Error Analysis 2Missing return statement
def add_numbers(a, b): total = a + b result = add_numbers(3, 7) print(result)

→ The program prints None instead of 10. What is missing? Correct it.

Error Analysis 3Unreachable code
def multiply(a, b): return a * b print("Multiplied!") print(multiply(4, 5))

→ The program never prints "Multiplied!" Why? Is this a bug or expected behavior? Explain.

Error Analysis 4Reference without call
def count_up(n): for i in range(1, n + 1): print(i) result = count_up print(result(5))

→ What is wrong on the line result = count_up? How should it be written?

Error Analysis 5Argument order swapped
def show_info(name, age, city): print(name + " is " + str(age) + " from " + city + ".") show_info("Jordan", "Chicago", 28)

→ The output is garbled. What is wrong? Write the corrected function call.

Chapter 9 Checkpoint

Chapter 9 Checkpoint
Complete without assistance — assesses all key skills and concepts from Chapter 9
Section 1 — Vocabulary and Concepts
  1. What is a function? Give two reasons why functions are useful in programs.
  2. Explain the difference between a function definition and a function call.
  3. What is a local variable? Why are local variables important?
Section 2 — Reading and Tracing
  1. What does this program print? Trace step by step.
    def add(a, b): return a + b
    x = add(3, 4)
    print(x)
    print(add(x, 10))
  2. Identify the parameter(s) and the return value in: def area(base, height): return 0.5 * base * height
  3. A student calls greet("Jordan", "evening"). The definition is def greet(time, name):. What values do each parameter receive?
Section 3 — Writing Functions
  1. Write a function called square that takes one number and returns its square.
  2. Write a function called is_passing that takes a score and returns True if the score is 60 or above, False otherwise.
  3. Write a function called repeat_message that takes a message and a number, and prints the message that many times.
Section 4 — Design
  1. A program needs to: greet the user, ask for a temperature in Celsius, convert it to Fahrenheit, and print the result. Write a main function that describes this program using four function calls, then define each helper function.
  2. What qualities make a function well-designed? Name and explain four.
Section 5 — Error Analysis
  1. A student writes def show(n): print(n) and then calls x = show(5) + 1. The program crashes. What is wrong and how should it be fixed?
  2. A student places a print statement after the return in a function. What happens to that statement? Why?

Real-World Applications

For each scenario, identify which functions you would write and how they would work together.

  1. A recipe scaling app allows a user to enter a number of servings and adjusts ingredient quantities. What functions might this program use? Name them and describe their parameters and return values.
  2. A ride-share app calculates trip cost based on distance and time, then applies a surge multiplier if demand is high, then applies a promo code. Describe the decomposition into functions.
  3. A school attendance system records whether each student is present, calculates the attendance percentage, and flags if it falls below 70%. What distinct tasks become separate functions?
  4. A unit converter can convert miles to kilometers, pounds to kilograms, and Fahrenheit to Celsius. How does reuse apply to the design? Could you use a shared helper function?
  5. A weather app fetches temperature data, converts to the user's preferred unit, and displays a message based on the range. Describe the function structure from top-level main down to the helpers.

Mixed Review

These questions draw on material from earlier chapters.

  1. Chapter 3 introduced decomposition as a computational thinking strategy before programming. How does Chapter 9's treatment of functions connect to that earlier idea?
  2. Chapter 8 introduced loops. Can a function contain a loop? Can a loop contain a function call? Write a short example of each.
  3. A function is a kind of abstraction. Using what you will learn in Chapter 13 about abstraction and black boxes, explain why a function call is an example of a black box.
  4. Write a pseudocode version of the following Python function: def find_larger(a, b): if a > b: return a else: return b
  5. A program has three functions: collect_data, process_data, and display_results. The main function calls them in order. Describe what the call stack looks like at each stage of execution.

Design and Application Questions

  1. Write a function called average that takes three numbers as parameters and returns their average. Test it with at least three different sets of inputs by predicting the output before running.
  2. Write a function called celsius_to_kelvin that converts Celsius to Kelvin (Kelvin = Celsius + 273.15). Return the result rather than printing it. Then write a caller that uses the return value.
  3. A program needs to print a formatted report for any student, including their name, score, and pass/fail status. Design the functions this program would need. Name them, describe parameters and return values, and explain how they work together.
  4. Explain in your own words why a function should do one thing rather than many things. What specific problems does mixing multiple tasks into one function create?
  5. A classmate argues that functions are unnecessary because you can always just write the same code multiple times. Write a clear, detailed explanation of why this approach leads to problems in real programs.

Review Questions

  1. What is a function? Why are functions useful in programs?
  2. What is the difference between a function definition and a function call?
  3. What are parameters? What are arguments? How do they relate to each other?
  4. What does the return statement do? What happens if a function has no return statement?
  5. What is a local variable? What does it mean to say a variable is "in scope"?
  6. What is decomposition? How do functions support it?
  7. What is code reuse? Give an example of a situation where reuse prevents a serious problem.
  8. What qualities make a function well-designed? Name at least four.
  9. What is the main function pattern? Why is it a useful organizational approach?
  10. In what order must a function be defined relative to its first call in a Python program?
Looking Ahead
Chapter 10: Debugging, Testing, and Program Design

Chapter 9 established functions as the primary tool for organizing and reusing code. Chapter 10 turns to a challenge that every programmer faces from the very first program: mistakes. No program works perfectly on the first attempt. Errors appear in syntax, in logic, and at runtime. Chapter 10 introduces the three major categories of programming errors, systematic strategies for finding and fixing them, the discipline of testing programs with specific known inputs, and principles for designing programs that are less likely to contain mistakes. Every skill introduced in Part II — variables, control flow, functions — will be revisited through the lens of debugging and testing. These habits apply to every program a student will write, in this course and beyond.

MGU Library Connection
  • Python Syntax Quick Reference — Appendix D of this textbook
  • Pseudocode and Flowchart Reference — Appendix C of this textbook
  • Chapter 3: Problem Solving and Computational Thinking — decomposition as a pre-programming strategy
  • Chapter 8: Conditionals, Loops, and Control Flow — using loops inside functions
  • Python Programming Foundations — functions in depth, recursion, higher-order functions
  • Data Structures and Algorithms — functions as the basic unit of algorithmic design