{"record":{"id":"702df2c67ef554c0","repo":"TheAlgorithms/Python","slug":"number-of-compounding-periods-must-be-0","errorCode":null,"errorMessage":"number_of_compounding_periods must be > 0","messagePattern":"number_of_compounding_periods must be > 0","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"financial/interest.py","lineNumber":68,"sourceCode":"    >>> compound_interest(10000.0, 0.05, 1)\n    500.00000000000045\n    >>> compound_interest(0.5, 0.05, 3)\n    0.07881250000000006\n    >>> compound_interest(10000.0, 0.06, -4)\n    Traceback (most recent call last):\n        ...\n    ValueError: number_of_compounding_periods must be > 0\n    >>> compound_interest(10000.0, -3.5, 3.0)\n    Traceback (most recent call last):\n        ...\n    ValueError: nominal_annual_interest_rate_percentage must be >= 0\n    >>> compound_interest(-5500.0, 0.01, 5)\n    Traceback (most recent call last):\n        ...\n    ValueError: principal must be > 0\n    \"\"\"\n    if number_of_compounding_periods <= 0:\n        raise ValueError(\"number_of_compounding_periods must be > 0\")\n    if nominal_annual_interest_rate_percentage < 0:\n        raise ValueError(\"nominal_annual_interest_rate_percentage must be >= 0\")\n    if principal <= 0:\n        raise ValueError(\"principal must be > 0\")\n\n    return principal * (\n        (1 + nominal_annual_interest_rate_percentage) ** number_of_compounding_periods\n        - 1\n    )\n\n\ndef apr_interest(\n    principal: float,\n    nominal_annual_percentage_rate: float,\n    number_of_years: float,\n) -> float:\n    \"\"\"\n    >>> apr_interest(10000.0, 0.05, 3)","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/financial/interest.py#L50-L86","documentation":"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.","triggerScenarios":"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.","commonSituations":"Confusing compounding frequency (4 for quarterly) with total periods (years*4); off-by-one loops building amortization tables; defaults of 0 in config schemas.","solutions":["Pass the total number of compounding periods, e.g. years * periods_per_year (12 for monthly over 3 years -> 36).","Validate n > 0 upstream, especially when it is a computed product of two config values.","For fractional-period needs, use a formula that supports continuous or fractional compounding instead of this function."],"exampleFix":"# before\nci = compound_interest(10000.0, 0.05, 0)  # ValueError\n\n# after\nci = compound_interest(10000.0, 0.05, 3 * 12)  # monthly compounding for 3 years","handlingStrategy":"validation","validationCode":"if number_of_compounding_periods <= 0:\n    raise InputError(\"periods must be >= 1; use years * periods_per_year\")","typeGuard":"def valid_periods(n) -> bool:\n    return isinstance(n, (int, float)) and n > 0","tryCatchPattern":"try:\n    ci = compound_interest(principal, rate, periods)\nexcept ValueError as exc:\n    raise InputError(str(exc)) from exc","preventionTips":["Compute periods as years * frequency (e.g. 3 * 12), never pass frequency alone.","Validate computed products of config values before calls.","Do not pass a fractional interval (0.25) as the period count."],"tags":["finance","interest","compounding","validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}