Modules & the Standard Library

The Course
January 9, 2026
5 min read

Python ships with a large standard library — the “batteries included” its users have bragged about for thirty years. Knowing what is in the box saves you from writing it again.

Four ways to import

Import styles Python
import math                      # the whole module
print(math.sqrt(16), math.pi)

from math import sqrt, pi        # specific names
print(sqrt(25), pi)

import statistics as stats       # with a shorter alias
print(stats.mean([1, 2, 3, 4]))

from math import *               # everything - do not do this
print(cos(0))

Prefer the first two. import math keeps the origin of math.sqrt visible; from math import * dumps unknown names into your namespace and quietly shadows your own.

math and random

Numbers Python
import math
import random

print(math.sqrt(144), math.floor(3.7), math.ceil(3.2))
print(math.factorial(5), round(math.log(100, 10)))

random.seed(7)          # same seed, same sequence - handy for tests
print(random.randint(1, 6))
print(random.random())
print(random.choice(["rock", "paper", "scissors"]))

deck = list(range(1, 11))
random.shuffle(deck)
print(deck)
print(random.sample(deck, 3))

datetime

Dates and times Python
from datetime import date, datetime, timedelta

today = date(2026, 1, 9)
print(today, today.year, today.strftime("%A, %d %B %Y"))

launch = date(2026, 3, 1)
gap = launch - today
print(f"{gap.days} days until launch")

print(today + timedelta(days=90))

parsed = datetime.strptime("2026-01-09 14:30", "%Y-%m-%d %H:%M")
print(parsed, parsed.hour)

strftime formats a date into text; strptime parses text into a date. The codes are the same both ways: %Y four-digit year, %m month, %d day, %H hour, %M minute, %A weekday name, %B month name.

json

JSON is how programs exchange structured data. The mapping to Python is almost one to one: objects become dictionaries, arrays become lists.

Text in, data out Python
import json

data = {
    "name": "Ada",
    "languages": ["Python", "Analytical Engine"],
    "active": True,
    "score": None,
}

text = json.dumps(data, indent=2)     # Python -> JSON text
print(text)

restored = json.loads(text)           # JSON text -> Python
print(type(restored), restored["languages"][0])
print(restored["active"] is True, restored["score"] is None)

Note the translation: Python’s True becomes true, None becomes null. json.dump() and json.load() (no “s”) do the same to and from a file object.

collections

Three tools here save real work.

Counter, defaultdict, namedtuple Python
from collections import Counter, defaultdict, namedtuple

words = "the quick brown fox the lazy dog the end".split()

counts = Counter(words)
print(counts.most_common(2))
print(counts["the"], counts["missing"])    # missing keys are 0, not an error

groups = defaultdict(list)                 # a missing key auto-creates []
for word in words:
    groups[len(word)].append(word)
print(dict(groups))

Point = namedtuple("Point", ["x", "y"])    # a tuple with named fields
p = Point(3, 4)
print(p, p.x, p.y)

Counter is the word-count exercise from Day 3 in a single call.

pathlib

The modern way to handle paths — no string concatenation, no separators to get wrong.

Paths as objects Python
from pathlib import Path

folder = Path("data")
folder.mkdir(exist_ok=True)

note = folder / "note.txt"        # / joins paths on any OS
note.write_text("Written through pathlib\n")

print(note)
print(note.name, note.suffix, note.stem)
print(note.exists())
print(note.read_text())

for item in folder.iterdir():
    print("  found:", item)

Writing your own module

Any .py file is a module. The next playground holds two files — click the tabs above the editor to switch between them.

Two files, one program Python
from geometry import circle_area, rectangle_area print(f"Circle r=2: {circle_area(2):.2f}") print(f"Rectangle 3x4: {rectangle_area(3, 4)}") """Small geometry helpers.""" from math import pi def circle_area(radius): """Return the area of a circle.""" return pi * radius ** 2 def rectangle_area(width, height): """Return the area of a rectangle.""" return width * height

Imports look in the same folder first, so from geometry import ... finds geometry.py sitting next to main.py. That is all a module is.

if __name__ == '__main__'

Code at the top level of a module runs on import. Guarding it with if __name__ == "__main__": means it runs only when the file is executed directly — so a module can be both an importable library and a runnable script.

Exercise

A dice-rolling report

Roll two six-sided dice 1,000 times and report how often each total from 2 to 12 came up, as a percentage to one decimal place. Seed the generator with 42 so your run is reproducible.

import random
from collections import Counter

random.seed(42)

# Your code here
Show one solution
import random
from collections import Counter

random.seed(42)

rolls = Counter(
    random.randint(1, 6) + random.randint(1, 6)
    for _ in range(1000)
)

for total in range(2, 13):
    count = rolls[total]
    bar = "#" * (count // 10)
    print(f"{total:2}: {count / 10:5.1f}%  {bar}")

A generator expression feeding Counter does the whole simulation in one statement, and rolls[total] returns 0 for any total that never came up.

What you learned

  • import module and from module import name are the imports to use.
  • math, random, datetime, json, collections and pathlib cover an enormous amount of everyday work.
  • JSON maps onto Python dictionaries and lists almost exactly.
  • Counter counts, defaultdict removes missing-key checks, namedtuple names tuple fields.
  • Any .py file next to yours is importable as a module.
Last updated on January 9, 2026

Was this article helpful?

Your response is saved on this device.