{"record":{"id":"10659e1197025752","repo":"TheAlgorithms/Python","slug":"purchase-value-cannot-be-less-than-zero","errorCode":null,"errorMessage":"Purchase value cannot be less than zero","messagePattern":"Purchase value cannot be less than zero","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"financial/straight_line_depreciation.py","lineNumber":68,"sourceCode":"    [30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0]\n    >>> straight_line_depreciation(1, 4985, 100)\n    [4885.0]\n    \"\"\"\n\n    if not isinstance(useful_years, int):\n        raise TypeError(\"Useful years must be an integer\")\n\n    if useful_years < 1:\n        raise ValueError(\"Useful years cannot be less than 1\")\n\n    if not isinstance(purchase_value, (float, int)):\n        raise TypeError(\"Purchase value must be numeric\")\n\n    if not isinstance(residual_value, (float, int)):\n        raise TypeError(\"Residual value must be numeric\")\n\n    if purchase_value < 0.0:\n        raise ValueError(\"Purchase value cannot be less than zero\")\n\n    if purchase_value < residual_value:\n        raise ValueError(\"Purchase value cannot be less than residual value\")\n\n    # Calculate annual depreciation expense\n    depreciable_cost = purchase_value - residual_value\n    annual_depreciation_expense = depreciable_cost / useful_years\n\n    # List of annual depreciation expenses\n    list_of_depreciation_expenses = []\n    accumulated_depreciation_expense = 0.0\n    for period in range(useful_years):\n        if period != useful_years - 1:\n            accumulated_depreciation_expense += annual_depreciation_expense\n            list_of_depreciation_expenses.append(annual_depreciation_expense)\n        else:\n            depreciation_expense_in_end_year = (\n                depreciable_cost - accumulated_depreciation_expense","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/financial/straight_line_depreciation.py#L50-L86","documentation":"Raised by straight_line_depreciation() when purchase_value is numeric but negative (ValueError). A negative purchase price makes depreciable_cost negative and produces a nonsense schedule of negative expenses, so the function rejects it after type checks. Zero is allowed.","triggerScenarios":"Calling straight_line_depreciation(5, -1250.0, 50.0) or passing a credit-note-adjusted cost basis that went below zero.","commonSituations":"Accounting systems storing reversals/refunds as negatives, currency-adjusted bases that underflow to negative, or sign-convention mistakes when importing GL data.","solutions":["Pass purchase_value >= 0.","Investigate the source of the negative basis — usually an upstream double-entry error worth surfacing, not silently fixing.","If reversals are legitimate in your pipeline, handle them before depreciation, not through this API."],"exampleFix":"# before\nstraight_line_depreciation(5, net_cost_basis, 50.0)  # -1250.0 after reversals\n\n# after\nif net_cost_basis < 0:\n    raise ValueError(f'negative cost basis from reversals: {net_cost_basis}')\nstraight_line_depreciation(5, net_cost_basis, 50.0)","handlingStrategy":"validation","validationCode":"if purchase_value < 0:\n    raise ValueError(f'purchase value cannot be negative: {purchase_value}')\nstraight_line_depreciation(5, purchase_value, residual)","typeGuard":null,"tryCatchPattern":"try:\n    sched = straight_line_depreciation(y, p, r)\nexcept ValueError as exc:\n    if 'less than zero' in str(exc):\n        flag_for_review(p)\n        raise\n    raise","preventionTips":["Zero purchase is legal (fully-residual asset); only negatives raise.","Audit negative monetary inputs at import time — they usually indicate data corruption."],"tags":["finance","input-validation","valueerror"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}