Lesson 12 of 2012 min read

Modules

Share:WhatsAppLinkedIn

Prerequisites: Variables, data types, operators, functions


1. What is a Module?

A module is a Python file (.py) containing functions, classes, and variables that you can import and reuse in other programs.

Why use modules?

  • Code reuse, use pre-written, tested code
  • Organization, keep related functions together
  • Namespace management, avoid name conflicts

Python has many built-in modules (math, random, statistics, os, etc.) plus thousands of third-party modules.


2. Importing Modules

2.1 import, Import entire module

import math

print(math.sqrt(16))
print(math.pi)

Output:

4.0
3.141592653589793

You must use the module name as prefix: math.sqrt, not just sqrt.

2.2 from ... import, Import specific items

from math import sqrt, pi

print(sqrt(16)) # no prefix needed
print(pi)

Output:

4.0
3.141592653589793

2.3 from ... import *, Import everything (not recommended)

from math import *

print(sqrt(16))
print(pi)
print(ceil(3.2))

Output:

4.0
3.141592653589793
4

Why not recommended: It imports all names into your namespace, which can cause name conflicts and makes it hard to tell where a function came from.

2.4 import ... as, Import with alias

import math as m

print(m.sqrt(16))
print(m.pi)

Output:

4.0
3.141592653589793

2.5 Import Methods Comparison

Method Syntax Usage When to use
import math Full module math.sqrt(16) Best practice, clear origin
from math import sqrt Specific item sqrt(16) When using few functions often
from math import * Everything sqrt(16) Avoid in production code
import math as m Alias m.sqrt(16) When module name is long

3. The math Module

The math module provides mathematical functions and constants.

import math

3.1 Constants

import math

print(math.pi) # 3.141592653589793
print(math.e) # 2.718281828459045

Output:

3.141592653589793
2.718281828459045

3.2 math.sqrt, Square root

import math

print(math.sqrt(16)) # 4.0
print(math.sqrt(2)) # 1.4142135623730951
# print(math.sqrt(-1)) # ValueError: math domain error

Output:

4.0
1.4142135623730951

3.3 math.ceil, Round up to nearest integer

import math

print(math.ceil(3.2)) # 4
print(math.ceil(3.9)) # 4
print(math.ceil(-3.2)) # -3
print(math.ceil(5.0)) # 5

Output:

4
4
-3
5

3.4 math.floor, Round down to nearest integer

import math

print(math.floor(3.2)) # 3
print(math.floor(3.9)) # 3
print(math.floor(-3.2)) # -4
print(math.floor(5.0)) # 5

Output:

3
3
-4
5

3.5 math.pow, Power (returns float)

import math

print(math.pow(2, 3)) # 8.0
print(math.pow(5, 2)) # 25.0
print(math.pow(9, 0.5)) # 3.0 (same as sqrt)

Output:

8.0
25.0
3.0

Note: math.pow always returns float. The built-in ** operator and pow function can return int.

print(2 ** 3) # 8 (int)
print(pow(2, 3)) # 8 (int)
print(math.pow(2, 3)) # 8.0 (float)

3.6 math.fabs, Absolute value (returns float)

import math

print(math.fabs(-5)) # 5.0
print(math.fabs(3.14)) # 3.14
print(abs(-5)) # 5 (built-in, returns int for int input)

Output:

5.0
3.14
5

3.7 Trigonometric Functions

Important: These use radians, not degrees. Convert degrees to radians using math.radians.

import math

# Convert degrees to radians
angle = math.radians(90) # 90 degrees in radians

print(math.sin(angle)) # 1.0
print(math.cos(angle)) # ~0 (very small number due to floating point)
print(math.tan(math.radians(45))) # ~1.0

# sin(30) = 0.5
print(math.sin(math.radians(30))) # 0.49999999999999994

# Convert radians to degrees
print(math.degrees(math.pi)) # 180.0

Output:

1.0
6.123233995736766e-17
0.9999999999999999
0.49999999999999994
180.0

3.8 math.log and math.log10

import math

# Natural log (base e)
print(math.log(1)) # 0.0
print(math.log(math.e)) # 1.0

