SECTION 1
Historical Context & Motivation
Long before Python existed, programmers struggled with a frustrating problem: every time they needed the same calculation done with different numbers, they had to rewrite the same block of code over and over. This was tedious, error-prone, and made programs impossibly long. The idea of parameters and return values — feeding information into a reusable block of code and getting a result back — was one of the most transformative ideas in the history of computing.
1936 • Lambda Calculus
1958 • FORTRAN Subroutines
1972 • The C Language
return statement to send a value back. Nearly every language since — including Python — follows this pattern.1991 • Python Is Born
def keyword to define functions with parameters and return values. Python's readable syntax made functions easier to learn than ever before.The central question this lesson addresses is: how do we write functions that are truly reusable? A function that only ever works with one fixed value, or that only prints text to the screen without giving a result back, is far less flexible. By mastering parameters and return values, you unlock the ability to write code once and use it in countless situations.
SECTION 2
Core Principles & Definitions
Before diving into code, let's establish the four foundational ideas that make functions powerful. Each principle builds on the previous one, so understanding them in order will help everything click.
Parameters Are Inputs
Return Values Are Outputs
return keyword exits the function and hands the value over. Without it, the function returns None.Returning ≠ Printing
print() displays text on the screen for a human to read, but the value disappears immediately. return sends the value back so your program can store it in a variable, use it in math, or pass it to another function.Reusability Through Abstraction
KEY TAKEAWAY
print() is like the blender making a loud noise — you can hear it, but you can't drink the noise. If you want to actually use the result, you need return.SECTION 3
Visual Explanation — How Data Flows Through a Function
The diagram below shows the complete lifecycle of a function call. Follow the numbered arrows to see how an argument enters a function as a parameter, gets processed, and exits as a return value that the calling code can store and reuse.
5 flowing into the function as parameter r. Arrow ② shows the computed value 78.54 flowing back via return. The dashed box at the bottom warns what happens when you mistakenly use print() instead of return.Notice that the function definition on the right is a self-contained unit. It doesn't know or care where the value 5 came from. Tomorrow you could call circle_area(10) or circle_area(user_input) and the function would work perfectly — that's the power of reusability through parameters.
SECTION 4
How It Works — Syntax & Mechanics
Now let's look at the precise Python syntax for defining and calling functions with parameters and return values. Understanding each piece of the syntax will prevent the most common beginner mistakes.
Defining a Function with Parameters
FUNCTION DEFINITION SYNTAX
def — keyword that starts a function definition. function_name — the name you choose (use snake_case). param1, param2 — parameters (inputs the function expects). return expression — sends the computed value back to the caller.
Calling a Function with Arguments
FUNCTION CALL SYNTAX
arg1, arg2 — arguments (the actual values you pass in). variable — captures the return value so you can use it later. The arguments are matched to parameters by position: the first argument goes to the first parameter, the second to the second, and so on.
What Happens at Runtime
- Step 1: Python sees the function call and pauses the current line of code.
- Step 2: It assigns each argument to its corresponding parameter (like creating temporary variables).
- Step 3: It executes the body of the function line by line.
- Step 4: When it hits
return, it exits the function and substitutes the return value back into the calling line. - Step 5: If there is no
returnstatement (or a barereturnwith no value), the function returnsNone.
Common Mistake Alert
print() inside their function instead of return. The output might look correct when you run the program, but the value is gone forever. You cannot store it in a variable, use it in a calculation, or pass it to another function. Always ask yourself: does the rest of my program need this value? If yes, use return.SECTION 5
Return vs. Print — The Critical Distinction
This is the single most important distinction in this lesson, and one of the most common sources of confusion for new programmers. Let's compare two versions of the same function side by side, trace what happens in memory, and see why the difference matters so much.
return sends 14 back to the variable result, making it usable everywhere. Right panel: print() shows 14 on screen, but result gets None, causing a TypeError when you try to add 3 to it.| Feature | return | print() |
|---|---|---|
| Sends value to... | The calling code (stored in a variable) | The screen (console output) |
| Value available later? | Yes — stored in memory | No — gone after display |
| Can be used in math? | Yes | No (None + int → TypeError) |
| Can be passed to other functions? | Yes | No |
| Visible on screen by default? | No (you must print it separately) | Yes |
return vs. print() comparison
The rule of thumb is simple: use return when your program needs the value, and use print() when a human needs to see the value. Often you'll do both: return the value from the function, then print it outside the function when you want to display it.
SECTION 6
Worked Example — Building a Tip Calculator
Let's build a practical function from scratch. We want to create a tip calculator that takes a bill amount and a tip percentage, then returns the total amount to pay. We'll use parameters for flexibility and return so the result can be used in further calculations.
Tip Calculator Function
- 1
Step 1 — Identify the Inputs and Output
We need two pieces of information (parameters): the bill amount and the tip percentage. The output (return value) will be the total cost including the tip.Inputs:bill,tip_percent→ Output: total cost - 2
Step 2 — Write the Function Definition
We usedefto define our function, placing the two parameters inside the parentheses. Inside the body, we calculate the tip and add it to the bill.def calculate_total(bill, tip_percent):tip = bill * (tip_percent / 100)total = bill + tipreturn totalFunction defined with 2 parameters and areturnstatement - 3
Step 3 — Call the Function with Arguments
Now we call the function, passing in a $50.00 bill and a 20% tip. We store the return value in a variable.my_total = calculate_total(50.00, 20)Python assigns:bill = 50.00,tip_percent = 20 - 4
Step 4 — Trace the Execution
Inside the function:tip = 50.00 * (20 / 100)→tip = 10.00. Thentotal = 50.00 + 10.00→total = 60.00. Thereturnstatement sends60.00back, somy_totalnow holds60.00.my_total = 60.00✓ - 5
Step 5 — Reuse the Function
Because we usedreturn, we can now reuse the result. We can print it, compare it to our budget, or even split it among friends:print(f"You owe: ${my_total}")per_person = my_total / 4print(f"Split 4 ways: ${per_person}")Output:You owe: $60.0Split 4 ways: $15.0One function, many uses — that's the power of return values!
SECTION 7
Common Patterns & Pitfalls
As you start writing more functions, you'll encounter recurring patterns that work well and common pitfalls that trip up even experienced students. The table below summarizes the most important ones.
| Pattern / Pitfall | Code Example | Why It Matters |
|---|---|---|
| ✓ Return and print separately | result = add(3, 4)
print(result) | Keeps the function reusable; display is separate from computation. |
| ✓ Chain function calls | total = add(multiply(3, 4), 5) | Return values can be passed directly as arguments to other functions. |
| ✓ Use default parameters | def greet(name, msg="Hello"): | Makes parameters optional; increases flexibility without breaking existing calls. |
| ✗ Printing instead of returning | def add(a, b):
print(a + b) | The value vanishes — can't be stored or reused. The function returns None. |
| ✗ Forgetting to capture the return | add(3, 4) # no variable! | The function runs but the return value is discarded. It's like computing an answer and throwing it away. |
| ✗ Code after return | return total
print("Done") # never runs | return exits the function immediately. Any code below it is unreachable. |
Common patterns and pitfalls with parameters and return values
KEY TAKEAWAY
return as handing someone a letter, and print() as shouting the message out loud. If you shout it, everyone hears it once, but nobody has a copy to read later. If you hand them the letter, they can read it whenever they want, copy it, or pass it along to someone else. Return gives your program a letter; print gives it a shout.SECTION 8
Connection to Advanced Concepts
Parameters and return values are the foundation for nearly every advanced programming concept you'll encounter. Once you're comfortable with these basics, here's where the road leads.
| What You Know Now | What's Coming Next |
|---|---|
| Functions with fixed parameters | Variable-length arguments — using *args and **kwargs to accept any number of inputs |
| Returning a single value | Returning multiple values — Python lets you return tuples, like return min_val, max_val |
| Calling one function at a time | Function composition — piping the return value of one function into another to build complex pipelines |
| Writing standalone functions | Methods in classes — functions attached to objects in Object-Oriented Programming, which use self as an implicit parameter |
| Functions that return data | Functions that return functions — higher-order functions, decorators, and closures enable powerful abstractions |
From basics to advanced function concepts
Every one of these advanced topics depends on the core idea you learned today: functions accept inputs through parameters and produce outputs through return values. Master this concept now, and everything that follows will feel like a natural extension rather than a completely new idea.
SECTION 9
Practice Problems
Question 1: CONCEPTUAL
def square(n):
print(n * n)
They then write result = square(5) and try to compute result + 10. What happens, and why?Show answer
square(5) is called, the number 25 appears on the screen because of print(). However, the function has no return statement, so it returns None by default. The variable result is assigned None. When Python tries to evaluate None + 10, it raises a TypeError because you cannot add an integer to NoneType. The fix is to replace print(n * n) with return n * n.Question 2: BASIC CALCULATION
to_celsius that takes a temperature in Fahrenheit as a parameter and returns the equivalent temperature in Celsius. The formula is: C = (F − 32) × 5 / 9. Then show how to call the function with 98.6 and store the result.Show answer
def to_celsius(fahrenheit):
return (fahrenheit - 32) * 5 / 9
To call it and store the result: body_temp = to_celsius(98.6). Inside the function, Python computes (98.6 - 32) * 5 / 9 = 66.6 * 5 / 9 = 37.0. The return value 37.0 is stored in body_temp. Because we used return instead of print, we can now use body_temp in further calculations or comparisons.Question 3: INTERMEDIATE
is_passing that takes two parameters: a student's score and a threshold (with a default value of 60). The function should return True if the score is greater than or equal to the threshold, and False otherwise. Show two different calls: one using the default threshold and one overriding it to 70.Show answer
def is_passing(score, threshold=60):
return score >= threshold
Call with default threshold: result1 = is_passing(65) → returns True because 65 ≥ 60. Call with custom threshold: result2 = is_passing(65, 70) → returns False because 65 < 70. The default parameter threshold=60 makes the function flexible — it works with a standard passing grade but can be customized for stricter requirements. The comparison operator >= already produces a boolean, so there's no need for an if/else.Question 4: APPLIED
apply_discount(price, percent) which returns the discounted price, and add_tax(price, tax_rate) which returns the price with tax added. Then show how to chain both functions together to find the final price of a $80 item with a 25% discount and 8% sales tax.Show answer
def apply_discount(price, percent):
return price - (price * percent / 100)
def add_tax(price, tax_rate):
return price * (1 + tax_rate / 100)
Chaining them together: final = add_tax(apply_discount(80, 25), 8). First, apply_discount(80, 25) returns 60.0. That return value becomes the first argument to add_tax, which computes 60.0 * 1.08 = 64.8. This chaining is only possible because both functions use return — the output of one becomes the input of the next.Question 5: CRITICAL THINKING
def mystery(a, b):
if a > b:
return a
print(b)
What does mystery(10, 5) return? What does mystery(3, 7) return? Explain why this function is poorly designed, and rewrite it so it always returns the larger of the two values.Show answer
mystery(10, 5) returns 10 because the condition a > b is True, and the function hits return a. However, mystery(3, 7) prints 7 to the screen but returns None because the else path has no return statement. This is a dangerous inconsistency: the function sometimes returns a usable integer and sometimes returns None, which will cause unexpected errors. A corrected version:
def larger(a, b):
if a > b:
return a
return b
Now both paths use return, so the function always produces a usable value. This highlights an important principle: every code path through your function should end with a return statement.SUMMARY
Lesson Summary
Summary
In this lesson, you learned that parameters are the input variables listed in a function's definition, while arguments are the actual values passed in when the function is called. The return value is the output a function sends back to the calling code using the return keyword, allowing the result to be stored in a variable, used in calculations, or passed into other functions.
The most critical distinction is between returning and printing: return sends data back into the program for further use, while print() displays data on the screen and discards it. Functions without a return statement give back None. By combining parameters and return values, you create reusable, modular functions — the building blocks of every well-organized Python program.