Python Series track

Week 03 · Intermediate Track

Week 3 — Modules & Packages

Organize code into reusable modules and packages. Understand how Python's import system works, create your own packages, and manage dependencies with pip.

Intermediate Track2 min readFree lesson

Level: Intermediate | Prerequisite: Week 2

Learning Goals

  • Create your own modules and import them
  • Know the __name__ == "__main__" pattern
  • Understand package structure and the role of __init__.py
  • Install external packages using pip

1. Module

A .py file is a module. Use import to use it in another file.

# calc.py
def add(a, b):
    return a + b

def sub(a, b):
    return a - b
# main.py
import calc
print(calc.add(3, 5))

from calc import add, sub
print(add(1, 2), sub(5, 3))

from calc import add as plus
print(plus(10, 20))

2. __name__ == "__main__"

Code that only runs when executed directly as a script.

# mymod.py
def main():
    print("Executed")

if __name__ == "__main__":
    main()

Thanks to this pattern, even if you import mymod, main() does not run automatically.

3. Package

A folder that bundles multiple modules together. Must have __init__.py to be recognized as a package (not required from Python 3.3+).

mypkg/
├── __init__.py
├── math_utils.py
└── string_utils.py
#use
from mypkg.math_utils import add
from mypkg.string_utils import slugify

4. Using __init__.py

# mypkg/__init__.py
from .math_utils import add, sub
from .string_utils import slugify

This way, from mypkg import add is possible (convenient).

5. Installing external packages with pip

pip install requests
pip install requests==2.31.0       #Specific version
pip install -r requirements.txt    #Batch installation
pip list                            #Installed list

Key Examples (examples/)

File Content
calc.py Custom module
main.py Uses calc module import
mypkg/__init__.py, math_utils.py, string_utils.py Package
use_pkg.py Using package

⚠️ Common Mistakes

  1. Circular import — A imports B, B imports A → ImportError
  2. Incorrect relative import — Inside a package, use from .module import ...
  3. Module name conflicts with standard library — Creating a file named random.py will override the standard random

❓ FAQ

Q1. Which should I use, import or from? A. If you use only 1-2 functions, use from; if there are many or you want to specify the module name, use import.

Q2. pip is not installed A. Check with python -m ensurepip or python -m pip --version.

Q3. Why use a virtual environment (venv)? A. To separate library versions for each project. Almost essential for the next semester and in practice.

📝 Exercises (exercises/)

  • exercise1.md — calculator/ package (basic + advanced)
  • exercise2.md — string_utils.py (slugify, truncate)
  • Using exercise3.md — __name__ == "__main__"

Next Week

Week 4. Standard Library

Example files

The runnable files used in this lesson. Copy them into your own project and experiment.

examples/calc.pyPython
def add(a, b):
    return a + b

def sub(a, b):
    return a - b

def mul(a, b):
    return a * b

def div(a, b):
    if b == 0:
        return None
    return a / b
examples/main.pyPython
import calc
print(calc.add(3, 5))

from calc import sub, mul
print(sub(10, 4))
print(mul(6, 7))

from calc import add as plus
print(plus(100, 200))
examples/mypkg/__init__.pyPython
"""mypkg package — A collection of frequently used utilities"""
from .math_utils import add, factorial
from .string_utils import slugify, truncate
examples/mypkg/math_utils.pyPython
def add(a, b):
    return a + b

def factorial(n):
    if n < 0:
        raise ValueError("Negative numbers are not allowed")
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result
examples/mypkg/string_utils.pyPython
def slugify(text):
    return text.strip().lower().replace(" ", "-")

def truncate(text, max_len):
    if len(text) <= max_len:
        return text
    return text[:max_len - 3] + "..."
examples/use_pkg.pyPython
from mypkg import add, factorial, slugify, truncate

print(add(3, 5))
print(factorial(5))
print(slugify("Hello World"))
print(truncate("This sentence is a bit long", 8))

Assignment

Goal

Create a package separated into two modules: basic arithmetic + advanced (power, root).

Structure

calculator/
├── __init__.py     # exports all of add, sub, mul, div, power, sqrt
├── basic.py        # add, sub, mul, div
└── advanced.py     # power, sqrt

Example of use

from calculator import add, power, sqrt
print(add(3, 5))      # 8
print(power(2, 10))   # 1024
print(sqrt(16))       # 4.0

Assignment 2. string_utils.py

Goal

Create a string utility module.

Functions

  • slugify(text) — Trim whitespace on both sides, convert to lowercase, replace spaces with -
  • truncate(text, max_len) — If longer than max_len, shorten to ...
  • wrap(text, width) — Insert line breaks at every width

Example of use

print(slugify(" Hello World "))      # "hello-world"
print(truncate("This sentence is long", 5)) #"This sentence..."
print(wrap("abcdefghij", 4))          # "abcd\nefgh\nij"

Assignment 3. __name__ == "__main__" pattern

Goal

Make the module usable both as a library and as a script.

Requirements

  • Write greet.py
  • Define def greet(name) function
  • Receive user input within if __name__ == "__main__": and print a greeting
  • Must be usable from other files as from greet import greet as well

Verification

  • python greet.py → Receive input and print greeting
  • python -c "from greet import greet; print(greet('Bob'))" → Use function only (no user input)
Show the reference solution

Try the assignment yourself first — comparing your attempt with a working solution is where most of the learning happens.

calculator/__init__.pyPython
from .basic import add, sub, mul, div
from .advanced import power, sqrt
calculator/advanced.pyPython
import math

def power(base, exp):
    return base ** exp

def sqrt(x):
    if x < 0:
        raise ValueError("Square root of a negative number")
    return math.sqrt(x)
calculator/basic.pyPython
def add(a, b): return a + b
def sub(a, b): return a - b
def mul(a, b): return a * b
def div(a, b):
    if b == 0:
        raise ZeroDivisionError("Cannot divide by 0")
    return a / b
solution2.pyPython
"""Collection of string utility functions"""

def slugify(text):
    return text.strip().lower().replace(" ", "-")

def truncate(text, max_len):
    if len(text) <= max_len:
        return text
    return text[:max_len - 3] + "..."

def wrap(text, width):
    return "\n".join(text[i:i+width] for i in range(0, len(text), width))

if __name__ == "__main__":
    print(slugify(" Hello World "))
    print(truncate("This sentence is long", 5))
    print(wrap("abcdefghij", 4))
solution3.pyPython
"""greet.py — Can be used both as a library and as a script"""

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

if __name__ == "__main__":
    name = input("Name:").strip()
    print(greet(name))

Learn this lesson with a mentor

Work through the Python Series track on your own, or join a guided cohort at our Pitampura campus and online.

Call NowEnroll Now