# Log with specified base
print(math.log(8, 2)) # 3.0 (log base 2 of 8)
print(math.log(100, 10)) # 2.0

# Log base 10
print(math.log10(100)) # 2.0
print(math.log10(1000)) # 3.0

Output:

0.0
1.0
3.0
2.0
2.0
3.0

3.9 math.factorial

import math

print(math.factorial(5)) # 120
print(math.factorial(0)) # 1
print(math.factorial(10)) # 3628800
# print(math.factorial(-1)) # ValueError

Output:

120
1
3628800

3.10 math Module Quick Reference

Function Purpose Example Result
math.pi Pi constant math.pi 3.14159...
math.e Euler's number math.e 2.71828...
math.sqrt(x) Square root math.sqrt(25) 5.0
math.ceil(x) Round up math.ceil(3.2) 4
math.floor(x) Round down math.floor(3.9) 3
math.pow(x, y) x to the power y math.pow(2, 3) 8.0
math.fabs(x) Absolute value math.fabs(-5) 5.0
math.sin(x) Sine (radians) math.sin(math.pi/2) 1.0
math.cos(x) Cosine (radians) math.cos(0) 1.0
math.tan(x) Tangent (radians) math.tan(math.pi/4) 1.0
math.log(x) Natural log math.log(math.e) 1.0
math.log10(x) Log base 10 math.log10(100) 2.0
math.factorial(x) Factorial math.factorial(5) 120
math.radians(x) Degrees to radians math.radians(180) 3.14...
math.degrees(x) Radians to degrees math.degrees(math.pi) 180.0

4. The random Module

The random module generates pseudo-random numbers.

import random

4.1 random.random, Random float in [0.0, 1.0)

import random

print(random.random) # e.g., 0.7234561289
print(random.random) # e.g., 0.1456782390

Output (varies each run):

0.7234561289043521
0.14567823901289745

4.2 random.randint(a, b), Random integer in [a, b]

Both endpoints are included.

import random

print(random.randint(1, 6)) # random integer 1 to 6 (like a dice)
print(random.randint(1, 100)) # random integer 1 to 100
print(random.randint(5, 5)) # always 5

Output (varies each run):

4
73
5

4.3 random.randrange(start, stop[, step])

Random integer from range(start, stop, step). The stop value is excluded.

import random

print(random.randrange(1, 7)) # 1 to 6 (stop excluded)
print(random.randrange(0, 10, 2)) # random even: 0, 2, 4, 6, or 8
print(random.randrange(10)) # 0 to 9

Output (varies each run):

3
6
7

Difference: randint(1, 6) includes 6; randrange(1, 7) also includes up to 6 but the syntax is different (stop is excluded in randrange).

4.4 random.choice(sequence), Pick one random element

import random

colors = ["red", "green", "blue", "yellow"]
print(random.choice(colors))

print(random.choice("HELLO")) # random character from string
print(random.choice(range(100))) # same as randrange(100)

Output (varies each run):

green
L
42

4.5 random.shuffle(list), Shuffle list in place

import random

cards = [1, 2, 3, 4, 5]
print("Before:", cards)

random.shuffle(cards)
print("After:", cards)

Output (varies each run):

Before: [1, 2, 3, 4, 5]
After: [3, 1, 5, 2, 4]

Note: shuffle modifies the list in place and returns None. It only works with lists (mutable sequences).

4.6 random.uniform(a, b), Random float in [a, b]

import random

print(random.uniform(1, 10)) # random float between 1 and 10
print(random.uniform(0.5, 1.5)) # random float between 0.5 and 1.5

Output (varies each run):

7.345612890435216
0.8912345678901234

4.7 random Module Quick Reference

Function Purpose Range Returns
random.random Random float [0.0, 1.0) float
random.randint(a, b) Random integer [a, b] (both included) int
random.randrange(start, stop, step) Random from range [start, stop) int
random.choice(seq) Random element from sequence element type
random.shuffle(list) Shuffle in place , None
random.uniform(a, b) Random float [a, b] float

5. The statistics Module

The statistics module provides functions for statistical calculations.

import statistics

5.1 statistics.mean, Arithmetic mean (average)

import statistics

