The standard library: random, datetime, pathlib
Python comes with a huge standard library — hundreds of modules installed with the language itself. "Batteries included" is the slogan: before reaching for an external package, check whether the stdlib already does it.
You bring a module into your file with import name, then use it as name.thing(). Three you'll reach for constantly:
random— controlled randomness. Crucially,random.seed(n)makes it *reproducible*: seed with the same number and you get the same "random" results every run. Vital for tests.datetime— dates and times. Subtracting two dates gives atimedelta, whose.daystells you the gap.pathlib— modern file-path handling.Path("...")wraps a path and gives you.name,.stem,.suffix,.parent— no fragile string-splitting on/.
You don't need to memorise these. Know they exist, know roughly what's in them, and look up the rest.
Syntax
import random, datetime, pathlib
random.seed(42) # make randomness reproducible
random.choice(["a", "b"]) # pick one item
random.randint(1, 6) # int between 1 and 6 inclusive
datetime.date.today() # today's date
(date_a - date_b).days # gap in whole days
p = pathlib.Path("/logs/errors.log")
p.stem # "errors" (name without extension)
p.suffix # ".log"
p.parent # PosixPath("/logs")Worked examples
random — seed it for a repeatable pick
import random
random.seed(42)
print(random.choice(['a', 'b', 'c', 'd'])) # a
random.seed(42)
print(random.choice(['a', 'b', 'c', 'd'])) # a (same seed → same pick)
random.seed(42)
print(random.randint(1, 6)) # 6 (1..6 inclusive)datetime — the gap between two dates
import datetime
start = datetime.date(2026, 12, 1)
end = datetime.date(2026, 12, 25)
gap = end - start # a timedelta
print(gap.days) # 24
print(type(gap).__name__) # timedelta
# Days from today until a target date:
def days_until(year, month, day):
target = datetime.date(year, month, day)
return (target - datetime.date.today()).dayspathlib — pull a path apart
import pathlib
p = pathlib.Path('/logs/errors.log')
print(p.name) # errors.log
print(p.stem) # errors
print(p.suffix) # .log
print(p.parent) # /logs
# Build a path with / instead of string-glue:
out = pathlib.Path('/data') / 'report.csv'
print(out) # /data/report.csvCommon mistakes & gotchas
random is not for security
random is fine for games, shuffles, and test data, but it's predictable — never use it for passwords, tokens or session IDs. For anything security-sensitive use the secrets module instead.
randint is inclusive on both ends
random.randint(1, 6) can return 6 — unlike range(1, 6) which stops at 5. If you want 0..n-1, use random.randrange(n) instead, which matches range's exclusive-stop behaviour.
Don't parse paths by hand
Splitting a path on "/" or "." breaks on edge cases (archive.tar.gz, Windows backslashes, trailing slashes). pathlib.Path handles all of that. Reach for it instead of str.split("/").
Why it matters
The standard library is the difference between writing ten lines and writing ten thousand. Real developers spend a surprising amount of time just knowing which battery is already in the box — random, datetime and pathlib alone cover a huge slice of everyday backend work.