Implementing Summations in Python

Python · Concrete Mathematics

Implementing Summations in Python

If a loop runs 1 time, then 2 times, then 3 times, how much work did it do overall? That question turns into a summation. This is one of the first places where concrete mathematics becomes useful to programmers, because it lets you turn “a growing pile of steps” into code and, sometimes, into one fast formula.

What a summation actually means

A summation is a compact way to say “add a sequence of values.” Instead of writing every term one by one, mathematicians use the Greek letter sigma:

$$\sum_{k=1}^{n} k$$

That notation can look intimidating at first, but it is just instructions for repeated addition.

Part Meaning
\(\sum\) Add the terms that follow
\(k=1\) Start the counter at 1
\(n\) Stop at \(n\), inclusive
\(k\) The value being added each time

So if n = 5, this becomes:

\(\sum_{k=1}^{5} k = 1 + 2 + 3 + 4 + 5 = 15\)

The part after the sigma does not have to be just k. It could be , 2k + 1, or another expression involving k. For example:

\(\sum_{k=1}^{5} k^2 = 1 + 4 + 9 + 16 + 25 = 55\)

Turning the math into Python

Python already has a built-in tool for adding values: sum(). That makes it a natural fit for summations.

from typing import Callable


def summation(func: Callable[[int], float], start: int, end: int) -> float:
    """Return func(start) + func(start + 1) + ... + func(end)."""
    if end < start:
        return 0
    return sum(func(k) for k in range(start, end + 1))

Why end + 1?

Python’s range(a, b) stops before b. Adding 1 makes the upper limit inclusive, which matches standard summation notation.

Why return 0 for an empty sum?

If end < start, returning 0 matches the usual mathematical convention and makes the helper safer in real code.

Here is the sum of the first 10 positive integers:

result = summation(lambda k: k, 1, 10)
print(result)
# 55

That lambda k: k means “use k itself as the value to add.”

Why programmers care about closed forms

The helper above is correct and readable, but it still loops through every value from start to end. Sometimes you can do better.

A closed form is a direct formula that gives the result without stepping through every term one at a time. For this summation:

$$\sum_{k=1}^{n} k = \frac{n(n+1)}{2}$$
def closed_form(n: int) -> int:
    """Return 1 + 2 + ... + n for n >= 0."""
    if n < 0:
        raise ValueError("n must be non-negative")
    return n * (n + 1) // 2
Why use // here? Because \(n(n+1)\) is always even, dividing by 2 is exact. Integer division keeps the result as an integer instead of turning it into a float.

That means a formula can replace a whole loop. For large inputs, that matters.

Check the formula against the loop

Whenever you use a closed form, it is smart to compare it to a direct implementation for small inputs. That gives you a quick sanity check before you trust the formula.

print("n | loop | closed form | match")
print("-" * 34)

for n in range(0, 11):
    loop_value = summation(lambda k: k, 1, n)
    formula_value = closed_form(n)
    print(f"{n:2} | {loop_value:4} | {formula_value:11} | {loop_value == formula_value}")
This is one of the best habits in mathematical programming: verify the elegant formula against the boring version before you rely on it.

The same pattern works for more than integers

Once you have the idea, you can reuse it for many other summations. A classic example is the sum of squares:

$$\sum_{k=1}^{n} k^2 = \frac{n(n+1)(2n+1)}{6}$$
def sum_of_squares_loop(n: int) -> int:
    if n < 0:
        raise ValueError("n must be non-negative")
    return sum(k * k for k in range(1, n + 1))


def sum_of_squares_closed(n: int) -> int:
    if n < 0:
        raise ValueError("n must be non-negative")
    return n * (n + 1) * (2 * n + 1) // 6

The loop version is easy to reason about. The closed form is dramatically faster once you already know the identity.

What this changes in real programming

Summations appear everywhere in algorithm analysis. The moment you ask, “What is the total work done by this loop?” you are usually one step away from a summation.

That is why this topic matters. It helps you:

Skill Why it helps
Translate math into code You can test ideas directly instead of leaving them on paper
Verify formulas You can compare a direct implementation against a closed form
Reason about performance You start seeing when a formula can replace repeated work

If you are trying to get stronger at Python and mathematical thinking at the same time, summations are one of the best places to start.

Related reading: Mastering Python Coding Practices: Learning from the Best

Comments