TheAlgorithms/Python · error · ValueError

number_of_compounding_periods must be > 0

Error message

number_of_compounding_periods must be > 0

What it means

Raised by compound_interest() in financial/interest.py when number_of_compounding_periods <= 0. The formula principal * ((1 + r)**n - 1) needs at least one compounding period to be meaningful; the check runs first, before rate and principal, so it fires even for otherwise-bad inputs.

Source

Thrown at financial/interest.py:68

    >>> compound_interest(10000.0, 0.05, 1)
    500.00000000000045
    >>> compound_interest(0.5, 0.05, 3)
    0.07881250000000006
    >>> compound_interest(10000.0, 0.06, -4)
    Traceback (most recent call last):
        ...
    ValueError: number_of_compounding_periods must be > 0
    >>> compound_interest(10000.0, -3.5, 3.0)
    Traceback (most recent call last):
        ...
    ValueError: nominal_annual_interest_rate_percentage must be >= 0
    >>> compound_interest(-5500.0, 0.01, 5)
    Traceback (most recent call last):
        ...
    ValueError: principal must be > 0
    """
    if number_of_compounding_periods <= 0:
        raise ValueError("number_of_compounding_periods must be > 0")
    if nominal_annual_interest_rate_percentage < 0:
        raise ValueError("nominal_annual_interest_rate_percentage must be >= 0")
    if principal <= 0:
        raise ValueError("principal must be > 0")

    return principal * (
        (1 + nominal_annual_interest_rate_percentage) ** number_of_compounding_periods
        - 1
    )


def apr_interest(
    principal: float,
    nominal_annual_percentage_rate: float,
    number_of_years: float,
) -> float:
    """
    >>> apr_interest(10000.0, 0.05, 3)

View on GitHub (pinned to f5988cc097)

Solutions

  1. Pass the total number of compounding periods, e.g. years * periods_per_year (12 for monthly over 3 years -> 36).
  2. Validate n > 0 upstream, especially when it is a computed product of two config values.
  3. For fractional-period needs, use a formula that supports continuous or fractional compounding instead of this function.

Example fix

# before
ci = compound_interest(10000.0, 0.05, 0)  # ValueError

# after
ci = compound_interest(10000.0, 0.05, 3 * 12)  # monthly compounding for 3 years
Defensive patterns

Strategy: validation

Validate before calling

if number_of_compounding_periods <= 0:
    raise InputError("periods must be >= 1; use years * periods_per_year")

Type guard

def valid_periods(n) -> bool:
    return isinstance(n, (int, float)) and n > 0

Try / catch

try:
    ci = compound_interest(principal, rate, periods)
except ValueError as exc:
    raise InputError(str(exc)) from exc

Prevention

When it happens

Trigger: compound_interest(10000.0, 0.05, 0) or a negative period count; passing a period interval (e.g. 0.25 for quarterly) instead of the number of periods; counter variables that never increment because a loop body is skipped.

Common situations: Confusing compounding frequency (4 for quarterly) with total periods (years*4); off-by-one loops building amortization tables; defaults of 0 in config schemas.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/702df2c67ef554c0. Report an issue: GitHub.