python
solutions
solutions.py🐍python
"""
Solutions for Module 05 - Functions Exercises
These are reference solutions. Try to solve the exercises yourself first!
"""
# =============================================================================
# Basic Function Solutions
# =============================================================================
def greet(name: str) -> str:
"""Return a greeting message."""
return f"Hello, {name}!"
def add_numbers(a: float, b: float) -> float:
"""Add two numbers and return the result."""
return a + b
def is_even(number: int) -> bool:
"""Check if a number is even."""
return number % 2 == 0
def factorial(n: int) -> int:
"""Calculate factorial of n (recursive)."""
if n <= 1:
return 1
return n * factorial(n - 1)
def factorial_iterative(n: int) -> int:
"""Calculate factorial of n (iterative)."""
result = 1
for i in range(2, n + 1):
result *= i
return result
# =============================================================================
# Default Arguments & Keyword Arguments
# =============================================================================
def power(base: float, exponent: float = 2) -> float:
"""Calculate base raised to exponent (default: square)."""
return base ** exponent
def create_user(name: str, age: int = 0, email: str = "", active: bool = True) -> dict:
"""Create a user dictionary with default values."""
return {
"name": name,
"age": age,
"email": email,
"active": active
}
def format_name(first: str, last: str, *, middle: str = "", title: str = "") -> str:
"""Format a full name with optional middle name and title."""
parts = []
if title:
parts.append(title)
parts.append(first)
if middle:
parts.append(middle)
parts.append(last)
return " ".join(parts)
# =============================================================================
# *args and **kwargs
# =============================================================================
def sum_all(*args: float) -> float:
"""Sum all provided numbers."""
return sum(args)
def average(*args: float) -> float:
"""Calculate average of all provided numbers."""
if not args:
return 0.0
return sum(args) / len(args)
def build_profile(name: str, **kwargs) -> dict:
"""Build a user profile from name and any additional attributes."""
profile = {"name": name}
profile.update(kwargs)
return profile
def call_with_logging(func, *args, **kwargs):
"""Call a function and log the call."""
print(f"Calling {func.__name__} with args={args}, kwargs={kwargs}")
result = func(*args, **kwargs)
print(f"Result: {result}")
return result
# =============================================================================
# Lambda Functions
# =============================================================================
# Sort by second element
pairs = [(1, 'b'), (2, 'a'), (3, 'c')]
sorted_pairs = sorted(pairs, key=lambda x: x[1])
# Filter even numbers
numbers = [1, 2, 3, 4, 5, 6]
evens = list(filter(lambda x: x % 2 == 0, numbers))
# Map to squares
squares = list(map(lambda x: x**2, numbers))
# Sort strings by length
words = ["apple", "pie", "banana", "kiwi"]
by_length = sorted(words, key=lambda x: len(x))
# =============================================================================
# Higher-Order Functions
# =============================================================================
def apply_operation(numbers: list, operation) -> list:
"""Apply an operation to each number in the list."""
return [operation(n) for n in numbers]
def create_multiplier(factor: int):
"""Return a function that multiplies by factor (closure)."""
def multiplier(x):
return x * factor
return multiplier
def compose(f, g):
"""Return a function that composes f and g: f(g(x))."""
def composed(x):
return f(g(x))
return composed
def retry(max_attempts: int = 3):
"""Decorator that retries a function on exception."""
def decorator(func):
def wrapper(*args, **kwargs):
last_error = None
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except Exception as e:
last_error = e
print(f"Attempt {attempt + 1} failed: {e}")
raise last_error
return wrapper
return decorator
# =============================================================================
# Recursive Functions
# =============================================================================
def fibonacci(n: int) -> int:
"""Calculate nth Fibonacci number (recursive)."""
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
def fibonacci_memo(n: int, memo: dict = None) -> int:
"""Calculate nth Fibonacci number with memoization."""
if memo is None:
memo = {}
if n in memo:
return memo[n]
if n <= 1:
return n
memo[n] = fibonacci_memo(n - 1, memo) + fibonacci_memo(n - 2, memo)
return memo[n]
def flatten(nested_list: list) -> list:
"""Flatten a nested list recursively."""
result = []
for item in nested_list:
if isinstance(item, list):
result.extend(flatten(item))
else:
result.append(item)
return result
def deep_sum(data) -> float:
"""Sum all numbers in a nested structure."""
if isinstance(data, (int, float)):
return data
elif isinstance(data, (list, tuple)):
return sum(deep_sum(item) for item in data)
elif isinstance(data, dict):
return sum(deep_sum(v) for v in data.values())
return 0
# =============================================================================
# Test Solutions
# =============================================================================
if __name__ == "__main__":
# Test basic functions
assert greet("Alice") == "Hello, Alice!"
assert add_numbers(2, 3) == 5
assert is_even(4) == True
assert factorial(5) == 120
# Test default arguments
assert power(3) == 9
assert power(2, 3) == 8
user = create_user("Bob")
assert user["name"] == "Bob"
assert user["active"] == True
# Test *args and **kwargs
assert sum_all(1, 2, 3, 4) == 10
assert average(10, 20, 30) == 20.0
profile = build_profile("Alice", age=30, city="NYC")
assert profile["city"] == "NYC"
# Test closures
double = create_multiplier(2)
triple = create_multiplier(3)
assert double(5) == 10
assert triple(5) == 15
# Test recursive functions
assert fibonacci(10) == 55
assert flatten([1, [2, 3], [4, [5, 6]]]) == [1, 2, 3, 4, 5, 6]
assert deep_sum([1, [2, 3], {"a": 4}]) == 10
print("All solutions verified! ✓")