Lesson 02
Python Function Definition — 4 Approaches with Examples
Master four Python function styles: input from the call or inside the body, print vs return, tuple packing, and the production pattern used in APIs.
What you will learn
- Function anatomy as a machine: input → process → output
- Formal parameters vs local variables
- All 4 input/output approaches
- Returning multiple values with tuple packing
- When to use each approach in a real ATM-style example
The big idea
Master the four ways Python functions receive input and produce output. Every function is still the same machine: two parts, three phases.
Remember:
defcreates the function. The body runs only when called.
You already met this idea on the Functions overview. This lesson is the deep dive: where input comes from and where output goes.
Function anatomy — think of a machine
| Phase | Purpose | Example |
|---|---|---|
| Input | Receive values | a, b |
| Process | Perform logic | c = a + b |
| Output | Send or show the result | return c or print(c) |
def add(a, b): # INPUT
c = a + b # PROCESS
return c # OUTPUTFormal parameters vs local variables
This is a favorite interview question.
def sumop(a, b): # a, b → formal parameters (function heading)
c = a + b # c → local variable (function body)
return c| Type | Lives where? | Purpose |
|---|---|---|
| Formal parameter | Function heading | Receives values from the call |
| Local variable | Function body | Stores a temporary result |
Both exist only inside the function. Accessing c after sumop returns raises NameError.
The 4 function approaches
The four approaches are combinations of where input comes from and where output goes.
Approach 1 — Input from call → return to call
Most important. This is the style used in almost every production application.
# ApproachEx1.py — INPUT from call · PROCESS in body · RESULT back to call
def sumop(a, b): # a, b → formal parameters
c = a + b
return c # c → local variable, sent back
print("type of sumop =", type(sumop)) # <class 'function'>
k, v = 10.0, 20.0
res = sumop(k, v)
print("Sum({}, {}) = {}".format(k, v, res))Output:
type of sumop = <class 'function'>
Sum(10.0, 20.0) = 30.0Memory trick: Call gives → return comes back.
Use this for utilities, APIs, ML models, and reusable business logic. Same input always gives the same output — easy to test: assert sumop(2, 3) == 5.
Approach 2 — Input inside → print inside
A self-contained function. The caller just writes sumop() with no arguments.
# ApproachEx2.py — input and output both inside the body
def sumop():
a = 5.0 # terminal version: float(input("Enter First Value:"))
b = 3.0
c = a + b
print("Sum({}, {}) = {}".format(a, b, c))
sumop()Output:
Sum(5.0, 3.0) = 8.0Best for quick scripts and console programs. Harder to test because the function prints instead of returning a value.
Approach 3 — Input from call → print inside
Useful when the function is responsible for displaying information. Data comes from outside; formatting stays inside.
# ApproachEx3.py — params from call · print inside · no return
def sumop(k, v):
r = k + v
print("Sum({}, {}) = {}".format(k, v, r))
k, v = 15.0, 5.0
sumop(k, v)Output:
Sum(15.0, 5.0) = 20.0There is no return. The function only displays output. print(sumop(15, 5)) would also print None.
Approach 4 — Input inside → return to call
Internal input with reusable output. The caller decides what to do with the result.
# ApproachEx4.py — input inside · return multiple values (tuple)
def sumop():
a, b = 4.0, 6.0
c = a + b
return a, b, c # packed into a tuple automatically
k, v, r = sumop() # unpack
print("Sum({}, {}) = {}".format(k, v, r))
res = sumop() # res is <class 'tuple'>
print("Sum({}, {}) = {}".format(res[0], res[1], res[2]))
print("Sum({}, {}) = {}".format(res[-3], res[-2], res[-1]))Output:
Sum(4.0, 6.0) = 10.0
Sum(4.0, 6.0) = 10.0
Sum(4.0, 6.0) = 10.0Multiple return values — tuple packing
A hidden feature of Python: comma-separated return packs a tuple.
def values():
return 4, 6, 10
a, b, c = values()
print(a) # 4
print(c) # 10
print(type(values())) # <class 'tuple'>Side-by-side comparison
| Approach | Input | Output | Best use |
|---|---|---|---|
| 1 | Function call | return |
Production code, APIs, tests |
| 2 | Inside body | print |
Console scripts |
| 3 | Function call | print |
Reports / display helpers |
| 4 | Inside body | return (often a tuple) |
Data collection |
Learn Approach 1 first — it is the standard in professional Python.
def add1(a, b):
return a + b
def add2():
x, y = 10, 20
print("Approach 2:", x + y)
def add3(a, b):
print("Approach 3:", a + b)
def add4():
x, y = 10, 20
return x + y
print("Approach 1:", add1(10, 20))
add2()
add3(10, 20)
print("Approach 4:", add4())Real-world example — ATM balance
Approach 1 is ideal: the function does not know where the money comes from. It only performs logic.
def withdraw(balance, amount):
if amount <= balance:
return balance - amount
return balance
new_balance = withdraw(5000, 1200)
print(new_balance) # 3800Why this is good design:
- Input comes from the caller
- The function has one responsibility
- The result is returned for further use (save, log, API response)
This is the same pattern used in FastAPI services, ML preprocessing, and business logic.
Common mistakes
1. Calling before defining → NameError
# add(2, 3) # NameError — always define first
def add(a, b):
return a + b
print(add(2, 3)) # 52. Wrong number of arguments → TypeError
def add(a, b):
return a + b
# add(5) # TypeError: add() missing 1 required positional argument: 'b'
print(add(5, 3))3. Using a local variable outside → NameError
def calc():
total = 10
return total
# print(total) # NameError — total lives inside calc() only
print(calc()) # 104. Forgetting return → None
def add(a, b):
a + b # computed, then thrown away
print(add(2, 3)) # None
def add_ok(a, b):
return a + b
print(add_ok(2, 3)) # 5print() shows a value on screen. It does not replace return. The caller cannot reuse a printed number.
Practice in the playground
The playground above already runs all four approaches plus the ATM example. Try:
- Change
sumop(10, 20)tosumop(100, 25)— confirm Approach 1 prints125. - Add
print(show_sum(15, 5))and notice the extraNone. - Change the ATM call to
withdraw(5000, 9000)— balance should stay5000.
Next: Parameters and Arguments — five ways to pass data into these functions.
Loading playground…
Check your understanding
Function approaches quiz
Which approach is used most often in production applications?
1 / 10