Technology  /  Python

๐Ÿ Python 78 guides ยท updated 2026

From first variable to OOP, generators, and real projects โ€” the language that runs everything from data pipelines to AI agents, taught the practical way.

Calculate Pi in Python Without math.pi: Three Algorithms Compared

math.pi gives you 3.141592653589793 instantly. But computing Pi from scratch โ€” without any library โ€” is a much more interesting problem. Three algorithms worth knowing, each using a different mathematical approach.

Algorithm 1: Leibniz Formula

The Leibniz series is the most famous Pi formula and the one most commonly asked about in pair programming interviews:

ฯ€ = 4 ร— (1 - 1/3 + 1/5 - 1/7 + 1/9 - โ€ฆ)

def pi_leibniz(terms):
"""
Approximate Pi using the Leibniz series.
More terms = more accurate, but convergence is slow.
"""
result = 0.0
sign = 1
for i in range(terms):
denominator = 2 * i + 1 # 1, 3, 5, 7, 9, ...
result += sign / denominator
sign *= -1 # alternate signs
return result * 4
print(pi_leibniz(100)) # 3.1315929035585537
print(pi_leibniz(10_000)) # 3.1414926535900345
print(pi_leibniz(1_000_000)) # 3.1415916535897743

The Leibniz formula converges very slowly โ€” you need millions of terms to get decent precision. Good for understanding the concept; not great for performance.

Algorithm 2: Monte Carlo Estimation

Randomly throw points into a 1ร—1 square. The fraction that land inside the quarter-circle of radius 1 approximates ฯ€/4.

import random
def pi_monte_carlo(num_samples):
"""
Approximate Pi using Monte Carlo simulation.
More samples = more accurate, but probabilistic.
"""
inside_circle = 0
for _ in range(num_samples):
x = random.random() # random point in [0, 1)
y = random.random()
if x * x + y * y <= 1.0: # inside unit circle?
inside_circle += 1
return 4 * inside_circle / num_samples
# Results vary each run due to randomness
random.seed(42) # seed for reproducibility
print(pi_monte_carlo(100)) # ~3.12 (rough)
print(pi_monte_carlo(10_000)) # ~3.148 (getting there)
print(pi_monte_carlo(1_000_000)) # ~3.1416 (much better)

Monte Carlo is intuitive and easy to explain, but you need a lot of samples for precision. It converges at O(1/โˆšn) โ€” to gain one digit of accuracy, you need 100ร— more samples.

Algorithm 3: Nilakantha Formula

The Nilakantha series converges much faster than Leibniz:

ฯ€ = 3 + 4/(2ร—3ร—4) - 4/(4ร—5ร—6) + 4/(6ร—7ร—8) - โ€ฆ

def pi_nilakantha(terms):
"""
Approximate Pi using the Nilakantha series.
Converges much faster than Leibniz โ€” accurate to 8 decimal places in ~20 terms.
"""
result = 3.0
sign = 1
for i in range(1, terms + 1):
n = 2 * i
result += sign * 4 / (n * (n + 1) * (n + 2))
sign *= -1
return result
print(pi_nilakantha(5)) # 3.1415925595560743
print(pi_nilakantha(20)) # 3.1415926535897865
print(pi_nilakantha(50)) # 3.141592653589793 (matches math.pi)

Just 50 terms of the Nilakantha formula matches the precision of math.pi. For the same precision, Leibniz needs millions.

Comparing Accuracy

import math
reference = math.pi
for label, value in [
("Leibniz (10k)", pi_leibniz(10_000)),
("Nilakantha (50)", pi_nilakantha(50)),
("Monte Carlo (1M)", pi_monte_carlo(1_000_000)),
]:
error = abs(value - reference)
print(f"{label}: {value:.10f} (error: {error:.2e})")
AlgorithmTerms/SamplesTypical Error
Leibniz10,000~1e-4
Nilakantha50~1e-15
Monte Carlo1,000,000~1e-3 (random)

The Interview Answer

In a pair programming interview, the expected answer is usually the Leibniz formula โ€” it maps directly to the mathematical expression interviewers typically write on a whiteboard. Mention that it converges slowly. If they ask for something faster, Nilakantha is the next step. Monte Carlo demonstrates a different kind of thinking โ€” probabilistic rather than algebraic โ€” and is worth mentioning as an alternative approach.