For AI agents: use /llms.txt for the Nakafa content index.
Python keeps its core language focused and organizes reusable code in modules. A module can own 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, so application code should reuse them instead of recreating formulas carelessly.
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.
Python offers several ways to import modules, each with different characteristics and usage.
The most basic way to import a module is using the import math command. This way, all function and constant names remain bound to the math namespace.
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 definedAn 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
# Using alias 'm' instead of 'math'
print(m.sqrt(9)) # Output: 3.0
print(m.pi) # Output: 3.141592653589793
# Original name 'math' is no longer available
# math.sqrt(9) # NameError: name 'math' is not definedThis 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 * can silently overwrite an existing name, makes each imported name's owner harder to trace, and lets a future module change alter the importing namespace. Explicit imports keep those dependencies reviewable.
A more selective approach is to import only the specific functions needed. This provides direct access without a prefix while maintaining code clarity.
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 definedYou can also give an alias to specific functions when importing them. This is useful for making function names more concise or avoiding name conflicts.
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 definedPython provides numeric built-ins such as abs() and round() without an import. They work across types through Python's numeric protocols: a type can define the operation it supports, rather than Python selecting from several statically overloaded function declarations.
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 .
For Python's built-in numeric types, round() uses round-to-nearest with ties going to the even choice. A call without ndigits returns an integer for a float; a second argument chooses the decimal position.
# Standard rounding
print(round(-3.8)) # Output: -4
print(round(3.5)) # Output: 4
print(round(4.5)) # Output: 4 (not 5!)
# Rounding with specific precision
print(round(3.141592653589793, 3)) # Output: 3.142
print(round(1234.4321, -2)) # Output: 1200.0Therefore round(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.
Each math function has a domain. For example, sqrt(x) requires a nonnegative real input and logarithms require positive real inputs.
import math
# Square root function
print(f"Square root of 16: {math.sqrt(16)}") # Output: 4.0
# Exponential function (e^x)
print(f"e to the power of 2: {math.exp(2)}") # Output: 7.38905609893065
# Natural logarithm function
print(f"ln(10): {math.log(10)}") # Output: 2.302585092994046
# Base 10 logarithm function
print(f"log10(100): {math.log10(100)}") # Output: 2.0
# Logarithm with specific base
print(f"log2(8): {math.log(8, 2)}") # Output: 3.0import math
# Trigonometry functions (input in radians)
angle_rad = math.pi / 4 # 45 degrees in radians
print(f"sin(π/4): {math.sin(angle_rad)}") # Output: 0.7071067811865475
print(f"cos(π/4): {math.cos(angle_rad)}") # Output: 0.7071067811865476
print(f"tan(π/4): {math.tan(angle_rad)}") # Output: 0.9999999999999999
# Converting degrees to radians
angle_deg = 45
angle_rad = math.radians(angle_deg)
print(f"45 degrees = {angle_rad} radians") # Output: 0.7853981633974483import math
number = 4.7
# Ceiling: smallest integer >= x
print(f"ceil(4.7): {math.ceil(number)}") # Output: 5
# Floor: largest integer <= x
print(f"floor(4.7): {math.floor(number)}") # Output: 4
# Factorial
print(f"5!: {math.factorial(5)}") # Output: 120The 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}")Choose an import style that makes ownership obvious at the call site and introduces only the names the module needs.
import math when several members are used and their origin should stay visible.import math as m deliberately only when the alias is a documented local convention.from math import sqrt, pi when a small set of unambiguous names improves the local code.from math import * because it obscures ownership and can create name conflicts.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 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.