TheAlgorithms/Python · error · TypeError
Useful years must be an integer
Error message
Useful years must be an integer
What it means
Raised by straight_line_depreciation() in financial/straight_line_depreciation.py when useful_years is not an int (TypeError, not ValueError). The function loops range(useful_years), which requires an int, so a string or float is rejected up front. Note: True/False are ints in Python and pass this check — a latent quirk.
Source
Thrown at financial/straight_line_depreciation.py:56
Calculate the depreciation expenses over the given period
:param useful_years: Number of years the asset will be used
:param purchase_value: Purchase expenditure for the asset
:param residual_value: Residual value of the asset at the end of its useful life
:return: A list of annual depreciation expenses over the asset's useful life
>>> straight_line_depreciation(10, 1100.0, 100.0)
[100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
>>> straight_line_depreciation(6, 1250.0, 50.0)
[200.0, 200.0, 200.0, 200.0, 200.0, 200.0]
>>> straight_line_depreciation(4, 1001.0)
[250.25, 250.25, 250.25, 250.25]
>>> straight_line_depreciation(11, 380.0, 50.0)
[30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0]
>>> straight_line_depreciation(1, 4985, 100)
[4885.0]
"""
if not isinstance(useful_years, int):
raise TypeError("Useful years must be an integer")
if useful_years < 1:
raise ValueError("Useful years cannot be less than 1")
if not isinstance(purchase_value, (float, int)):
raise TypeError("Purchase value must be numeric")
if not isinstance(residual_value, (float, int)):
raise TypeError("Residual value must be numeric")
if purchase_value < 0.0:
raise ValueError("Purchase value cannot be less than zero")
if purchase_value < residual_value:
raise ValueError("Purchase value cannot be less than residual value")
# Calculate annual depreciation expense
depreciable_cost = purchase_value - residual_valueView on GitHub (pinned to f5988cc097)
Solutions
- Coerce to int before calling: int(useful_years) after confirming no precision is lost.
- Fix the source: parse CLI args with int(sys.argv[1]); tighten JSON schemas to integer type.
- If fractional years are a real requirement, this function cannot model them — scale periods yourself.
Example fix
# before straight_line_depreciation(float(sys.argv[1]), 1250.0, 50.0) # after straight_line_depreciation(int(sys.argv[1]), 1250.0, 50.0)
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(useful_years, int) or isinstance(useful_years, bool):
raise TypeError('useful_years must be int')
straight_line_depreciation(useful_years, purchase, residual) Type guard
def is_int_years(v: object) -> bool:
return isinstance(v, int) and not isinstance(v, bool) Try / catch
try:
sched = straight_line_depreciation(y, p, r)
except TypeError as exc:
if 'Useful years' in str(exc):
sched = straight_line_depreciation(int(y), p, r)
else:
raise Prevention
- Cast at the boundary: CLI/JSON values never reach business logic unparsed.
- Remember all six checks raise TypeError for type errors and ValueError for range errors — catch accordingly.
When it happens
Trigger: Calling straight_line_depreciation(5.0, 1250.0, 50.0) (float years), straight_line_depreciation('5', ...) (string from CLI/JSON), or passing a Decimal. Booleans pass because bool subclasses int.
Common situations: Unparsed CLI arguments (always strings), JSON/YAML config where 5 is written as 5.0, or ORM/API fields typed as float. This is the first of six ordered checks, so it fires before any value checks.
Related errors
- Purchase value must be numeric
- Residual value must be numeric
- Input value of [number={number}] must be an integer
- Input value of [number={number}] must be an integer
- Input value of [number={number}] must be an integer
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/b85a5050965f09e6.
Report an issue: GitHub.