Module Concept in Python
Python stores much of its reusable code in modules. A module can contain functions, constants, classes, and other names without placing all of them in the global namespace.
An import loads a module when needed and binds a name through which your code can reach its public members. The standard library already supplies well-tested mathematical operations. Reusing them avoids mistakes from rewriting the formulas yourself.
The math Module for Mathematical Functions
The math module provides real-valued functions and constants. It accepts compatible real numbers such as int and float, but does not accept complex values for operations such as sqrt(). Use cmath when the domain or result may be complex.
How to Import the math Module
Python offers several ways to import a module, and the choice affects how each later call looks. You can import the whole module, import selected names from it, or rename the module during the import.
Basic Import with Namespace
The statement import math imports the module under the math namespace. Functions and constants are then accessed with names such as math.sqrt and math.pi.
import math
# Using sqrt function with math prefix
print(math.sqrt(9)) # Output: 3.0
# Accessing pi constant
print(math.pi) # Output: 3.141592653589793
# If trying without prefix, an error will occur
# sqrt(9) # NameError: name 'sqrt' is not definedImport with Alias
An alias binds the module to another local name. Use one only when it follows an established convention or resolves a genuine naming conflict. math is already short and explicit.
import math as m
# Import math under the shorter alias 'm'
print(m.sqrt(9)) # Output: 3.0
print(m.pi) # Output: 3.141592653589793
# This import binds m, not math
# math.sqrt(9) # NameError: name 'math' is not definedImport All Functions
This form imports every public name from math into the current namespace. It may be convenient in a disposable interactive session, but application code should avoid it.
from math import *
# Functions can be called directly without prefix
print(sqrt(9)) # Output: 3.0
print(pi) # Output: 3.141592653589793
# Name 'math' is not available because it wasn't imported
# math.sqrt(9) # NameError: name 'math' is not definedfrom math import * places every public name from math in the current namespace. If one of those names is already in use, the value from math replaces it without an error. The code also stops showing which module supplied each name, and a later change to math can add new names to the importing module. An explicit import lists every dependency on the import line.
Import Specific Functions
Import only the functions the program uses. The function name remains available without a module prefix, while the import line still records its source.
from math import sqrt
# sqrt function can be called directly
print(sqrt(9)) # Output: 3.0
# pi constant is not available because it wasn't imported
# print(pi) # NameError: name 'pi' is not defined
# Name 'math' is also not available
# math.sqrt(9) # NameError: name 'math' is not definedImport with Function Alias
An imported function can receive an alias to resolve a name conflict or follow an established local convention.
from math import factorial as fac
# Using alias 'fac' for factorial function
print(fac(5)) # Output: 120
# Original name 'factorial' is not available
# factorial(5) # NameError: name 'factorial' is not defined
# Same with 'math'
# math.factorial(5) # NameError: name 'math' is not definedBuilt In Functions vs Module Functions
Python provides numeric built-ins such as abs() and round() without an import. They work across types through Python's numeric protocols. Each type can define the operations it supports.
Absolute Value Function
For real numbers, abs() returns a nonnegative magnitude. For a complex number, it returns the distance from the origin.
# Absolute value for negative integer
print(abs(-5)) # Output: 5
# Absolute value for negative float
print(abs(-1.4)) # Output: 1.4
# Absolute value for complex number (modulus)
print(abs(4 + 3j)) # Output: 5.0The result for 4 + 3j is because . Python writes the imaginary unit as j, while the mathematical formula conventionally uses .
Rounding Function
For Python's built-in numeric types, round() rounds to the nearest value and resolves exact halfway cases by rounding to even. Without ndigits, round() returns an integer for a float. Pass ndigits as the second argument to choose the place value used for rounding.
# Standard rounding
print(round(-3.8)) # Output: -4
print(round(3.5)) # Output: 4
print(round(4.5)) # Output: 4
# Rounding with specific precision
print(round(3.141592653589793, 3)) # Output: 3.142
print(round(1234.4321, -2)) # Output: 1200.0round(4.5) produces , while round(3.5) produces . Decimal-looking float values are stored in binary, so a value that appears to be an exact tie may not be one internally. Use decimal arithmetic when a domain requires decimal rounding rules.
Functions and Constants in the math Module
Each math function has a domain. For example, sqrt(x) requires a nonnegative real input and logarithms require positive real inputs. A value outside the domain raises a ValueError instead of returning a number.
Square Root and Logarithm Functions
The example calls the square root and logarithm functions, and it shows how Python reports an input outside the allowed domain.
import math
# Square root function
print(f"Square root of 16: {math.sqrt(16)}") # Output: Square root of 16: 4.0
# Exponential function (e^x)
print(f"e to the power of 2: {math.exp(2)}") # Output: e to the power of 2: 7.38905609893065
# Natural logarithm function
print(f"ln(10): {math.log(10)}") # Output: ln(10): 2.302585092994046
# Base 10 logarithm function
print(f"log10(100): {math.log10(100)}") # Output: log10(100): 2.0
# Logarithm with specific base
print(f"log2(8): {math.log(8, 2)}") # Output: log2(8): 3.0
try:
math.sqrt(-1)
except ValueError as error:
print(type(error).__name__)
# Output: ValueErrorTrigonometry Functions
The trigonometry functions expect radians. The example converts an angle and calls the three primary functions.
import math
# Trigonometry functions (input in radians)
angle_rad = math.pi / 4 # 45 degrees in radians
print(f"sin(π/4): {math.sin(angle_rad)}") # Output: sin(π/4): 0.7071067811865475
print(f"cos(π/4): {math.cos(angle_rad)}") # Output: cos(π/4): 0.7071067811865476
print(f"tan(π/4): {math.tan(angle_rad)}") # Output: tan(π/4): 0.9999999999999999
# Converting degrees to radians
angle_deg = 45
angle_rad = math.radians(angle_deg)
print(f"45 degrees = {angle_rad} radians") # Output: 45 degrees = 0.7853981633974483 radiansCeiling Floor and Factorial Functions
Rounding up, rounding down, and factorial answer different questions. The example applies each function and prints the result.
import math
number = 4.7
# Ceiling: smallest integer >= x
print(f"ceil(4.7): {math.ceil(number)}") # Output: ceil(4.7): 5
# Floor: largest integer <= x
print(f"floor(4.7): {math.floor(number)}") # Output: floor(4.7): 4
# Factorial
print(f"5!: {math.factorial(5)}") # Output: 5!: 120Mathematical Constants
The module also exposes constants, including finite mathematical constants and special floating-point values.
import math
# Pi constant (π ≈ 3.141592...)
print(f"Value of π: {math.pi}")
# e constant (Euler's number ≈ 2.718281...)
print(f"Value of e: {math.e}")
# Infinity (positive infinity)
print(f"Infinity: {math.inf}")
# Not a Number
print(f"NaN: {math.nan}")
# Example usage of constants
circle_radius = 5
circle_area = math.pi * circle_radius ** 2
print(f"Circle area with radius {circle_radius}: {circle_area}")Choosing the Right Import Method
Choose an import style that shows the module name at each call when that context matters, and introduce only the names the program actually uses. A single function used once reads well as from math import sqrt, while several calls are clearer with import math.
Guide to Choosing Import Methods
Pick the import style from how many names you need and how readable the call site stays. The list below orders the options from the most explicit to the least.
- Prefer
import mathwhen the program uses several members. Calls such asmath.sqrt()keep the module name next to the function. - Use
import math as mdeliberately only when the alias is a documented local convention. - Use
from math import sqrt, piwhen a small set of unambiguous names improves the local code. - Avoid
from math import *because its names have no module prefix and can replace names that the program already uses.
Calculating Distance and Area
For points (0, 0) and (3, 4), the Euclidean distance is the square root of the sum of squared coordinate differences. For sides 3, 4, and 5, Heron’s formula agrees with the right-triangle area formula.
import math
def calculate_euclidean_distance(x1, y1, x2, y2):
"""Calculate Euclidean distance between two points"""
return math.hypot(x2 - x1, y2 - y1)
def calculate_triangle_area(a, b, c):
"""Calculate triangle area using Heron's formula"""
if not all(math.isfinite(side) for side in (a, b, c)):
raise ValueError("Side lengths must be finite")
if min(a, b, c) <= 0:
raise ValueError("Side lengths must be positive")
if a + b <= c or a + c <= b or b + c <= a:
raise ValueError("Side lengths must form a triangle")
# Calculate semi-perimeter
s = (a + b + c) / 2
# Heron's formula
area = math.sqrt(s * (s - a) * (s - b) * (s - c))
return area
# Usage example
point1 = (0, 0)
point2 = (3, 4)
distance = calculate_euclidean_distance(*point1, *point2)
print(f"Distance between {point1} and {point2}: {distance}")
# Calculate triangle area with sides 3, 4, 5
area = calculate_triangle_area(3, 4, 5)
print(f"Triangle area with sides 3, 4, 5: {area}")Clear numerical code makes three decisions explicit: which namespace owns an operation, which input domain the operation accepts, and how exceptional inputs are handled. Those decisions matter more than shortening a function name by a few characters.