data = [10, 20, 30, 40, 50]
print(statistics.mean(data))

Output:

30

5.2 statistics.median, Middle value

import statistics

# Odd number of elements
data1 = [1, 3, 5, 7, 9]
print(statistics.median(data1)) # 5 (middle element)

# Even number of elements
data2 = [1, 3, 5, 7]
print(statistics.median(data2)) # 4.0 (average of two middle)

Output:

5
4.0

5.3 statistics.mode, Most frequent value

import statistics

data = [1, 2, 2, 3, 3, 3, 4]
print(statistics.mode(data))

words = ["apple", "banana", "apple", "cherry", "apple"]
print(statistics.mode(words))

Output:

3
apple

5.4 statistics Module Quick Reference

Function Purpose Example Result
statistics.mean(data) Average mean([1,2,3,4,5]) 3
statistics.median(data) Middle value median([1,3,5,7,9]) 5
statistics.mode(data) Most frequent mode([1,2,2,3]) 2

6. Practice Programs

Program 1: Calculate area of circle using math.pi

import math

radius = float(input("Enter radius: "))
area = math.pi * radius ** 2
circumference = 2 * math.pi * radius

print(f"Area = {area:.2f}")
print(f"Circumference = {circumference:.2f}")

Sample Run:

Enter radius: 7
Area = 153.94
Circumference = 43.98

Program 2: Generate random number between 1-100

import random

number = random.randint(1, 100)
print(f"Random number: {number}")

# Guessing game
secret = random.randint(1, 100)
attempts = 0

while True:
 guess = int(input("Guess the number (1-100): "))
 attempts += 1

 if guess < secret:
 print("Too low!")
 elif guess > secret:
 print("Too high!")
 else:
 print(f"Correct! You got it in {attempts} attempts!")
 break

Sample Run:

Guess the number (1-100): 50
Too high!
Guess the number (1-100): 25
Too low!
Guess the number (1-100): 37
Correct! You got it in 3 attempts!

Program 3: Dice simulator (1-6)

import random

def roll_dice:
 return random.randint(1, 6)

print("Dice Simulator")
print("=" * 20)

while True:
 input("Press Enter to roll the dice...")
 result = roll_dice
 print(f"You rolled: {result}")

 play_again = input("Roll again? (y/n): ")
 if play_again.lower != 'y':
 break

print("Thanks for playing!")

Sample Run:

Dice Simulator
====================
Press Enter to roll the dice...
You rolled: 4
Roll again? (y/n): y
Press Enter to roll the dice...
You rolled: 2
Roll again? (y/n): n
Thanks for playing!

Extended: Simulate 1000 rolls and show frequency:

import random

freq = {i: 0 for i in range(1, 7)}

for _ in range(1000):
 roll = random.randint(1, 6)
 freq[roll] += 1

