Learning Goals
3 minBy the end of this lesson you can:
- Write a function with two or three parameters and pass the arguments in the correct order.
- Use keyword arguments (
greet(name="Faiz")) when you want to be explicit or change the order. - Give a parameter a default value with
language="English"so callers can leave it out.
Warm-Up
5 minYou've been calling multi-parameter built-ins for ages without noticing. Look:
print("hi", "there") # two arguments to print "banana".replace("a", "o") # two arguments to replace round(3.14159, 2) # two arguments to round
Two values inside one set of parentheses, separated by commas. That's all there is to it — Python matches the first value to the first parameter, the second value to the second parameter, and so on. Order matters.
Quick prediction game. What does each line print?
print(round(3.7, 0)) print(round(0, 3.7))
Show the answers
4.0 0
round(number, digits) rounds the first argument to the second number of digits. Swapping them is technically legal — Python doesn't crash — but the answer is nonsense. Argument order matters when you have more than one slot.
New Concept · Two Slots, One Default
14 minTwo parameters, comma-separated
def greet(name, language): if language == "Malay": print("Selamat datang,", name + "!") elif language == "Tamil": print("Vanakkam,", name + "!") else: print("Hello,", name + "!")
Two slots: name first, language second. Inside the function, both are just normal variables.
Call with two arguments, in order
greet("Aisyah", "Malay") greet("Priya", "Tamil") greet("Sarah", "English")
Selamat datang, Aisyah! Vanakkam, Priya! Hello, Sarah!
Aisyah went into name, Malay went into language. Swap them and you'd get something silly:
greet("Malay", "Aisyah") # → Hello, Malay! (because "Aisyah" != "Malay")
Keyword arguments · be explicit
Sometimes the order is hard to remember, or you want to skip an argument. Python lets you pass arguments by name:
greet(name="Aisyah", language="Malay") greet(language="Tamil", name="Priya") # order doesn't matter when named
Both work. When you write name="Aisyah" in a call, that's a keyword argument — you're telling Python "put this value in the slot called name, no matter what position it's in".
Default values · let the caller skip
If you wrote language="English" in the def line, you're giving that parameter a default. Callers who don't pass anything for language get the default automatically:
def greet(name, language="English"): if language == "Malay": print("Selamat datang,", name + "!") elif language == "Tamil": print("Vanakkam,", name + "!") else: print("Hello,", name + "!") greet("Aisyah", "Malay") # explicit → Selamat datang, Aisyah! greet("Sarah") # skipped → Hello, Sarah! (default kicks in)
Defaults are a kindness to the caller — "you don't need to remember this one unless you care."
Two rules to memorise
- In the
defline, parameters with defaults must come AFTER parameters without defaults.def greet(language="English", name):is aSyntaxError. - In a call, positional arguments must come BEFORE keyword arguments.
greet(name="Aisyah", "Malay")is aSyntaxError.
Mix them sensibly: greet("Aisyah", language="Malay") is fine — one positional, one keyword, in that order.
Give the most-likely-to-be-skipped parameter a default. Pass the obvious ones positionally; use keyword arguments for anything that would otherwise be confusing.
Worked Example · Receipt Line Printer
13 minThe job
Aunty Mei runs a juice stall. She wants Python to print receipt lines that look like this:
Mango juice x 2 = RM 8.00 Watermelon x 1 = RM 4.00
Each line has an item name, a quantity, and a unit price. Most drinks are RM 4.00 each, so let's make price the default.
Step 1 · The function with three parameters
def print_line(item, qty, price=4.00): total = qty * price print(item, "x", qty, " = RM", total)
Three parameters. The last one has a default — if Aunty doesn't pass a price, the line uses 4.00.
Step 2 · Call it three different ways
print_line("Mango juice", 2) # uses default price 4.00 print_line("Watermelon", 1) # uses default price 4.00 print_line("Avocado smoothie", 1, 7.50) # special price, override the default
Mango juice x 2 = RM 8.0 Watermelon x 1 = RM 4.0 Avocado smoothie x 1 = RM 7.5
Step 3 · A keyword-argument call for clarity
Imagine a new drink at the stall — same default price, but a free promotional quantity. We can keyword-pass qty=0 to make it obvious:
print_line("Lychee sample", qty=0, price=0.00)
Using keyword arguments here makes the call self-documenting. Someone reading the line knows exactly which value is the quantity and which is the price.
Step 4 · The full receipt
Save as receipt.py:
Code
# receipt.py — Aunty Mei's juice receipt def print_header(stall): print("=" * 35) print(stall, "— Today's Receipt") print("=" * 35) def print_line(item, qty, price=4.00): total = qty * price print(item, "x", qty, " = RM", total) # main program print_header("Mei Juice Bar") print_line("Mango juice", 2) print_line("Watermelon", 1) print_line("Avocado smoothie", 1, 7.50) print_line("Lychee sample", qty=0, price=0.00) print("=" * 35)
Sample run
=================================== Mei Juice Bar — Today's Receipt =================================== Mango juice x 2 = RM 8.0 Watermelon x 1 = RM 4.0 Avocado smoothie x 1 = RM 7.5 Lychee sample x 0 = RM 0.0 ===================================
If 80% of items cost RM 4.00, making 4.00 the default saves Aunty Mei from typing the same number 80 times. The 20% of calls that need a different price still work — they just pass it explicitly. Defaults are how libraries you'll use later (pandas, requests, Flask) stay polite — sensible behaviour with zero arguments, every knob still adjustable when you need it.
Try It Yourself
14 minThree tasks. Each adds one new idea — two parameters, then a default, then keyword arguments.
Write a function add(a, b) that prints <a> + <b> = <answer>. Call it with (3, 5), (10, 25), and (100, 200).
Hint
def add(a, b): print(a, "+", b, "=", a + b) add(3, 5) add(10, 25) add(100, 200)
Expected output: 3 + 5 = 8, 10 + 25 = 35, 100 + 200 = 300. The function's body uses both parameters — the inputs really do flow in.
Write final_price(price, discount=0). It should print Final: RM <price minus discount>. Call it as final_price(20) — should print Final: RM 20. Then final_price(20, 5) — should print Final: RM 15.
Hint
def final_price(price, discount=0): print("Final: RM", price - discount) final_price(20) # discount defaults to 0 → Final: RM 20 final_price(20, 5) # discount = 5 → Final: RM 15 final_price(50, 12.50) # works with floats too → Final: RM 37.5
Defaults shine when the "normal" case has no discount. Callers who don't pass one get sensible behaviour; the ones who do, override it.
Write book_room(name, room="Standard", nights=1). It should print <name> booked the <room> room for <nights> night(s).. Call it three times — once with just a name; once with a name and a room; once with all three, but using keyword arguments in a deliberately weird order.
Hint
def book_room(name, room="Standard", nights=1): print(name, "booked the", room, "room for", nights, "night(s).") book_room("Aisyah") book_room("Faiz", "Deluxe") book_room(nights=3, name="Mei", room="Suite")
Expected output: Aisyah → Standard, 1 night; Faiz → Deluxe, 1 night; Mei → Suite, 3 nights. The third call uses three keyword arguments in a different order to the def — Python doesn't care, because each one has a label.
Mini-Challenge · Devraj's Reversed Receipt
8 minDevraj built a receipt printer with parameters in a confusing order. Read it, then fix the bugs.
# devraj_receipt.py — buggy
def line(qty, price=4.00, item):
total = qty * price
print(item, "x", qty, "= RM", total)
line(2, "Mango juice")
line(1, "Watermelon", 4.00)
line("Avocado", 1, 7.50)You'll get a SyntaxError as soon as the file runs. Find and fix two bugs:
- Bug 1. Parameters with defaults must come after parameters without defaults.
price=4.00shouldn't sit betweenqtyanditem. - Bug 2. Devraj's call sites pass the item name in different slots each time. Once the parameter order is fixed, the calls need updating too —
itemfirst, thenqty, then optionalprice.
Show one possible fix
# devraj_receipt.py — fixed def line(item, qty, price=4.00): total = qty * price print(item, "x", qty, "= RM", total) line("Mango juice", 2) line("Watermelon", 1, 4.00) line("Avocado", 1, 7.50)
Defaults at the back is the iron rule. Once that's fixed, the call sites become predictable too: always item, qty, then maybe price. If Devraj really wanted to be flexible at the call sites, he could use keyword arguments — line(qty=2, item="Mango juice") would also work after the fix.
Recap
3 minFunctions with two or more parameters take a comma-separated list of arguments at the call. Python matches them by position by default — first to first, second to second — but you can also pass them by name with keyword arguments like greet(name="Aisyah"). Adding =value after a parameter name in the def gives it a default; callers can then skip it. Two rules to remember: parameters with defaults come last in the def, and positional arguments come before keyword arguments in the call. Next lesson we'll teach functions to send a value back to the caller with return.
Vocabulary Card
- positional argument
- An argument matched to its parameter by position. The first value goes to the first parameter.
- keyword argument
- An argument passed by name:
greet(name="Aisyah"). Order no longer matters. - default value
- A value given to a parameter in the
defline with=. Used when the caller doesn't pass anything for that slot. - argument order rule
- In a call, positional arguments must come before any keyword arguments.
- default order rule
- In a
def, parameters with defaults must come after parameters without defaults.
Homework
4 minCreate a new file greet_anyone.py. Build a polite multilingual greeter driven by one function.
- Define
greet(name, language="English"). Inside, use anif/elif/elseto print:- Malay →
Selamat datang, <name>! - Tamil →
Vanakkam, <name>! - Mandarin →
欢迎, <name>! - anything else (including the default) →
Hello, <name>!
- Malay →
- Make six calls:
greet("Aisyah")greet("Aisyah", "Malay")greet("Priya", "Tamil")greet("Wei", "Mandarin")greet(name="Sarah", language="English")greet(language="Malay", name="Hafiz")
- Notice the last two calls use keyword arguments — and the very last one passes them in reverse order, which Python is perfectly happy with.
Bring greet_anyone.py next class. In PY-L1-29 we teach functions to send a value back: return.
Sample · greet_anyone.py
# greet_anyone.py — multilingual greeter def greet(name, language="English"): if language == "Malay": print("Selamat datang,", name + "!") elif language == "Tamil": print("Vanakkam,", name + "!") elif language == "Mandarin": print("欢迎,", name + "!") else: print("Hello,", name + "!") # main program greet("Aisyah") greet("Aisyah", "Malay") greet("Priya", "Tamil") greet("Wei", "Mandarin") greet(name="Sarah", language="English") greet(language="Malay", name="Hafiz")
The two big wins to notice: (1) greet("Aisyah") still works because language has a sensible default; (2) the very last call swaps the order of the arguments around — keyword arguments are positional-order-proof, which is incredibly handy for functions with many parameters.