You do not have to write everything yourself. A lot of the code you need already comes with Python, sitting in what is called the standard library. You reach it with one word.
import random print(random.randint(1, 6))
4
Two lines, and you have a working dice roll. You did not write the random-number code. Someone did, years ago, and it ships inside Python. Run it again and you will get a different number, because that is what random does. This part is about that word import, what a module actually is, and which parts of the standard library are worth knowing on your first day writing real code.
import, then use its tools by name, like random.randint. Import the specific thing you need, keep the module name in front of it, and you will always know where a function came from.This one is for the career switcher or fresher who has been writing everything in a single file and is starting to wonder where functions like sqrt live. You need Python 3 and about twenty five minutes. It builds on Part 12, where your expense tracker learned to refuse a bad amount without crashing. Every snippet below runs as printed, so copy it and try it as you read.
A module is just a file of code
Strip away the jargon and a module is a plain .py file. When you write import random, Python finds a file named random.py that ships with it, runs it once, and hands you everything defined inside under the name random. That is why you call random.randint and not just randint. The module name stays in front like a surname.
The standard library is simply the collection of these files that install alongside Python itself. Dates, math, file paths, JSON, random numbers, counting things: a huge amount is already there. You do not install any of it. That is the difference from the packages you will meet in Part 14, which other people publish and you fetch with pip.
Figure 1. import runs the module file once and gives you its names under the module name.
The shapes of import
There is more than one way to pull code in, and the shape you pick changes how you call it. Three forms cover almost everything you will write.
Import the whole module
import math print(math.sqrt(144)) print(math.pi)
12.0 3.141592653589793
Everything stays behind math., so a reader always knows where sqrt came from. This is the safest default.
Pull in one name with from
from math import sqrt print(sqrt(144))
12.0
Now sqrt is a bare name in your file. Shorter to type, but if two modules both have a sqrt, the second import quietly wins. Use this for one or two names you call a lot.
Give a long name a short alias
import datetime as dt today = dt.date.today() print(today)
2026-07-03
The as keyword renames the module for the rest of the file. Your date will differ, since it prints whatever today is on your machine.
| Form | Example | Reach for it when |
|---|---|---|
| import module | import math | your default, keeps origins clear |
| from module import name | from math import sqrt | you call one or two names often |
| import module as alias | import datetime as dt | the name is long or has a convention |
| from module import * | avoid this | almost never; it hides where names came from |
Here is a real opinion, and it goes against the lazy habit you will see in tutorials. Do not write from module import *. It dumps every name from the module into your file, so a reader cannot tell what is yours and what came from where, and two star imports can silently clobber each other. The few keystrokes you save are not worth the confusion. Name what you import.
What is worth knowing in the standard library
You will not memorize all of it, and you do not need to. A handful of modules cover most everyday jobs. Learn these names and you will stop reinventing code that already exists.
| Module | Gives you | A call |
|---|---|---|
| math | square roots, pi, rounding | math.sqrt(16) |
| random | random numbers and picks | random.choice(items) |
| datetime | dates and times | date.today() |
| statistics | mean, median, stdev | statistics.mean(nums) |
| os | folders, paths, environment | os.getcwd() |
| pathlib | modern file paths | Path(‘data.csv’).exists() |
| json | read and write JSON | json.dumps(obj) |
| collections | Counter, defaultdict | Counter(words) |
A quick worked example ties two of them together. Pick a random amount and average a short list, using only standard-library code.
import random
import statistics
random.seed(1)
nums = [random.randint(1, 100)
for _ in range(5)]
print(nums)
print('mean is', statistics.mean(nums))[18, 73, 98, 9, 33] mean is 46.2
The random.seed(1) line pins the sequence so your run matches the output above. Without it you would get five different numbers each time.
The datetime trap almost everyone hits
The datetime module is a common first stumble, and the reason is confusing on purpose. Inside the module named datetime there is a class also named datetime. So a natural guess fails.
import datetime print(datetime.today())
Traceback (most recent call last):
File "app.py", line 2, in <module>
print(datetime.today())
^^^^^^^^^^^^^^^^
AttributeError: module 'datetime' has
no attribute 'today'Read that last line the way Part 12 taught you. The module has no today. The today function lives on the classes inside the module, like date and datetime. The clean fix is to import the classes you want by name.
from datetime import date, datetime print(date.today()) print(datetime.now().year)
2026-07-03 2026
Now date and datetime are the classes, and the calls read plainly. When you see from datetime import datetime in real code, that is why. The names collide, so people import the class straight.
Do not name your file random.py
This one costs beginners an afternoon. Say you are learning random and you save your practice file as random.py. You run it and get this.
# saved as random.py import random print(random.randint(1, 6))
Traceback (most recent call last):
File "random.py", line 2, in <module>
import random
File "random.py", line 3, in <module>
print(random.randint(1, 6))
AttributeError: partially initialized
module 'random' has no attribute
'randint' (most likely due to a
circular import)Python looks in your script’s own folder first, so import random found your file, not the real one. Your file has no randint, so it fails. The fix is simple: rename your file to something that is not a standard-library name, like dice.py, and delete any random.pyc cache next to it. When an import behaves strangely, check whether one of your files is shadowing a real module.
Write your own module
Any .py file you make can be imported by another. Put a helper in one file and use it from another. Say money.py holds a formatter.
def format_money(amount):
return 'Rs ' + format(amount, '.2f')Then a second file in the same folder imports it by the file’s name, without the .py.
from money import format_money print(format_money(120.5))
Rs 120.50
Run it the usual way. The command differs a little by system, so here are both.
python app.py
python3 app.py
That is the whole idea behind splitting a growing program into files: each file is a module, and import stitches them together.
One module that hides the slash problem
File paths look different on each system. Windows uses a backslash, like datanotes.txt, while macOS and Linux use a forward slash, like data/notes.txt. Gluing paths together by hand means picking the wrong slash on someone else’s machine. The pathlib module from the standard library handles it for you.
from pathlib import Path
path = Path('data') / 'notes.txt'
print(path)
print(path.suffix)data/notes.txt .txt
On Windows the same code prints datanotes.txt. You wrote it once, and pathlib used the right slash for the machine it ran on. That is the standard library doing the boring, easy-to-get-wrong work so you do not have to.
datetime. It builds on the dicts and functions from earlier parts.
from datetime import date
def add_expense(items, amount,
category):
items.append(
{'amount': amount,
'category': category,
'day': date.today()
.isoformat()})
return items
def total_by_month(items):
totals = {}
for e in items:
month = e['day'][:7]
totals[month] = (
totals.get(month, 0)
+ e['amount'])
return totals
expenses = []
expenses = add_expense(
expenses, 120.5, 'food')
expenses = add_expense(
expenses, 40.0, 'travel')
print(total_by_month(expenses)){'2026-07': 160.5}date.today().isoformat() gives a string like 2026-07-03, and the slice [:7] keeps just the year and month for grouping. Your month key will match whatever today is when you run it.Figure 2. Once each expense carries a date, total_by_month turns the list into a monthly picture.
import math and from math import sqrt? A good answer: the first keeps every name behind math., so math.sqrt tells a reader exactly where it came from. The second copies sqrt straight into your file, which is shorter but can clash with another name and hides its origin. Mention that you avoid from module import * for the same reason, and you have shown you think about readability, not just getting it to run.random and datetime modules together: pick a random lunch from a list and print it with today’s date, like 2026-07-03: pizza. Your date and pick will vary.
2026-07-03: pizza
Show solution
import random
from datetime import date
lunches = ['pizza', 'salad', 'rice']
pick = random.choice(lunches)
print(date.today().isoformat()
+ ': ' + pick)Questions people ask about import
Do I need to install the standard library? No. It comes with Python. The pip command in Part 14 is for third-party packages, not for math, random, or datetime.
Where does Python look for a module? First the built-in modules, then the folders listed in sys.path, starting with your script’s own folder. That folder-first rule is exactly why a file named random.py breaks things.
Should imports go at the top of the file or inside a function? The top of the file, always, as the normal place readers expect. Import inside a function only for a rare, heavy, or optional dependency you do not always need.
What is the difference between a module and a package? A module is a single file. A package is a folder of modules with an __init__.py file. You import from both the same way, so as a beginner you can treat them alike.
as, find the right tool in the standard library instead of writing it yourself, avoid the datetime and same-name-file traps, and split your own code into a module you import. Your tracker stamps each expense with a date and totals spending by month.So far every module you have used shipped with Python. Next comes the other kind: packages other people wrote, installed with pip into an isolated venv so they do not collide with your system Python. Keep expenses.py open for Part 14.
References
Python docs: Modules
Python docs: The standard library
Python docs: datetime


DrJha