print("Results of 1000 dice rolls:")
for face, count in freq.items:
 bar = "#" * (count // 5)
 print(f" {face}: {count:4d} {bar}")

Program 4: Random password generator

import random
import string

def generate_password(length=8):
 # Characters to use
 lowercase = string.ascii_lowercase # a-z
 uppercase = string.ascii_uppercase # A-Z
 digits = string.digits # 0-9
 special = "!@#$%&*"

 all_chars = lowercase + uppercase + digits + special

 # Ensure at least one of each type
 password = [
 random.choice(lowercase),
 random.choice(uppercase),
 random.choice(digits),
 random.choice(special),
 ]

 # Fill remaining length
 for i in range(length - 4):
 password.append(random.choice(all_chars))

 # Shuffle to randomize position
 random.shuffle(password)

 return "".join(password)

# Generate passwords
length = int(input("Enter password length (min 4): "))
if length < 4:
 length = 4

for i in range(3):
 print(f"Password {i+1}: {generate_password(length)}")

Sample Run:

Enter password length (min 4): 10
Password 1: k4#Bm7xR!p
Password 2: N2&jYq8Lm#
Password 3: 5rT@wK9!bz

Simpler version (without string module):

import random

def generate_password(length=8):
 chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*"
 password = ""
 for i in range(length):
 password += random.choice(chars)
 return password

print("Password:", generate_password(10))

Program 5: Calculate mean, median, mode of a list

import statistics

data = input("Enter numbers separated by spaces: ")
numbers = [float(x) for x in data.split]

print(f"\nData: {numbers}")
print(f"Mean: {statistics.mean(numbers)}")
print(f"Median: {statistics.median(numbers)}")

try:
 print(f"Mode: {statistics.mode(numbers)}")
except statistics.StatisticsError:
 print("Mode: No unique mode")

Sample Run:

Enter numbers separated by spaces: 1 2 2 3 4 4 4 5

Data: [1.0, 2.0, 2.0, 3.0, 4.0, 4.0, 4.0, 5.0]
Mean: 3.125
Median: 3.5
Mode: 4.0

Without statistics module (manual calculation):

def mean(data):
 return sum(data) / len(data)

def median(data):
 sorted_data = sorted(data)
 n = len(sorted_data)
 mid = n // 2
 if n % 2 == 0:
 return (sorted_data[mid - 1] + sorted_data[mid]) / 2
 else:
 return sorted_data[mid]

def mode(data):
 freq = {}
 for item in data:
 freq[item] = freq.get(item, 0) + 1
 max_count = max(freq.values)
 for item, count in freq.items:
 if count == max_count:
 return item

numbers = [1, 2, 2, 3, 4, 4, 4, 5]
print("Mean:", mean(numbers))
print("Median:", median(numbers))
print("Mode:", mode(numbers))

Program 6: Trigonometric values table (0-90 degrees)

import math

print(f"{'Angle':>6} {'sin':>10} {'cos':>10} {'tan':>10}")
print("-" * 40)

for degree in range(0, 91, 15):
 radian = math.radians(degree)
 sin_val = math.sin(radian)
 cos_val = math.cos(radian)

 if degree == 90:
 tan_val = "undefined"
 else:
 tan_val = f"{math.tan(radian):10.4f}"

 print(f"{degree:>6} {sin_val:10.4f} {cos_val:10.4f} {tan_val:>10}")

Output:

 Angle sin cos tan
----------------------------------------
 0 0.0000 1.0000 0.0000
 15 0.2588 0.9659 0.2679
 30 0.5000 0.8660 0.5774
 45 0.7071 0.7071 1.0000
 60 0.8660 0.5000 1.7321
 75 0.9659 0.2588 3.7321
 90 1.0000 0.0000 undefined

7. Common Mistakes

Mistake Why it is wrong Correct way
sqrt(16) without import Function not defined import math then math.sqrt(16)
from math import * then log = 5 Overwrites math.log accidentally Use import math for clarity
math.sqrt(-1) Domain error for negative numbers Check if n >= 0 first
random.randint(1, 6) expecting 1-5 randint includes both endpoints Use randrange(1, 6) for 1-5
random.shuffle("hello") Strings are immutable Convert to list first
result = random.shuffle(L) shuffle returns None Call random.shuffle(L), then use L
Forgetting math.radians for trig math.sin(90) is not sin(90 degrees) math.sin(math.radians(90))

$1$2 Quick Tips

  1. Know all three import styles and the difference between them. Questions often ask you to rewrite code using a different import style.

  2. math.ceil vs math.floor, know how they behave with negative numbers. ceil(-3.2) is -3, floor(-3.2) is -4.

  3. random.randint vs random.randrange, randint(1, 6) includes 6; randrange(1, 7) also gives 1-6 but with different syntax.

  4. random.shuffle returns None and modifies the list in place. This is a common trap in output questions.

  5. Trigonometric functions use radians. Always convert degrees to radians with math.radians. This is a classic mistake in exams.

  6. statistics module is relatively recent. Know mean, median, and mode, that is usually sufficient.

  7. Common exam question format: Given a code snippet using a module, predict the output. Pay attention to:

  • Whether the module is imported correctly
  • Whether function names are prefixed with the module name
  • The exact range of random functions (included/excluded endpoints)
  1. math.pow always returns float, while the ** operator can return int. math.pow(2, 3) gives 8.0, not 8.

Test Your Knowledge

Take a quick quiz on this lesson

Start Quiz →

Prefer watching over reading?

Subscribe for free.

Subscribe on YouTube