Day 5: Functions — Reusable Building Blocks
🐍 Day 5: Functions — Reusable Building Blocks
1. Learning Objectives
By the end of Day 5, you will be able to:
- Define your own functions using
def - Pass data into functions via parameters and arguments
- Send data back from functions with
return - Understand scope — where variables live and where they can be accessed
- Distinguish between local and global variables
- Refactor repetitive code into clean, reusable functions
2. Concept Explanation
2.1 Why Functions? — Code That You Write Once, Use Forever
So far, your code has been linear — top to bottom, executing every line. But what if you need to calculate BMI ten times? Rewrite the formula each time? No!
Functions are named blocks of code that you can call whenever you need them. They solve three major problems:
| Problem | Without Functions | With Functions |
|---|---|---|
| Repetition | Copy-paste code → bugs multiply | Write once, call many times |
| Readability | 200+ line scripts, hard to follow | Small, named, understandable pieces |
| Maintainability | Change formula = hunt down every copy | Change one function, fix everywhere |
Think of functions like kitchen appliances. You don't reinvent a blender every time you need one — you just turn it on.
2.2 def — Defining a Function
def greet():
print("Hello!")
print("Welcome to Python.")
defkeyword tells Python: "I'm defining a function."greetis the function name (lowercase, snake_case).():parentheses — we'll add parameters inside them soon. Even when empty, they're required.- Indented block — the function's body, executed when called.
Calling a function:
greet() # Runs the function
greet() # Runs it again
Output:
Hello!
Welcome to Python.
Hello!
Welcome to Python.
💡 Nothing happens unless you call the function. Defining it is like writing a recipe — you still have to cook it!
2.3 Parameters & Arguments — Passing Data In
Functions become powerful when they accept data.
def greet_person(name): # 'name' is a parameter
print(f"Hello, {name}!")
greet_person("Alice") # "Alice" is an argument
greet_person("Bob") # "Bob" is an argument
Output:
Hello, Alice!
Hello, Bob!
Terminology:
- Parameter: The variable inside the function definition (e.g.,
name). - Argument: The actual value you pass when calling (e.g.,
"Alice").
Multiple parameters:
def describe_person(name, age, city):
print(f"{name} is {age} years old and lives in {city}.")
describe_person("Maria", 28, "Manila")
describe_person("Carlos", 35, "Cebu")
Order matters! Arguments are assigned positionally:
describe_person(28, "Maria", "Manila") # Wrong order — 28 is now 'name'!
You can also use keyword arguments (named arguments) to swap order safely:
describe_person(age=28, city="Manila", name="Maria") # Works, order irrelevant
2.4 return — Sending Data Back
print() shows something to the user. return sends a value back to the caller — the real powerhouse of functions.
def add(a, b):
return a + b
result = add(3, 5) # Capture the returned value
print(result) # 8
print(add(10, 20)) # 30 — can use directly
print(result * 2) # 16 — result holds the number, not None
Without return, a function returns None implicitly:
def bad_add(a, b):
print(a + b) # Shows the sum, does NOT return it
x = bad_add(3, 5) # prints 8, but x becomes None
print(x) # None
print(x * 2) # TypeError: unsupported operand type(s) for *: 'NoneType'
Key rules:
returnimmediately exits the function — code after it won't run.- A function can return multiple values as a tuple:
def min_max(a, b):
if a > b:
return b, a # returns a tuple (min, max)
return a, b
low, high = min_max(10, 20)
print(low, high) # 10, 20
2.5 Scope — Where Variables Live
Scope determines where a variable can be accessed.
Local scope: Variables defined inside a function belong to that function. They're born when the function runs and die when it ends.
def calculate():
x = 10 # local variable
print(x) # works fine inside the function
calculate()
print(x) # NameError: name 'x' is not defined
Global scope: Variables defined outside all functions are global. They're visible everywhere — but modifying them inside a function requires the global keyword.
score = 0 # global variable
def add_point():
global score # tell Python we mean the global 'score'
score += 1
add_point()
print(score) # 1
The LEGB Rule — Python looks for a variable name in this order:
- Local — inside the current function
- Enclosing — in outer functions (closures, later topic)
- Global — at the module level
- Built-in — like
print,len,type
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print(x) # prints "local" (Local first)
inner()
print(x) # prints "enclosing" (Enclosing second)
outer()
print(x) # prints "global" (Global third)
2.6 Default Parameter Values
You can give parameters a fallback value when no argument is passed:
def greet(name="friend"):
print(f"Hello, {name}!")
greet("Alice") # Hello, Alice!
greet() # Hello, friend! (uses default)
Important quirk — mutable defaults: Avoid using mutable objects like lists as defaults; use None and create the object inside the function.
# BAD: Default list persists across calls
def add_item(item, lst=[]):
lst.append(item)
return lst
print(add_item(1)) # [1]
print(add_item(2)) # [1, 2] — same list!
# GOOD:
def add_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
2.7 Docstrings — Documenting Your Functions
A docstring (triple-quoted string right after def) describes what a function does. It's accessible via help().
def bmi(weight_kg, height_m):
"""Calculate Body Mass Index.
Args:
weight_kg: weight in kilograms
height_m: height in meters
Returns:
BMI value (float)
"""
return weight_kg / (height_m ** 2)
help(bmi) # Displays the docstring
Always document your functions — your future self will thank you.
2.8 Common Mistakes
| Mistake | Why it happens |
|---|---|
Forgetting parentheses when calling: greet instead of greet() |
Just references the function object, doesn't run it |
| Mixing up parameter order | Positional arguments — swap unintended |
Using print() instead of return |
print shows, return gives back — different purposes |
Modifying a global without global |
Creates a local variable with the same name (shadowing) |
Missing indentation after def |
Functions must have an indented body |
3. Code Examples
Example 1: BMI Calculator as a Function
def calculate_bmi(weight, height):
"""Return BMI value."""
return weight / (height ** 2)
def bmi_category(bmi_value):
"""Return weight category based on BMI."""
if bmi_value < 18.5:
return "Underweight"
elif bmi_value < 25:
return "Normal"
elif bmi_value < 30:
return "Overweight"
else:
return "Obese"
# Usage
w = float(input("Weight (kg): "))
h = float(input("Height (m): "))
bmi = calculate_bmi(w, h)
print(f"Your BMI is {bmi:.1f} — {bmi_category(bmi)}")
Example 2: Validate Input with a Function
def get_positive_int(prompt):
"""Keep asking until user enters a positive integer."""
while True:
value = int(input(prompt))
if value > 0:
return value
print("Please enter a positive number.")
age = get_positive_int("Enter your age: ")
print(f"Age: {age}")
Example 3: Function with Multiple Returns
def arithmetic_ops(a, b):
"""Return sum, difference, product, and quotient."""
return a + b, a - b, a * b, a / b
s, d, p, q = arithmetic_ops(10, 3)
print(f"Sum: {s}, Diff: {d}, Prod: {p}, Quot: {q}")
4. Hands-On Exercises
Exercise 1: Simple Greeter
Write a function greet_user(name) that prints "Welcome, [name]!". Call it with three different names.
Exercise 2: Rectangle Calculator
Write a function rectangle_area(length, width) that returns the area. Write another rectangle_perimeter(length, width) that returns the perimeter. Ask the user for length and width, then display both results.
Exercise 3: Temperature Converter (revisited)
Write a function celsius_to_fahrenheit(c) that returns the converted temperature. Then write a program that asks for a Celsius value, calls the function, and prints the result.
Exercise 4: Maximum of Three (with function)
Write a function max_of_three(a, b, c) that returns the largest of three numbers. Do not use the built-in max(). Test it with user input.
Exercise 5: Even/Odd Tester
Write a function is_even(n) that returns True if n is even, False otherwise. Use it to print whether a user-entered number is even or odd. (Make sure your function only returns a boolean — let the caller decide what to print.)
5. Applied Challenge Task 🏗️
Mini Banking System
Create three functions that simulate a simple bank account:
deposit(balance, amount)— adds amount to balance, shows new balance, returns updated balancewithdraw(balance, amount)— subtracts amount from balance if sufficient funds exist; otherwise prints an error. Returns updated balance.check_balance(balance)— prints the current balance
Then write a main program that:
- Starts with a balance of $0
- Repeatedly shows a menu:
[D]eposit, [W]ithdraw, [C]heck Balance, [Q]uit - Calls the appropriate function based on user choice
- Loops until the user quits
Example run:
=== MINI BANK ===
Balance: $0.00
[D]eposit [W]ithdraw [C]heck [Q]uit
> D
Enter amount: 500
Deposited $500.00. New balance: $500.00
> W
Enter amount: 200
Withdrew $200.00. New balance: $300.00
> C
Current balance: $300.00
> Q
Goodbye!
Stretch goals:
- Add a pin system (hardcoded PIN, validate before any transaction)
- Add transaction history (store each action in a list — tomorrow's topic, but you can try!)
- Use
globalsparingly — think about passing and returning balance instead
6. Brief Review Summary
| Concept | Key Points |
|---|---|
def |
Creates a named, reusable block of code |
| Parameter | Variable in function definition that receives data |
| Argument | Actual value passed during function call |
return |
Sends a value back to caller; exits function |
None |
Default return value when no return statement |
| Scope | Where variables can be accessed — Local, Enclosing, Global, Built-in |
| Default values | def f(x=10): — provides fallback |
| Docstrings | Document your function with triple-quoted string |
7. Preview of Next Topic — Day 6
Tomorrow we start working with Python's most versatile container:
- Lists — ordered, mutable collections
- Tuples — ordered, immutable collections
- List operations — indexing, slicing, appending, removing
- Iterating over lists with loops (which you now understand!)
🎯 Your Action Items for Day 5:
- ✅ Complete all 5 exercises
- ✅ Complete the Mini Banking System challenge
- ✅ Experiment with
returnvsprint— intentionally break things to see the difference - ✅ Write a docstring for every function you create today
Comments
Post a Comment
Leave us your comments here...