- Understand the difference between parameters and arguments
- Create functions with positional and keyword arguments
- Use default parameter values
- Work with *args and **kwargs for flexible functions
Parameters and Arguments
In the previous lesson, our functions were like vending machines with only one button – press it, get the same thing every time. But real vending machines have options! You select what you want, maybe customize your order.
Parameters and arguments give your functions this flexibility. Instead of always saying "Hello!", a greeting function can say "Hello, Alice!" or "Hello, Bob!" – the message changes based on what you provide. This transforms functions from rigid routines into flexible, reusable tools.
Parameters vs Arguments
These terms are often confused. Let's clarify:
Parameters vs Arguments
def greet(name): ← "name" is a PARAMETER
print(f"Hello, {name}!")
greet("Alice") ← "Alice" is an ARGUMENT
greet("Bob") ← "Bob" is an ARGUMENT
PARAMETER = Variable in the function definition
(The placeholder, the parking spot)
ARGUMENT = Value passed when calling the function
(The actual car that parks there)
Think of it like:
• Parameter = A slot labeled "Name" on a form
• Argument = What you write in that slot ("Alice")
Basic Parameters
Single Parameter
def greet(name):
"""Greet a person by name."""
print(f"Hello, {name}!")
# Call with different arguments
greet("Alice") # Output: Hello, Alice!
greet("Bob") # Output: Hello, Bob!
greet("World") # Output: Hello, World!
Multiple Parameters
def introduce(name, age, city):
"""Introduce a person with their details."""
print(f"Meet {name}!")
print(f"Age: {age}")
print(f"From: {city}")
introduce("Alice", 25, "Paris")
Output:
Meet Alice!
Age: 25
From: Paris
Positional Arguments
When you call a function with values in order, they're positional arguments:
def create_email(recipient, subject, body):
print(f"To: {recipient}")
print(f"Subject: {subject}")
print(f"Body: {body}")
# Positional: order matters!
create_email("alice@mail.com", "Hello!", "How are you?")
Order Matters!
Positional Arguments - Order Matters!
def introduce(name, age):
print(f"{name} is {age} years old")
CORRECT ORDER:
introduce("Alice", 25)
Output: "Alice is 25 years old"
WRONG ORDER:
introduce(25, "Alice")
Output: "25 is Alice years old" ← Makes no sense!
Keyword Arguments
You can specify which parameter each value goes to by name:
def create_profile(name, age, city, job):
print(f"Name: {name}")
print(f"Age: {age}")
print(f"City: {city}")
print(f"Job: {job}")
# Keyword arguments - order doesn't matter!
create_profile(age=25, name="Alice", job="Developer", city="Paris")
Benefits of Keyword Arguments
Why Use Keyword Arguments?
Order doesn't matter
create_profile(age=25, name="Alice")
create_profile(name="Alice", age=25) # Same result!
More readable
send_email("a@b.com", "Hi", "Hello") # What's what?
send_email(to="a@b.com", subject="Hi", body="Hello")
Can skip optional parameters
Only provide what you need
Mixing Positional and Keyword
def send_message(recipient, message, urgent=False):
if urgent:
print(f" URGENT to {recipient}: {message}")
else:
print(f"To {recipient}: {message}")
# Positional first, then keyword
send_message("Alice", "Hello!", urgent=True)
# WRONG: Positional after keyword
# send_message(recipient="Alice", "Hello!") # SyntaxError!
Default Parameter Values
Give parameters a default value that's used if no argument is provided:
def greet(name, greeting="Hello"):
"""Greet with customizable greeting."""
print(f"{greeting}, {name}!")
# Without the optional argument
greet("Alice") # Hello, Alice!
# With the optional argument
greet("Alice", "Hi") # Hi, Alice!
greet("Alice", "Good day") # Good day, Alice!
Visual Explanation
Default Parameters
def greet(name, greeting="Hello"):
greeting has default "Hello"
name is required (no default)
greet("Alice")
name="Alice", greeting="Hello" (default used)
greet("Alice", "Hi")
name="Alice", greeting="Hi" (provided value used)
Important Rule: Default Parameters Last!
# CORRECT: Required first, defaults last
def create_user(name, email, role="user", active=True):
pass
# WRONG: Default before required
# def create_user(role="user", name, email): # SyntaxError!
# pass
*args: Variable Positional Arguments
What if you don't know how many arguments you'll receive?
def sum_all(*numbers):
"""Sum any number of values."""
total = 0
for num in numbers:
total += num
return total
print(sum_all(1, 2)) # 3
print(sum_all(1, 2, 3, 4, 5)) # 15
print(sum_all(10)) # 10
print(sum_all()) # 0
How *args Works
*args Explained
def show_args(*args):
print(type(args)) # <class 'tuple'>
print(args)
show_args(1, 2, 3)
args = (1, 2, 3) ← All positional args as a tuple
show_args("a", "b")
args = ("a", "b")
show_args()
args = () ← Empty tuple
Practical Example
def make_sandwich(bread, *fillings):
"""Make a sandwich with any number of fillings."""
print(f" {bread} bread sandwich with:")
for filling in fillings:
print(f" • {filling}")
make_sandwich("Wheat", "Ham", "Cheese", "Lettuce", "Tomato")
Output:
Wheat bread sandwich with:
• Ham
• Cheese
• Lettuce
• Tomato
**kwargs: Variable Keyword Arguments
For an unknown number of named arguments:
def show_info(**kwargs):
"""Display any key-value pairs provided."""
for key, value in kwargs.items():
print(f"{key}: {value}")
show_info(name="Alice", age=25, city="Paris")
Output:
name: Alice
age: 25
city: Paris
How **kwargs Works
**kwargs Explained
def show_kwargs(**kwargs):
print(type(kwargs)) # <class 'dict'>
print(kwargs)
show_kwargs(name="Alice", age=25)
kwargs = {"name": "Alice", "age": 25} ← Dictionary!
show_kwargs()
kwargs = {} ← Empty dictionary
Practical Example
def create_html_element(tag, content, **attributes):
"""Create an HTML element with any attributes."""
attr_string = ""
for key, value in attributes.items():
attr_string += f' {key}="{value}"'
return f"<{tag}{attr_string}>{content}</{tag}>"
# Create various HTML elements
print(create_html_element("p", "Hello World"))
print(create_html_element("a", "Click me", href="https://python.org", target="_blank"))
print(create_html_element("div", "Content", id="main", class_="container"))
Output:
<p>Hello World</p>
<a href="https://python.org" target="_blank">Click me</a>
<div id="main" class_="container">Content</div>
Parameter Order
When combining different types, follow this order:
Correct Parameter Order
def function(positional, default=value, *args, **kwargs):
1 2 3 4
1. Required positional parameters
2. Default parameters
3. *args (variable positional)
4. **kwargs (variable keyword)
Example:
def full_example(name, greeting="Hello", *tags, **options):
pass
Practical Examples
Example 1: Flexible Print Function
def fancy_print(*messages, separator=" | ", end="\n"):
"""Print messages with custom separator."""
print(separator.join(messages), end=end)
fancy_print("Python", "is", "awesome")
# Output: Python | is | awesome
fancy_print("A", "B", "C", separator=" → ")
# Output: A → B → C
fancy_print("No newline", end="!!!\n")
# Output: No newline!!!
Example 2: Configuration Function
def configure_app(app_name, debug=False, **settings):
"""Configure an application with any settings."""
print(f" Configuring {app_name}")
print(f" Debug mode: {'ON' if debug else 'OFF'}")
if settings:
print(" Settings:")
for key, value in settings.items():
print(f" {key}: {value}")
configure_app("MyApp", debug=True,
database="PostgreSQL",
cache="Redis",
port=8080)
Example 3: Calculator with Multiple Operations
def calculate(operation, *numbers):
"""Perform calculation on any number of values."""
if not numbers:
return 0
if operation == "sum":
return sum(numbers)
elif operation == "product":
result = 1
for n in numbers:
result *= n
return result
elif operation == "average":
return sum(numbers) / len(numbers)
else:
return "Unknown operation"
print(calculate("sum", 1, 2, 3, 4, 5)) # 15
print(calculate("product", 2, 3, 4)) # 24
print(calculate("average", 10, 20, 30)) # 20.0
Key Takeaways
Remember These Points
Parameter = variable in definition (the slot)
Argument = value when calling (what fills the slot)
Positional arguments: order matters
greet("Alice", 25)
Keyword arguments: specify by name
greet(name="Alice", age=25)
Default parameters: provide fallback values
def greet(name, greeting="Hello")
*args: accept any number of positional arguments
**kwargs: accept any number of keyword arguments
Order: positional, defaults, *args, **kwargs
What's Next?
Your functions can now receive input! But what about sending data back? In the next lesson, we'll explore return values – how functions can calculate results and give them back to the caller for further use.
