BeginnerPython ยท Lesson 6

Functions

Define reusable functions with parameters, return values, default arguments, and *args/**kwargs

Defining Functions

def greet():
    print("Hello, World!")

greet()  # Hello, World!

Parameters and Arguments

def greet(name):
    print(f"Hello, {name}!")

greet("Alice")    # Hello, Alice!
greet("Bob")      # Hello, Bob!

Return Values

def add(a, b):
    return a + b

result = add(3, 5)
print(result)  # 8

# Return multiple values (as a tuple):
def min_max(numbers):
    return min(numbers), max(numbers)

lo, hi = min_max([3, 1, 4, 1, 5, 9])
print(lo, hi)  # 1 9

Default Arguments

def power(base, exponent=2):
    return base ** exponent

print(power(3))      # 9  (uses default exponent=2)
print(power(3, 3))   # 27

# Default mutable arguments โ€” GOTCHA!
def append_to(item, lst=[]):    # BAD: shared across calls
    lst.append(item)
    return lst

def append_to_safe(item, lst=None):  # GOOD
    if lst is None:
        lst = []
    lst.append(item)
    return lst

Keyword Arguments

def describe_pet(name, animal="dog"):
    print(f"{name} is a {animal}")

describe_pet("Rex")                   # Rex is a dog
describe_pet("Whiskers", "cat")       # Whiskers is a cat
describe_pet(animal="fish", name="Nemo")  # Nemo is a fish

*args and **kwargs

# *args โ€” variable number of positional arguments
def total(*numbers):
    return sum(numbers)

print(total(1, 2, 3, 4, 5))  # 15

# **kwargs โ€” variable number of keyword arguments
def user_info(**details):
    for key, value in details.items():
        print(f"{key}: {value}")

user_info(name="Alice", age=30, city="NYC")

# Combining all types:
def func(required, *args, default=10, **kwargs):
    print(required, args, default, kwargs)

func(1, 2, 3, default=99, x="hello")
# 1 (2, 3) 99 {'x': 'hello'}

Keyword-Only and Positional-Only Arguments

# Keyword-only (after *)
def connect(host, *, port=80, ssl=False):
    print(f"{host}:{port} ssl={ssl}")

connect("example.com", port=443, ssl=True)
# connect("example.com", 443)  # TypeError!

# Positional-only (before /)
def circle_area(radius, /):
    import math
    return math.pi * radius ** 2

circle_area(5)
# circle_area(radius=5)  # TypeError!

Docstrings

def factorial(n):
    """
    Calculate the factorial of n.

    Args:
        n (int): Non-negative integer

    Returns:
        int: n! (n factorial)

    Raises:
        ValueError: If n is negative
    """
    if n < 0:
        raise ValueError("n must be non-negative")
    if n == 0:
        return 1
    return n * factorial(n - 1)

help(factorial)  # shows the docstring

Lambda Functions

square = lambda x: x ** 2
print(square(5))  # 25

# Common use with sorted, map, filter:
nums = [3, 1, 4, 1, 5, 9, 2, 6]
sorted_nums = sorted(nums, key=lambda x: -x)  # descending
print(sorted_nums)  # [9, 6, 5, 4, 3, 2, 1, 1]

pairs = [(1, 'b'), (3, 'a'), (2, 'c')]
pairs.sort(key=lambda p: p[1])
print(pairs)  # [(3, 'a'), (1, 'b'), (2, 'c')]

Exercises

Exercise 1: Fibonacci

Write a function fibonacci(n) that returns the nth Fibonacci number (0-indexed).

Solution:

def fibonacci(n):
    if n <= 0:
        return 0
    if n == 1:
        return 1
    a, b = 0, 1
    for _ in range(2, n + 1):
        a, b = b, a + b
    return b

for i in range(10):
    print(fibonacci(i), end=" ")
# 0 1 1 2 3 5 8 13 21 34

Exercise 2: Recursive Factorial

Write a recursive function for factorial.

Solution:

def factorial(n):
    return 1 if n <= 1 else n * factorial(n - 1)

print(factorial(10))  # 3628800

Exercise 3: Flexible Calculator

Write a function calculate(operation, *numbers) supporting "add", "multiply", "max", "min".

Solution:

def calculate(operation, *numbers):
    if operation == "add":
        return sum(numbers)
    elif operation == "multiply":
        result = 1
        for n in numbers:
            result *= n
        return result
    elif operation == "max":
        return max(numbers)
    elif operation == "min":
        return min(numbers)
    else:
        raise ValueError(f"Unknown operation: {operation}")

print(calculate("add", 1, 2, 3, 4))        # 10
print(calculate("multiply", 2, 3, 4))       # 24
print(calculate("max", 5, 3, 8, 1))         # 8