Functions
A function packages a transformation behind a name, so the code that uses it only needs to know its inputs and outputs, not how it works inside.
By the end of this lesson, you can
- Write a function with parameters and a return value that packages a small transformation
- Trace a function call, showing how arguments map to parameters and how the return value flows back to the caller
- Explain the difference between a function that returns a value and one that only prints
Why it matters
Once a transformation is useful more than once — converting a temperature, calculating a price, validating an answer — copying its code every place it’s needed becomes a maintenance problem: fix a bug in one copy, and every other copy still has it. A function gives a sequence of steps a name, so it can be reused, and so the code that calls it only needs to know what goes in and what comes back out — not how the inside works.
Mental model
A function has an interface: parameters (the named inputs it expects) and a return value (the output it sends back). Everything between them is a detail the caller doesn’t need to think about.
def celsius_to_fahrenheit(celsius):
fahrenheit = celsius * 9 / 5 + 32
return fahrenheit
print(celsius_to_fahrenheit(0))
print(celsius_to_fahrenheit(100))32.0
212.0celsius is a parameter — a placeholder name the function uses for
whatever value it’s given. return sends a value back to wherever the
function was called, to be used just like any other expression.
Trace it
Tracing a function call means following the value as it moves in
through the parameter and back out through return:
| Call | celsius (parameter) | fahrenheit (inside the function) | Returns |
|---|---|---|---|
| celsius_to_fahrenheit(0) | 0 | 0 × 9 / 5 + 32 = 32.0 | 32.0 |
| celsius_to_fahrenheit(100) | 100 | 100 × 9 / 5 + 32 = 212.0 | 212.0 |
Each call gets its own fresh celsius and fahrenheit — the two calls
don’t interfere with each other at all, even though they use the same
names.
Check your understanding
Or reveal the answer without checking
Answer:9
double(4) evaluates to 8 (returned, not printed), and that value is used directly in the expression double(4) + 1, which is 9. result refers to 9.
Or reveal the answer without checking
Answer:Automatically returns None
A function always returns something. If it has no return statement, Python automatically returns None — printing inside a function has no effect on what it returns.
Practice: warm-up
Trace three calls to this function — write down the parameter, what happens inside, and the return value — before revealing the answer.
def area(width, height):
return width * height
Calls: area(3, 4), area(10, 2), area(5, 5).
Stuck? Reveal one hint at a time.
Hint 1
Each call gives width and height fresh values — write down what each parameter refers to for that call.
Hint 2
The function has one line: multiply the two parameters and return the result.
Reveal the trace
Try the problem yourself before reading this. There is often more than one reasonable approach — treat this as one worked example, not the only correct answer.
area(3, 4) -> width=3, height=4 -> returns 12
area(10, 2) -> width=10, height=2 -> returns 20
area(5, 5) -> width=5, height=5 -> returns 25Practice: apply it
This function is supposed to report whether a number is even, but using
it always seems to fail. (number % 2 is Python’s remainder operator —
it evaluates to the remainder after dividing by 2, so it’s 0 for even
numbers and 1 for odd ones.)
def is_even(number):
if number % 2 == 0:
print(True)
else:
print(False)
if is_even(4):
print("even!")
else:
print("odd!")
Or reveal the answer without checking
Answer:odd!
is_even(4) prints True inside itself, but has no return statement — so it returns None to the caller. The outer if treats None as falsy, so the else branch runs and prints 'odd!', even though 4 is even.
Modification challenge: fix is_even so if is_even(4): correctly
takes the if branch, by replacing the print calls inside it with
return statements.
Summary
- A function packages steps behind a name; its parameters are the inputs it expects, and
returnis the value it sends back. - Each call to a function gets its own fresh copies of its parameters — separate calls never interfere with each other.
- Printing inside a function only shows something on screen; it does not send a value back to the caller. Without an explicit
return, a function always returnsNone. - Tracing a call means following a value in through the parameters and back out through the return value.