Assignment 5-A

Functions Mastery

Build a complete Calculator Library that demonstrates mastery of Python functions: basic functions, parameters (positional, keyword, default, *args, **kwargs), return values, lambda functions, closures, decorators, and recursion.

4-6 hours
Intermediate
150 Points
Submit Assignment
What You'll Practice
  • Define functions with various parameter types
  • Use *args and **kwargs effectively
  • Write lambda functions and closures
  • Create and apply decorators
  • Implement recursive algorithms
Contents
01

Assignment Overview

In this assignment, you will build a comprehensive Calculator Library that demonstrates your mastery of Python functions. This project requires you to apply ALL concepts from Module 5: function definitions, multiple parameter types, return values, lambda expressions, higher-order functions, closures, decorators, and recursive algorithms.

No External Libraries: You must use ONLY Python's built-in functions and the math module. No third-party libraries allowed. This tests your understanding of pure Python functions.
Skills Applied: This assignment tests your understanding of Basic Functions (Topic 5.1), Advanced Functions (Topic 5.2), and Variable Scope (Topic 5.3) from Module 5.
Basic Functions (5.1)

Function definitions, parameters, arguments, return values, docstrings

Advanced Functions (5.2)

*args, **kwargs, lambda, closures, decorators, recursion

Variable Scope (5.3)

Local, global, nonlocal, LEGB rule, closures

Ready to submit? Already completed the assignment? Submit your work now!
Submit Now
02

The Scenario

MathGenius Calculator Library

You have been hired as a Python Developer at MathGenius Solutions, a company that creates educational software. The lead developer has given you this task:

"We need a reusable calculator library that showcases different types of Python functions. It should include basic arithmetic, statistical calculations, financial computations, and mathematical sequences. Make sure to use decorators for logging and validation, and implement some algorithms recursively."

Your Task

Create a Python file called calculator_library.py that implements a complete calculator library with various function types. Your code must demonstrate proficiency in all function concepts taught in Module 5, including proper docstrings and type hints.

03

Requirements

Your calculator_library.py must implement ALL of the following functions. Each function is mandatory and will be tested individually.

1
Basic Arithmetic Functions

Create four basic functions with proper docstrings:

  • add(a, b) - Returns the sum of two numbers
  • subtract(a, b) - Returns the difference of two numbers
  • multiply(a, b) - Returns the product of two numbers
  • divide(a, b) - Returns the quotient, handles division by zero
def add(a: float, b: float) -> float:
    """
    Add two numbers together.
    
    Args:
        a: First number
        b: Second number
    
    Returns:
        The sum of a and b
    """
    # Your implementation here
    pass
2
Function with Default Parameters

Create a function power(base, exponent=2) that:

  • Raises a number to a power
  • Default exponent is 2 (squares the number)
  • Works with negative exponents
def power(base: float, exponent: float = 2) -> float:
    """Raise base to the power of exponent. Default squares the base."""
    pass
3
Function with *args

Create a function calculate_sum(*numbers) that:

  • Accepts any number of numeric arguments
  • Returns the sum of all provided numbers
  • Returns 0 if no arguments provided
def calculate_sum(*numbers) -> float:
    """Calculate the sum of any number of arguments."""
    # Example: calculate_sum(1, 2, 3, 4, 5) -> 15
    pass
4
Function with **kwargs

Create a function calculate_weighted_average(**grades) that:

  • Accepts subjects as keys and (score, weight) tuples as values
  • Calculates weighted average of all grades
  • Returns the weighted average rounded to 2 decimal places
def calculate_weighted_average(**grades) -> float:
    """
    Calculate weighted average from keyword arguments.
    
    Example:
        calculate_weighted_average(
            math=(85, 0.3),      # score=85, weight=30%
            science=(90, 0.3),   # score=90, weight=30%
            english=(80, 0.4)    # score=80, weight=40%
        ) -> 84.5
    """
    pass
5
Statistics Functions with *args

Create these statistical functions that accept variable arguments:

  • mean(*numbers) - Returns arithmetic mean
  • median(*numbers) - Returns median value
  • mode(*numbers) - Returns most frequent value (first if tie)
def mean(*numbers) -> float:
    """Calculate the arithmetic mean of numbers."""
    pass

def median(*numbers) -> float:
    """Calculate the median of numbers."""
    pass

def mode(*numbers):
    """Return the most frequent number. First value if tie."""
    pass
6
Lambda Functions

Create these operations using lambda expressions:

  • square - Lambda that squares a number
  • cube - Lambda that cubes a number
  • is_even - Lambda that returns True if even
  • is_positive - Lambda that returns True if positive
# Define these as lambda expressions
square = lambda x: ...
cube = lambda x: ...
is_even = lambda x: ...
is_positive = lambda x: ...
7
Higher-Order Function

Create a function apply_operation(numbers, operation) that:

  • Takes a list of numbers and a function as arguments
  • Applies the operation to each number
  • Returns a new list with results
def apply_operation(numbers: list, operation) -> list:
    """
    Apply an operation to each number in the list.
    
    Example:
        apply_operation([1, 2, 3], square) -> [1, 4, 9]
        apply_operation([1, 2, 3], lambda x: x * 10) -> [10, 20, 30]
    """
    pass
8
Closure: Counter Factory

Create a function make_counter(start=0) that:

  • Returns a closure function
  • Each call to the closure increments and returns the count
  • Demonstrates nonlocal variable usage
def make_counter(start: int = 0):
    """
    Create a counter closure.
    
    Example:
        counter = make_counter(10)
        counter() -> 11
        counter() -> 12
        counter() -> 13
    """
    pass
9
Closure: Multiplier Factory

Create a function make_multiplier(factor) that:

  • Returns a function that multiplies its input by the factor
  • Demonstrates closure capturing outer variable
def make_multiplier(factor: float):
    """
    Create a multiplier closure.
    
    Example:
        double = make_multiplier(2)
        triple = make_multiplier(3)
        double(5) -> 10
        triple(5) -> 15
    """
    pass
10
Decorator: Logging

Create a decorator @log_call that:

  • Prints the function name and arguments before execution
  • Prints the return value after execution
  • Works with any function signature
def log_call(func):
    """
    Decorator that logs function calls.
    
    Example output:
        Calling: add(5, 3)
        Returned: 8
    """
    pass

@log_call
def add_logged(a, b):
    return a + b
11
Decorator: Validation

Create a decorator @validate_positive that:

  • Checks if all numeric arguments are positive
  • Raises ValueError if any argument is negative or zero
  • Passes through if all arguments are positive
def validate_positive(func):
    """
    Decorator that validates all numeric arguments are positive.
    Raises ValueError if any argument is <= 0.
    """
    pass

@validate_positive
def calculate_area(length, width):
    return length * width
12
Recursive: Factorial

Create a recursive function factorial(n) that:

  • Calculates factorial using recursion
  • Handles base case (0! = 1, 1! = 1)
  • Raises ValueError for negative numbers
def factorial(n: int) -> int:
    """
    Calculate factorial recursively.
    
    Example:
        factorial(5) -> 120  # 5*4*3*2*1
        factorial(0) -> 1
    """
    pass
13
Recursive: Fibonacci

Create a recursive function fibonacci(n) that:

  • Returns the nth Fibonacci number
  • fibonacci(0) = 0, fibonacci(1) = 1
  • Each subsequent number is sum of previous two
def fibonacci(n: int) -> int:
    """
    Calculate nth Fibonacci number recursively.
    
    Sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, ...
    
    Example:
        fibonacci(6) -> 8
        fibonacci(10) -> 55
    """
    pass
14
Recursive: Sum of Digits

Create a recursive function sum_digits(n) that:

  • Calculates sum of all digits in a number
  • Works with positive integers only
  • Uses recursion (not string conversion)
def sum_digits(n: int) -> int:
    """
    Calculate sum of digits recursively.
    
    Example:
        sum_digits(12345) -> 15  # 1+2+3+4+5
        sum_digits(999) -> 27     # 9+9+9
    """
    pass
15
Main Function with Demonstrations

Create a main() function that:

  • Demonstrates all implemented functions
  • Prints clear output for each demonstration
  • Uses if __name__ == "__main__": pattern
def main():
    """Demonstrate all calculator library functions."""
    print("=" * 50)
    print("CALCULATOR LIBRARY DEMONSTRATION")
    print("=" * 50)
    
    # Basic Arithmetic
    print("\n1. Basic Arithmetic:")
    print(f"   add(10, 5) = {add(10, 5)}")
    print(f"   subtract(10, 5) = {subtract(10, 5)}")
    print(f"   multiply(10, 5) = {multiply(10, 5)}")
    print(f"   divide(10, 5) = {divide(10, 5)}")
    
    # ... demonstrate all other functions
    
    print("\n" + "=" * 50)
    print("All demonstrations complete!")

if __name__ == "__main__":
    main()
04

Submission

Create a public GitHub repository with the exact name shown below:

Required Repository Name
python-calculator-library
github.com/<your-username>/python-calculator-library
Required Files
python-calculator-library/
├── calculator_library.py     # Your main Python file with ALL 15 requirements
├── test_calculator.py        # Unit tests for your functions (at least 10 tests)
├── output.txt                # Output from running main() function
└── README.md                 # REQUIRED - see contents below
README.md Must Include:
  • Your full name and submission date
  • Brief description of each function category implemented
  • Any challenges faced and how you solved them
  • Instructions to run the library and tests
Do Include
  • All 15 requirements implemented
  • Docstrings for every function
  • Type hints where appropriate
  • Clear, organized code structure
  • Unit tests in test_calculator.py
  • README.md with all required sections
Do Not Include
  • External libraries (ONLY math module allowed)
  • Any .pyc or __pycache__ files (use .gitignore)
  • Virtual environment folders
  • Code that doesn't run without errors
  • Copied code from the internet
Important: Before submitting, run your code to make sure it executes without errors and generates the output.txt file correctly!
Submit Your Assignment

Enter your GitHub username - we'll verify your repository automatically

05

Grading Rubric

Your assignment will be graded on the following criteria:

Criteria Points Description
Basic Functions (1-2) 15 Correct implementation of basic arithmetic and power functions with docstrings
Variable Arguments (3-5) 25 Proper use of *args, **kwargs, and statistical calculations
Lambda Functions (6-7) 20 Correct lambda definitions and higher-order function usage
Closures (8-9) 20 Proper closure implementations with nonlocal variables
Decorators (10-11) 25 Working decorators for logging and validation
Recursion (12-14) 25 Correct recursive implementations with proper base cases
Code Quality & Testing 20 Docstrings, type hints, unit tests, and clean organization
Total 150

Ready to Submit?

Make sure you have completed all requirements and reviewed the grading rubric above.

Submit Your Assignment
06

What You Will Practice

Function Basics (5.1)

Defining functions with parameters, default values, type hints, docstrings, and return statements

*args and **kwargs (5.2)

Variable positional arguments, keyword arguments, unpacking operators, and flexible function signatures

Lambda & Higher-Order Functions (5.2)

Anonymous functions, functions as arguments, map/filter/reduce patterns, functional programming

Closures & Decorators (5.2-5.3)

Factory functions, closures, nonlocal scope, decorator patterns, function wrapping

07

Pro Tips

Function Best Practices
  • Keep functions small and focused (single responsibility)
  • Use descriptive names that indicate what the function does
  • Always include docstrings with examples
  • Use type hints for better code clarity
Recursion Tips
  • Always define a clear base case first
  • Ensure recursive calls move toward the base case
  • Consider stack overflow for large inputs
  • Test with edge cases (0, 1, negative)
Decorator Tips
  • Use functools.wraps to preserve function metadata
  • Handle *args and **kwargs in wrapper functions
  • Return the result from the wrapped function
  • Test decorators with different function signatures
Common Mistakes
  • Forgetting to return a value from functions
  • Mutable default arguments (use None instead)
  • Missing base case in recursion (infinite loop)
  • Not handling edge cases in calculations
08

Pre-Submission Checklist

Code Requirements
Repository Requirements