Python Basics — Functions Practice Exercises

3 minute read

Functions — Practice Exercises

Test your understanding of defining functions, parameters, return values, *args/**kwargs, and docstrings.


Exercise 1 — Temperature Converter

Write a function celsius_to_fahrenheit(celsius) that converts Celsius to Fahrenheit using the formula F = C × 9/5 + 32. Then write fahrenheit_to_celsius(fahrenheit) for the reverse conversion.

print(celsius_to_fahrenheit(0))    # 32.0
print(celsius_to_fahrenheit(100))  # 212.0
print(fahrenheit_to_celsius(98.6)) # 37.0
Show Solution
def celsius_to_fahrenheit(celsius: float) -> float:
    """Convert Celsius to Fahrenheit."""
    return celsius * 9 / 5 + 32

def fahrenheit_to_celsius(fahrenheit: float) -> float:
    """Convert Fahrenheit to Celsius."""
    return (fahrenheit - 32) * 5 / 9

print(celsius_to_fahrenheit(0))    # 32.0
print(celsius_to_fahrenheit(100))  # 212.0
print(fahrenheit_to_celsius(98.6)) # 37.0

Exercise 2 — Flexible Calculator

Create a function calculate(*args, operation="add") that:

  • Takes any number of numeric arguments
  • Supports operation values: "add", "multiply", "max", "min"
  • Returns the result
print(calculate(1, 2, 3))                       # 6
print(calculate(2, 3, 4, operation="multiply"))  # 24
print(calculate(5, 1, 8, 3, operation="max"))    # 8
Show Solution
def calculate(*args, operation="add"):
    """Perform a calculation on variable number of arguments.

    Args:
        *args: Numbers to use in the calculation.
        operation: One of 'add', 'multiply', 'max', 'min'.

    Returns:
        Result of the operation.
    """
    if not args:
        return 0

    if operation == "add":
        return sum(args)
    elif operation == "multiply":
        result = 1
        for num in args:
            result *= num
        return result
    elif operation == "max":
        return max(args)
    elif operation == "min":
        return min(args)
    else:
        return f"Unknown operation: {operation}"

print(calculate(1, 2, 3))                       # 6
print(calculate(2, 3, 4, operation="multiply"))  # 24
print(calculate(5, 1, 8, 3, operation="max"))    # 8

Exercise 3 — User Profile Builder

Write a function build_profile(first, last, **kwargs) that returns a dictionary with keys first_name, last_name, and any additional keyword arguments.

profile = build_profile("Ravi", "Kumar", age=28, city="Bangalore", role="developer")
print(profile)
# {'first_name': 'Ravi', 'last_name': 'Kumar', 'age': 28, 'city': 'Bangalore', 'role': 'developer'}
Show Solution
def build_profile(first: str, last: str, **kwargs) -> dict:
    """Build a user profile dictionary.

    Args:
        first: First name.
        last: Last name.
        **kwargs: Additional profile fields.

    Returns:
        Dictionary containing the full profile.
    """
    profile = {"first_name": first, "last_name": last}
    profile.update(kwargs)
    return profile

profile = build_profile("Ravi", "Kumar", age=28, city="Bangalore", role="developer")
print(profile)

Exercise 4 — Password Validator

Create a function validate_password(password, *, min_length=8, require_digit=True, require_upper=True) that returns a tuple (is_valid, messages) where messages is a list of issues found.

valid, msgs = validate_password("hello")
print(valid)  # False
print(msgs)   # ['Too short (min 8)', 'Missing digit', 'Missing uppercase']

valid, msgs = validate_password("Hello123")
print(valid)  # True
print(msgs)   # []
Show Solution
def validate_password(
    password: str,
    *,
    min_length: int = 8,
    require_digit: bool = True,
    require_upper: bool = True
) -> tuple[bool, list[str]]:
    """Validate a password against configurable rules.

    Args:
        password: The password to validate.
        min_length: Minimum length required.
        require_digit: Whether at least one digit is required.
        require_upper: Whether at least one uppercase letter is required.

    Returns:
        Tuple of (is_valid, list_of_issues).
    """
    messages = []

    if len(password) < min_length:
        messages.append(f"Too short (min {min_length})")
    if require_digit and not any(c.isdigit() for c in password):
        messages.append("Missing digit")
    if require_upper and not any(c.isupper() for c in password):
        messages.append("Missing uppercase")

    return (len(messages) == 0, messages)

valid, msgs = validate_password("hello")
print(valid)  # False
print(msgs)   # ['Too short (min 8)', 'Missing digit', 'Missing uppercase']

valid, msgs = validate_password("Hello123")
print(valid)  # True
print(msgs)   # []

Exercise 5 — Function Composition

Write a function compose(*functions) that takes any number of single-argument functions and returns a new function that applies them right to left (i.e., the last function passed runs first).

def double(x):
    return x * 2

def add_ten(x):
    return x + 10

def square(x):
    return x ** 2

transform = compose(add_ten, double, square)
print(transform(3))  # add_ten(double(square(3))) = add_ten(double(9)) = add_ten(18) = 28
Show Solution
def compose(*functions):
    """Compose multiple functions right to left.

    Args:
        *functions: Functions to compose. Applied right to left.

    Returns:
        A new function that is the composition of all inputs.
    """
    def composed(x):
        result = x
        for func in reversed(functions):
            result = func(result)
        return result
    return composed

def double(x):
    return x * 2

def add_ten(x):
    return x + 10

def square(x):
    return x ** 2

transform = compose(add_ten, double, square)
print(transform(3))  # 28
print(transform(5))  # add_ten(double(25)) = add_ten(50) = 60

Scoring Guide

Score Level
5/5 ⭐ Functions master — ready for advanced topics
3-4/5 👍 Strong foundation — review edge cases
1-2/5 📚 Revisit parameters, *args/**kwargs, and return values

Next chapter: Scope & Closures →

Updated: