TheAlgorithms/Python · error · ValueError
days_between_payments must be > 0
Error message
days_between_payments must be > 0
What it means
Raised by simple_interest() in financial/interest.py when days_between_payments <= 0. Interest here is principal * daily_rate * days, and a non-positive day count is meaningless; this is the first of three ordered checks (days, then rate, then principal), so it fires even if the other arguments are also invalid.
Source
Thrown at financial/interest.py:34
>>> simple_interest(18000.0, 0.0, 3)
0.0
>>> simple_interest(5500.0, 0.01, 100)
5500.0
>>> simple_interest(10000.0, -0.06, 3)
Traceback (most recent call last):
...
ValueError: daily_interest_rate must be >= 0
>>> simple_interest(-10000.0, 0.06, 3)
Traceback (most recent call last):
...
ValueError: principal must be > 0
>>> simple_interest(5500.0, 0.01, -5)
Traceback (most recent call last):
...
ValueError: days_between_payments must be > 0
"""
if days_between_payments <= 0:
raise ValueError("days_between_payments must be > 0")
if daily_interest_rate < 0:
raise ValueError("daily_interest_rate must be >= 0")
if principal <= 0:
raise ValueError("principal must be > 0")
return principal * daily_interest_rate * days_between_payments
def compound_interest(
principal: float,
nominal_annual_interest_rate_percentage: float,
number_of_compounding_periods: float,
) -> float:
"""
>>> compound_interest(10000.0, 0.05, 3)
1576.2500000000014
>>> compound_interest(10000.0, 0.05, 1)
500.00000000000045
>>> compound_interest(0.5, 0.05, 3)View on GitHub (pinned to f5988cc097)
Solutions
- Pass a strictly positive integer day count between payments.
- When deriving from dates, assert end >= start and use max(1, (end - start).days) only if same-day accrual rules permit.
- Validate all three simple_interest arguments together before calling (see defense snippet).
Example fix
# before si = simple_interest(5500.0, 0.01, -5) # ValueError # after from datetime import date days = (date(2024, 2, 1) - date(2024, 1, 1)).days # 31 si = simple_interest(5500.0, 0.01, days)
Defensive patterns
Strategy: validation
Validate before calling
if days_between_payments <= 0:
raise ScheduleError("days_between_payments must be > 0; check payment date order") Type guard
def valid_simple_interest_args(p, r, d) -> bool:
return p > 0 and r >= 0 and d > 0 Try / catch
try:
si = simple_interest(principal, daily_rate, days)
except ValueError as exc:
raise ScheduleError(str(exc)) from exc Prevention
- Assert payment date > loan date before computing day deltas.
- Validate the whole (principal, rate, days) triple in one pre-check.
- Watch timezone shifts collapsing day counts to 0.
When it happens
Trigger: simple_interest(5500.0, 0.01, -5) or days=0; computing days as (end_date - start_date).days when the dates are reversed or equal; a date parse failure yielding a 0-day interval.
Common situations: Date-order bugs where payment date precedes the loan date; timezone/DST arithmetic collapsing to 0 days; pipelines where an empty schedule row produces 0 days.
Related errors
- daily_interest_rate must be >= 0
- principal must be > 0
- number_of_compounding_periods must be > 0
- nominal_annual_interest_rate_percentage must be >= 0
- Principal borrowed must be > 0
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/6a8ae61175823920.
Report an issue: GitHub.