Learning Goals
3 minBy the end of this lesson you can:
- Define a function that takes one or more parameters.
- Use the difference between a parameter and an argument correctly.
- Explain why the order of arguments matters, and what happens when you get it wrong.
- Pass variables — not just literal values — into a function.
Warm-Up · Almost the Same
5 minNia wrote three functions for her class register program:
def greet_Mia(): print("Good morning, Mia!") def greet_wei_jie(): print("Good morning, Leo!") def greet_firdaus(): print("Good morning, Firdaus!")
Two questions:
- How much of those three functions is identical, and how much is different?
- A new student joins the class. What must Nia do?
When several functions are the same except for one value, that value should be handed in when you call, not baked into the definition. Anything that changes goes in the brackets.
New Concept · A Blank to Fill In
12 minPut a name inside the brackets of the definition. It is a blank, waiting to be filled at the moment of the call.
def greet(name): """Greet one student by name.""" print("Good morning, " + name + "!") greet("Mia") greet("Leo") greet("Firdaus")
Output
Good morning, Mia! Good morning, Leo! Good morning, Firdaus!
Three functions became one. A new student is now a new call, not a new function.
Two words worth keeping straight:
- A parameter is the name in the definition —
name. It is a promise: "someone will give me this." - An argument is the value at the call —
"Mia". It is the thing actually handed over.
Inside the body, the parameter behaves exactly like a variable. You can join it, compare it, loop over it — anything you would do with a value you typed yourself.
More than one blank. Separate parameters with commas, and fill them in the same order at the call:
def order_line(item, price, qty): """Print one line of a receipt.""" total = price * qty print(f"{qty} x {item:<12} $ {total:.2f}") order_line("Pancake", 1.50, 3) order_line("Hot chocolate", 2.00, 2)
Output
3 x Pancake $4.50 2 x Hot chocolate $4.00
Python does not read your minds or your names — it matches by position. The first argument fills the first parameter, the second fills the second. Call order_line("Hot chocolate", 2, 2.00) and Python cheerfully sells you two dollar worth of two hot chocolate. No error, wrong receipt. Lesson 4 shows how to make calls that cannot be mixed up.
Arguments can be variables too. Anything that is a value can be passed:
student = input("Name: ") greet(student) for pupil in ["Theo", "Zoe", "Nur"]: greet(pupil)
Worked Example · One Card Function, Many Cards
12 minThe greeting-card program from lesson 1's homework, done properly. Type it and run it.
def print_border(width): """Print a border line of the given width.""" print("*" * width) def print_card(message, width): """Print one greeting card with the message centred inside a border.""" print_border(width) print("*" + message.center(width - 2) + "*") print_border(width) print() print_card("Happy Birthday!", 34) print_card("Happy Symmetry!", 34) print_card("Gong Xi Fa Cai!", 34)
Output
********************************** * Happy Birthday! * ********************************** ********************************** * Happy Symmetry! * ********************************** ********************************** * Gong Xi Fa Cai! * **********************************
Two things happened here that are worth naming.
- A function called another function.
print_cardcallsprint_bordertwice. That is completely ordinary, and it is how programs get built: small jobs, combined. - A parameter got passed onwards.
print_cardreceiveswidthand hands it straight toprint_border. Change the number 34 at the bottom and the whole card resizes.
Call print_card(34, "Happy Birthday!") with the arguments the wrong way round. Read the error: AttributeError: 'int' object has no attribute 'center'. Python is telling you it tried to centre a number. Errors like that usually mean the order, not the code inside.
Try It Yourself
13 minWrite show_fahrenheit(celsius) that prints the temperature in both units. Call it for 27, 31 and 35 — a normal week in Tokyo.
Hint
def show_fahrenheit(celsius): """Print a temperature in Celsius and Fahrenheit.""" f = celsius * 9 / 5 + 32 print(f"{celsius}C is {f:.1f}F") show_fahrenheit(27)
Write receipt_line(item, price, qty) that prints one tidy line, then use a for loop over a list of three orders to print a whole receipt. Add a print_total function that takes the total and prints it under a divider.
Hint
orders = [("Pizza", 4.50, 2), ("Iced cocoa", 2.50, 3)] for item, price, qty in orders: receipt_line(item, price, qty)
Unpacking a tuple in the for line gives you three ready-made arguments.
Mini-Challenge 🔥 · Debug: The Receipt That Adds Up Wrong
8 minFirdaus's receipt program runs without a single error message. It is also wrong. His teacher ordered 2 pizza at $4.50 and was charged $9.00 — correct — but the line reads 4 x Pizza.
def receipt_line(item, qty, price):
total = qty * price
print(f"{qty} x {item:<12} $ {total:.2f}")
receipt_line("Pizza", 4.50, 2)
receipt_line("Hot chocolate", 2.00, 3)Two questions. Why is the total right when the quantity is wrong? And why did Python not complain?
Answer
The definition expects (item, qty, price) but the calls pass (item, price, qty). So qty holds 4.50 and price holds 2.
- The total survives because multiplication does not care about order:
4.50 × 2and2 × 4.50are both 9. The bug hides in the one place it does not change the answer. - Python did not complain because both values are numbers, and every operation performed on them is legal. Python checks that operations work, not that they mean what you intended.
Two fixes: swap the arguments at every call, or — better, and the subject of lesson 4 — name them at the call, so receipt_line("Pizza", price=4.50, qty=2) cannot be misread by anyone, including you in a month.
Recap
3 minA parameter is a blank in the definition; an argument is the value that fills it at the call. Several parameters are separated by commas and matched by position, which is why swapped arguments produce wrong answers rather than error messages. Inside the body a parameter is just a variable. Functions may call other functions, and pass their parameters onwards.
Vocabulary Card
- parameter
- The name inside the brackets of a
def. A blank waiting for a value. - argument
- The actual value passed at the call:
greet("Mia"). - positional matching
- First argument fills the first parameter, and so on. Order decides meaning.
- f-string
f"{qty} x {item}"— drops values straight into text, handy for tidy output.
Homework
4 minWrite a menu_board.py for a cafe stall. It needs three functions: one that prints a titled header of any width, one that prints a menu item with its price, and one that prints the closing line. Use them to print a menu of at least five items.
Every value that appears on screen — the shop name, the width, the item, the price — must arrive as an argument. Nothing typed twice inside a function body.
Hint: f"{item:<15}" pads a name to 15 characters so the prices line up in a column.
Sample · menu_board.py
# menu_board.py - every value comes in through the brackets def print_header(shop, width): """Print a centred shop name inside a full-width border.""" print("=" * width) print(shop.center(width)) print("=" * width) def print_item(item, price): """Print one menu line with the price in a right-hand column.""" print(f" {item:<15} $ {price:>5.2f}") def print_footer(message, width): """Print the closing line.""" print("-" * width) print(message.center(width)) print() WIDTH = 34 print_header("CAFE SEBELAH SCHOOL", WIDTH) print_item("Pancake", 1.50) print_item("Pancake telur", 2.50) print_item("Maggi fried", 6.00) print_item("Hot chocolate", 2.00) print_item("Iced cocoa", 2.50) print_footer("Open 24 hours", WIDTH)
The tell-tale sign it is right: changing WIDTH to 50 resizes the header, the divider and the footer together, because all three read the same argument. If one of them stayed 34, that value was typed inside a function instead of passed in.