Modules and Imports
A module is a file of Python code that you can reuse in other programs. Python comes with a huge standard library of modules for maths, dates, random numbers, files, the web and much more. Using them is often the fastest way to get something done.
import
import module_name loads a module. You then use its contents with a dot:
import math print(math.sqrt(81)) print(math.pi) print(math.factorial(5))
math.sqrt means "the sqrt function that lives in the math module". After import math, the name math refers to the whole module, and the dot reaches inside it. Plain sqrt(81) would be a NameError, because import math doesn't create a variable called sqrt.
Imports normally go at the top of a file, so it's easy to see what a program depends on. A misspelled module name, as in import maths, gives a ModuleNotFoundError.
from … import
To use a few names without the module prefix, import them directly:
from math import sqrt, pi print(sqrt(16)) print(round(pi, 3))
Avoid from module import *. It pulls in every name and makes it hard to tell where things come from, and it can silently overwrite your own variables.
Aliases with as
Give a module or a name a shorter alias with as. Some aliases are so common they're a convention, like import numpy as np:
import statistics as stats from random import randint as roll scores = [72, 85, 90, 66, 98] print(stats.mean(scores)) print(stats.median(scores)) print(roll(1, 6))
The three styles side by side:
| You write | Then you use | Good for |
|---|---|---|
import math |
math.sqrt(16) |
most cases: it's clear where sqrt comes from |
from math import sqrt |
sqrt(16) |
a few names you use a lot |
import statistics as stats |
stats.mean(...) |
long module names, or well-known short forms like np |
from random import randint as roll combines the last two: it imports one name and renames it.
A tour of useful modules
random
import random print(random.randint(1, 10)) print(random.random()) print(random.choice(["rock", "paper", "scissors"])) cards = ["A", "K", "Q", "J", "10"] random.shuffle(cards) print(cards) print(random.sample(range(1, 50), 6))
| Function | Gives you |
|---|---|
randint(a, b) |
a whole number from a to b, including both ends |
random() |
a float from 0 up to, but not including, 1 |
choice(items) |
one item picked from a list, tuple or string |
shuffle(items) |
nothing: it shuffles the list in place (like sort(), it returns None) |
sample(items, k) |
a new list of k different items, with no repeats |
Run it a few times: you get different results each time. To get the same "random" sequence every time, which is useful for testing, set a seed with random.seed(42).
statistics
import statistics temps = [21.5, 19.0, 24.3, 22.8, 18.1, 22.8] print(statistics.mean(temps)) print(statistics.median(temps)) print(statistics.mode(temps)) print(round(statistics.stdev(temps), 2))
| Function | Meaning | Here |
|---|---|---|
mean() |
the average: the total divided by the count | about 21.42 |
median() |
the middle value once sorted (with an even count, halfway between the two middle ones) | 22.15 |
mode() |
the most common value | 22.8 (it appears twice) |
stdev() |
the standard deviation: how spread out the values are | 2.41 |
collections
Counter counts things for you, and defaultdict creates missing keys automatically:
from collections import Counter, defaultdict
words = "the cat and the dog and the bird".split()
counts = Counter(words)
print(counts)
print(counts.most_common(2))
groups = defaultdict(list)
for word in words:
groups[len(word)].append(word)
print(dict(groups))With a normal dictionary, groups[3].append("the") would be a KeyError the first time, because key 3 doesn't exist yet. defaultdict(list) fixes that: whenever you use a missing key, it first creates it with a new empty list (list() gives []). Here that sorts the words by length: {3: [...], 4: ['bird']}. dict(groups) just turns it into a plain dictionary for printing.
string, time and more
import string
import time
print(string.ascii_lowercase)
print(string.digits)
start = time.time()
total = sum(range(1_000_000))
print(f"Took {time.time() - start:.3f} seconds")Exploring a module
dir() lists what a module contains, and help() shows its documentation:
import random
names = [n for n in dir(random) if not n.startswith("_")]
print(names)dir(random) lists every name inside the module. Names starting with _ are for the module's own internal use, so the comprehension filters them out. Try help(random.choice) to read about one function.
Creating your own module
Any .py file is a module. Normally you'd create a second file in your editor. Here we'll write one from code, then import it:
code = '''
def greet(name):
return f"Hello, {name}!"
PI_ROUGH = 3.14
'''
with open("helpers.py", "w") as f:
f.write(code)
import importlib
import helpers
# pick up edits on the next run
importlib.reload(helpers)
print(helpers.greet("Ada"))
print(helpers.PI_ROUGH)You'll learn about open() and with in the next lesson.
Don't give your own file the same name as a module you want to use. A file called random.py next to your program is found before the standard library's random, so import random loads your file instead, and random.randint stops working.
Python imports a module only once per session and then reuses it. That's why the example calls importlib.reload(): without it, editing code and running again would still show the old version. In normal programs you rarely need this.
The if __name__ == "__main__" check
When a file is run directly, Python sets its special variable __name__ to "__main__". When it's imported, __name__ is the module's name instead. That lets a file contain test code that runs only when it's run directly:
print("This file's __name__ is:", __name__)
def main():
print("Running as a program")
if __name__ == "__main__":
main()Here the file is being run directly, so it prints __main__ and main() runs. If another file did import this one, __name__ would be its module name, the if would be False, and main() wouldn't run, so importing the file only makes its functions available.
Installing third-party packages
Beyond the standard library, thousands of packages are available from PyPI, the Python Package Index. On your own computer you install them with pip install package-name. In this browser environment, many popular packages such as numpy load automatically the first time you import them:
import numpy as np data = np.array([1, 2, 3, 4, 5]) print(data * 10) print(data.mean())
The first run takes a few seconds while the package downloads.
Exercises
Exercise 1: Dice roller
Use the random module to roll two six-sided dice and print both values and their total.
# roll two dice
random.randint(1, 6) gives a whole number from 1 to 6, both included.
Call it twice, store both results, and add them up for the total.
Exercise 2: Circle maths
Import only pi and sqrt from math. Print the area of a circle with radius 3 (to 2 decimals), and the radius of a circle whose area is 50 (to 2 decimals). It should print 28.27 and 3.99.
# import pi and sqrt from math
from math import pi, sqrt imports just those two names.
The area is pi * 3 ** 2. For the radius, rearrange the formula: sqrt(50 / pi). Round both to 2 decimals.
Exercise 3: Most common letters
Use collections.Counter to find the three most common letters in the sentence, ignoring spaces.
sentence = "the quick brown fox jumps over the lazy dog"
Remove the spaces first with .replace(" ", "").
Pass the result to Counter(...) and call .most_common(3).
Exercise 4: Random password
Use random.choice and the string module to build an 8-character password from letters and digits.
import random import string
string.ascii_letters + string.digits gives every character you can pick from.
Pick one with random.choice() eight times and join them: "".join(... for _ in range(8)).
Useful module functions at a glance
A quick reference for later. Results marked "e.g." are random and change on every run. The statistics examples use data = [2, 4, 4, 5, 7].
| Function | What it does | Example | Result |
|---|---|---|---|
random.randint(a, b) |
A random whole number from a to b, both included |
random.randint(1, 6) |
e.g. 4 |
random.random() |
A random float from 0 up to (not including) 1 | random.random() |
e.g. 0.7134 |
random.choice(items) |
One random item | random.choice(["rock", "paper", "scissors"]) |
e.g. 'paper' |
random.sample(items, k) |
k different random items |
random.sample(range(1, 50), 3) |
e.g. [7, 31, 12] |
random.shuffle(items) |
Shuffles a list in place | random.shuffle(cards) |
cards in a new order |
random.seed(n) |
Makes the "random" results repeatable | random.seed(42) |
the same results every run |
statistics.mean(data) |
The average | statistics.mean(data) |
4.4 |
statistics.median(data) |
The middle value | statistics.median(data) |
4 |
statistics.mode(data) |
The most common value | statistics.mode(data) |
4 |
statistics.stdev(data) |
How spread out the values are | round(statistics.stdev(data), 2) |
1.82 |
Counter(items) |
Counts each item | Counter("banana").most_common(1) |
[('a', 3)] |
defaultdict(list) |
A dictionary that creates missing keys automatically | defaultdict(list)["new"] |
[] |
string.ascii_lowercase |
The letters a to z | string.ascii_lowercase[:5] |
'abcde' |
string.digits |
The characters 0 to 9 | string.digits |
'0123456789' |
time.time() |
Seconds since 1 January 1970; subtract two of them to time code | time.time() |
e.g. 1791234567.89 |
time.sleep(seconds) |
Pauses the program | time.sleep(0.5) |
waits half a second |
dir(module) |
Lists everything in a module | dir(math) |
a list of names, such as 'pi' and 'sqrt' |
Summary
- A module is a reusable file of Python code. The standard library ships with Python.
import modulegives youmodule.name, andfrom module import namegives younamedirectly.ascreates an alias:import statistics as stats.- Handy modules include
math,random,statistics,collections,stringandtime. - Any
.pyfile is a module. Useif __name__ == "__main__":for code that should run only when the file runs directly. - Third-party packages come from PyPI and are installed with
pip.
Know something worth teaching? Write your own tutorial with runnable examples and share it.