{"record":{"id":"082decb2b6f84aa1","repo":"TheAlgorithms/Python","slug":"residual-value-must-be-numeric","errorCode":null,"errorMessage":"Residual value must be numeric","messagePattern":"Residual value must be numeric","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"financial/straight_line_depreciation.py","lineNumber":65,"sourceCode":"    >>> straight_line_depreciation(4, 1001.0)\n    [250.25, 250.25, 250.25, 250.25]\n    >>> straight_line_depreciation(11, 380.0, 50.0)\n    [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)","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/financial/straight_line_depreciation.py#L47-L83","documentation":"Raised by straight_line_depreciation() when residual_value is not int or float (TypeError). residual_value participates in subtraction (purchase - residual), so non-numeric inputs fail fast before the depreciation schedule is built. It is the fourth check, after useful_years type/range and purchase_value type.","triggerScenarios":"Calling straight_line_depreciation(5, 1250.0, '50.0'), passing None (common for 'no salvage value' defaults), or a Decimal salvage figure.","commonSituations":"Optional salvage-value fields defaulting to None in forms and APIs, string inputs from config files, or mixed types when purchase is float but residual comes from a different source.","solutions":["Pass residual as a number; use 0 when there is no salvage value.","Convert None -> 0.0 at the boundary if 'unspecified' means 'no residual' in your domain.","Apply the same numeric parsing you use for purchase_value — the checks are symmetric."],"exampleFix":"# before\nstraight_line_depreciation(5, 1250.0, asset.get('residual'))  # None when absent\n\n# after\nstraight_line_depreciation(5, 1250.0, asset.get('residual') or 0.0)","handlingStrategy":"type-guard","validationCode":"residual = residual if isinstance(residual, (int, float)) else 0.0\nstraight_line_depreciation(5, 1250.0, residual)","typeGuard":"def is_numeric(v: object) -> bool:\n    return isinstance(v, (int, float)) and not isinstance(v, bool)","tryCatchPattern":"try:\n    sched = straight_line_depreciation(y, p, r)\nexcept TypeError as exc:\n    if 'Residual value' in str(exc):\n        sched = straight_line_depreciation(y, p, 0.0)\n    else:\n        raise","preventionTips":["Normalize None salvage values to 0.0 where the domain allows it.","Keep purchase and residual types consistent — both must be plain int/float."],"tags":["finance","type-checking","typeerror"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}