TheAlgorithms/Python · error · ValueError

Purchase value cannot be less than residual value

Error message

Purchase value cannot be less than residual value

What it means

Raised by straight_line_depreciation() when purchase_value < residual_value (ValueError). The depreciable cost (purchase - residual) would be negative, producing negative annual depreciation — economically nonsensical for straight-line accounting, so the function refuses. Equal values are fine and yield all-zero schedules.

Source

Thrown at financial/straight_line_depreciation.py:71

    """

    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_value
    annual_depreciation_expense = depreciable_cost / useful_years

    # List of annual depreciation expenses
    list_of_depreciation_expenses = []
    accumulated_depreciation_expense = 0.0
    for period in range(useful_years):
        if period != useful_years - 1:
            accumulated_depreciation_expense += annual_depreciation_expense
            list_of_depreciation_expenses.append(annual_depreciation_expense)
        else:
            depreciation_expense_in_end_year = (
                depreciable_cost - accumulated_depreciation_expense
            )
            list_of_depreciation_expenses.append(depreciation_expense_in_end_year)

View on GitHub (pinned to f5988cc097)

Solutions

  1. Check argument order: the signature is (useful_years, purchase_value, residual_value).
  2. If order is right, fix the data: a residual above cost usually means a stale estimate or mismatched units.
  3. Use keyword arguments at call sites to make ordering impossible to get wrong.

Example fix

# before
straight_line_depreciation(5, residual, purchase)  # swapped

# after
straight_line_depreciation(5, purchase, residual)  # or use keywords
Defensive patterns

Strategy: validation

Validate before calling

if purchase_value < residual_value:
    raise ValueError(
        f'cost basis {purchase_value} below salvage {residual_value}'
    )
straight_line_depreciation(5, purchase_value, residual_value)

Try / catch

try:
    sched = straight_line_depreciation(y, p, r)
except ValueError as exc:
    if 'less than residual' in str(exc):
        raise ValueError('check purchase/residual order or units') from exc
    raise

Prevention

When it happens

Trigger: Calling straight_line_depreciation(5, 50.0, 1250.0) (arguments swapped — the most common cause), or genuinely passing a salvage estimate above the recorded cost basis.

Common situations: Swapped positional arguments (purchase/residual order confusion), re-valuation where market salvage exceeds depreciated book cost, or unit mismatches (purchase in cents, residual in dollars).

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/bacef417da89da50. Report an issue: GitHub.