IT243 Programming with Python

Programming with PythonUnit 45 min read

Functions, Modules, Recursion & Scope in Python

Unit 4 of Programming with Python covers defining and calling functions, parameter passing (pass-by-value vs. pass-by-object-reference), recursion, modules, and scope rules (LEGB), with real-world examples from Nepalese apps like eSewa and Daraz, and visual traces of function execution.

What is a Function?

A function is a reusable block of code that performs a specific task. It:

  • Takes inputs (parameters/arguments)
  • Processes them
  • Returns an output (or None)
  • Has a scope (where its variables exist)

Why Use Functions?

graph TD
    A["Why Use Functions?"] --> B["Code Reusability"]
    A --> C["Modularity"]
    A --> D["Readability"]
    A --> E["Debugging Easier"]
    A --> F["Avoid Repetition"]

Example: Calculating compound interest (like Ncell’s monthly installment plans).

def compound_interest(principal, rate, time):
    amount = principal * (1 + rate/100)**time
    return amount - principal

# eSewa’s loan interest calculation
interest = compound_interest(100000, 12, 2)  # Rs. 25,440

Defining and Calling Functions

Syntax

def function_name(parameters):
    """Docstring (optional)"""
    # Code block
    return value  # Optional

Example: Daraz Order Processing

def process_order(order_id, items, quantity):
    """Simulates Daraz order fulfillment."""
    total = sum(item['price'] * quantity for item in items)
    print(f"Order {order_id} processed. Total: Rs.{total}")
    return total

# Calling the function
process_order(1001, [{"name": "Phone", "price": 25000}], 1)

Output:

Order 1001 processed. Total: Rs.25000

Parameter Passing in Python

Python uses pass-by-object-reference (not pass-by-value). Changes to mutable objects (lists, dicts) inside a function affect the original.

Comparison Table

Feature Pass-by-Value Pass-by-Object-Reference (Python)
Primitive Types (int, float, str) Copied Copied (immutable)
Mutable Types (list, dict) Copied Reference passed (original modified)
Memory Usage Higher (copy) Lower (reference)

Example: Kathmandu Traffic Routes (Graph as List)

def update_route(routes, new_stop):
    routes.append(new_stop)  # Modifies original list

routes = ["Thamel", "Koteshwor"]
update_route(routes, "Naxal")
print(routes)  # Output: ['Thamel', 'Koteshwor', 'Naxal']

Recursion

Recursion is a function calling itself to solve smaller subproblems.

Example: Fibonacci Sequence (NEPSE Stock Analysis)

def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

# Trace for n=4
Step | fibonacci(4) | fibonacci(3) | fibonacci(2) | fibonacci(1) | fibonacci(0)
-----|--------------|--------------|--------------|--------------|--------------
1    | 3 + 1        |              |              |              |
2    |              | 2 + 1        |              |              |
3    |              |              | 1 + 0        |              |
4    |              |              |              | 1            |
5    |              |              |              |              | 0

Output: fibonacci(4) = 3


Modules in Python

A module is a .py file containing functions, classes, or variables. Modules help organize code (e.g., math, random).

Example: eSewa’s Payment Module

# payment.py (module)
def deduct_fee(amount, fee_percent):
    return amount * (1 - fee_percent/100)

# main.py
import payment
total = payment.deduct_fee(5000, 2)  # Rs. 4900 after 2% fee

Module Search Path:

graph LR
    A["Python Interpreter"] --> B["Built-in Modules"]
    A --> C["sys.path"]
    C --> D["Current Directory"]
    C --> E["PYTHONPATH"]

Scope Rules (LEGB)

Variables are resolved in this order:

  1. Local (inside function)
  2. Enclosing (non-local, in nested functions)
  3. Global (module-level)
  4. Built-in (Python keywords like print)

Example: Ncell’s Call Duration Tracker

call_duration = 10  # Global

def log_call(duration):
    call_duration = duration  # Local
    print(f"Call logged: {call_duration}")

log_call(5)  # Output: 5 (local scope)
print(call_duration)  # Output: 10 (global)

In the Real World

  1. eSewa’s Transaction Processing

    • Uses functions to validate payments, deduct fees, and log transactions.
    • Example: validate_payment(amount, user_id) checks if the user has sufficient balance.
  2. Daraz’s Order Queue

    • Implements a queue (FIFO) to process orders sequentially.
    • Example: process_order(order_id) removes the next order from the queue.
  3. Ncell’s Recursive Billing

    • Calculates roaming charges using recursion for nested call durations.
    • Example: calculate_roaming_charges(minutes) breaks down minutes into smaller intervals.

Exam Tip

  • Functions: Always include a return statement if the function is supposed to produce output.
  • Scope: Remember global keyword to modify global variables inside a function.
  • Recursion: Draw the call stack (like the Fibonacci trace above) to visualize recursive steps.
  • Modules: Know how to import (import module vs. from module import function).

Practice Question: Write a function calculate_traffic_fine(overspeed, location) that returns the fine for overspeeding in Kathmandu (Rs. 1000/km over 60 km/h) and Pokhara (Rs. 500/km over 50 km/h). Use an if-else to handle different locations.

Based on the TU BITM syllabus for Programming with Python (IT243), unit 4.

Discussion

Loading…