{"record":{"id":"31e86375ff7fe76f","repo":"TheAlgorithms/Python","slug":"nominal-annual-percentage-rate-must-be-0","errorCode":null,"errorMessage":"nominal_annual_percentage_rate must be >= 0","messagePattern":"nominal_annual_percentage_rate must be >= 0","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"financial/interest.py","lineNumber":108,"sourceCode":"    >>> apr_interest(0.5, 0.05, 3)\n    0.08091115361317736\n    >>> apr_interest(10000.0, 0.06, -4)\n    Traceback (most recent call last):\n        ...\n    ValueError: number_of_years must be > 0\n    >>> apr_interest(10000.0, -3.5, 3.0)\n    Traceback (most recent call last):\n        ...\n    ValueError: nominal_annual_percentage_rate must be >= 0\n    >>> apr_interest(-5500.0, 0.01, 5)\n    Traceback (most recent call last):\n        ...\n    ValueError: principal must be > 0\n    \"\"\"\n    if number_of_years <= 0:\n        raise ValueError(\"number_of_years must be > 0\")\n    if nominal_annual_percentage_rate < 0:\n        raise ValueError(\"nominal_annual_percentage_rate must be >= 0\")\n    if principal <= 0:\n        raise ValueError(\"principal must be > 0\")\n\n    return compound_interest(\n        principal, nominal_annual_percentage_rate / 365, number_of_years * 365\n    )\n\n\nif __name__ == \"__main__\":\n    import doctest\n\n    doctest.testmod()\n","sourceCodeStart":90,"sourceCodeEnd":121,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/financial/interest.py#L90-L121","documentation":"Raised by apr_interest() when nominal_annual_percentage_rate < 0. A negative APR has no financial meaning for this compounding formula (it would represent a guaranteed-loss product the function does not model), so it is rejected before delegation to compound_interest. The check allows exactly 0 (simple no-growth case).","triggerScenarios":"Calling apr_interest(10000.0, -3.5, 3.0) or any call where the rate argument is negative. Only reached when number_of_years > 0, since years is validated first.","commonSituations":"Reading rates from feeds that encode decreases as negatives, mixing up percentage (3.5) and fractional (0.035) conventions with a sign error, or passing a placeholder -1 sentinel meaning 'no rate'.","solutions":["Pass a rate >= 0; use 0 for a zero-interest instrument.","Check the data source for sign conventions (e.g. some APIs report yield changes, not levels, as negative).","If you need negative-growth modelling, apr_interest does not support it — compute it with compound_interest directly after your own validation."],"exampleFix":"# before\napr_interest(10000.0, latest_rate, 3)  # latest_rate == -3.5 from feed\n\n# after\nrate = max(0.0, latest_rate) if clamped else latest_rate\nif rate < 0:\n    raise ValueError(f'unsupported negative APR: {rate}')\napr_interest(10000.0, rate, 3)","handlingStrategy":"validation","validationCode":"if apr < 0:\n    raise ValueError(f'APR cannot be negative, got {apr}')\napr_interest(principal, apr, years)","typeGuard":null,"tryCatchPattern":"try:\n    value = apr_interest(p, r, y)\nexcept ValueError as exc:\n    if 'nominal_annual_percentage_rate' in str(exc):\n        # bad rate data, not a code bug\n        log.warning('skipping negative APR %s', r); return None\n    raise","preventionTips":["Never use -1 as a 'missing rate' sentinel when calling this function.","Pin down percentage-vs-fraction units once at the ingestion layer."],"tags":["finance","input-validation","valueerror"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}