{"record":{"id":"6e2031e444d67518","repo":"TheAlgorithms/Python","slug":"rate-of-interest-must-be-0","errorCode":null,"errorMessage":"Rate of interest must be >= 0","messagePattern":"Rate of interest must be >= 0","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"financial/equated_monthly_installments.py","lineNumber":40,"sourceCode":"    >>> equated_monthly_installments(25000, 0.12, 10)\n    358.67737100646826\n    >>> equated_monthly_installments(0, 0.12, 3)\n    Traceback (most recent call last):\n        ...\n    Exception: Principal borrowed must be > 0\n    >>> equated_monthly_installments(25000, -1, 3)\n    Traceback (most recent call last):\n        ...\n    Exception: Rate of interest must be >= 0\n    >>> equated_monthly_installments(25000, 0.12, 0)\n    Traceback (most recent call last):\n        ...\n    Exception: Years to repay must be an integer > 0\n    \"\"\"\n    if principal <= 0:\n        raise Exception(\"Principal borrowed must be > 0\")\n    if rate_per_annum < 0:\n        raise Exception(\"Rate of interest must be >= 0\")\n    if years_to_repay <= 0 or not isinstance(years_to_repay, int):\n        raise Exception(\"Years to repay must be an integer > 0\")\n\n    # Yearly rate is divided by 12 to get monthly rate\n    rate_per_month = rate_per_annum / 12\n\n    # Years to repay is multiplied by 12 to get number of payments as payment is monthly\n    number_of_payments = years_to_repay * 12\n\n    return (\n        principal\n        * rate_per_month\n        * (1 + rate_per_month) ** number_of_payments\n        / ((1 + rate_per_month) ** number_of_payments - 1)\n    )\n\n\nif __name__ == \"__main__\":","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/financial/equated_monthly_installments.py#L22-L58","documentation":"Raised by equated_monthly_installments() in financial/equated_monthly_installments.py when rate_per_annum < 0. A negative nominal interest rate is rejected even though some real-world rates have gone negative, because the annuity formula and its doctests assume rate >= 0; zero is allowed (it degenerates to principal/number_of_payments). It is the second check, after principal.","triggerScenarios":"equated_monthly_installments(25000, -1, 3); rates parsed with a stray '-' sign; percent values like -0.12 instead of 0.12.","commonSituations":"Sign errors when subtracting discounts from a base rate; handling negative-rate mortgages (unsupported here — compute manually if truly needed); config files storing rates as strings with minus signs.","solutions":["Pass the annual nominal rate as a non-negative decimal (0.12 for 12%, not 12 or -0.12).","If a negative rate is legitimate for your domain, special-case it: divide principal by the payment count instead of calling this function.","Sanitize: `rate = abs(rate) if data_entry_sign_error else rate` only after confirming the sign is an artifact."],"exampleFix":"# before\nemi = equated_monthly_installments(25000, -1, 3)  # Exception\n\n# after\nemi = equated_monthly_installments(25000, 0.01, 3)  # 1% p.a.","handlingStrategy":"validation","validationCode":"if rate_per_annum < 0:\n    raise LoanInputError(\"annual rate must be >= 0 (decimal, e.g. 0.12 for 12%)\")","typeGuard":"def valid_rate(r) -> bool:\n    return isinstance(r, (int, float)) and r >= 0","tryCatchPattern":"try:\n    emi = equated_monthly_installments(principal, rate, years)\nexcept Exception as exc:\n    raise LoanInputError(str(exc)) from exc  # bare Exception from library","preventionTips":["Store rates as decimal fractions and document the convention.","For genuinely negative rates, compute principal / (years * 12) yourself.","Strip unicode minus signs from imported rate data."],"tags":["finance","emi","interest-rate","validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}