TheAlgorithms/Python · error · Exception
Rate of interest must be >= 0
Error message
Rate of interest must be >= 0
What it means
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.
Source
Thrown at financial/equated_monthly_installments.py:40
>>> equated_monthly_installments(25000, 0.12, 10)
358.67737100646826
>>> equated_monthly_installments(0, 0.12, 3)
Traceback (most recent call last):
...
Exception: Principal borrowed must be > 0
>>> equated_monthly_installments(25000, -1, 3)
Traceback (most recent call last):
...
Exception: Rate of interest must be >= 0
>>> equated_monthly_installments(25000, 0.12, 0)
Traceback (most recent call last):
...
Exception: Years to repay must be an integer > 0
"""
if principal <= 0:
raise Exception("Principal borrowed must be > 0")
if rate_per_annum < 0:
raise Exception("Rate of interest must be >= 0")
if years_to_repay <= 0 or not isinstance(years_to_repay, int):
raise Exception("Years to repay must be an integer > 0")
# Yearly rate is divided by 12 to get monthly rate
rate_per_month = rate_per_annum / 12
# Years to repay is multiplied by 12 to get number of payments as payment is monthly
number_of_payments = years_to_repay * 12
return (
principal
* rate_per_month
* (1 + rate_per_month) ** number_of_payments
/ ((1 + rate_per_month) ** number_of_payments - 1)
)
if __name__ == "__main__":View on GitHub (pinned to f5988cc097)
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.
Example fix
# before emi = equated_monthly_installments(25000, -1, 3) # Exception # after emi = equated_monthly_installments(25000, 0.01, 3) # 1% p.a.
Defensive patterns
Strategy: validation
Validate before calling
if rate_per_annum < 0:
raise LoanInputError("annual rate must be >= 0 (decimal, e.g. 0.12 for 12%)") Type guard
def valid_rate(r) -> bool:
return isinstance(r, (int, float)) and r >= 0 Try / catch
try:
emi = equated_monthly_installments(principal, rate, years)
except Exception as exc:
raise LoanInputError(str(exc)) from exc # bare Exception from library Prevention
- 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.
When it happens
Trigger: equated_monthly_installments(25000, -1, 3); rates parsed with a stray '-' sign; percent values like -0.12 instead of 0.12.
Common situations: 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.
Related errors
- Principal borrowed must be > 0
- Years to repay must be an integer > 0
- window_size must be > 0
- days_between_payments must be > 0
- daily_interest_rate must be >= 0
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/6e2031e444d67518.
Report an issue: GitHub.