{"record":{"id":"f6179887445c733a","repo":"TheAlgorithms/Python","slug":"principal-must-be-0","errorCode":null,"errorMessage":"principal must be > 0","messagePattern":"principal must be > 0","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"financial/interest.py","lineNumber":38,"sourceCode":"    >>> simple_interest(10000.0, -0.06, 3)\n    Traceback (most recent call last):\n        ...\n    ValueError: daily_interest_rate must be >= 0\n    >>> simple_interest(-10000.0, 0.06, 3)\n    Traceback (most recent call last):\n        ...\n    ValueError: principal must be > 0\n    >>> simple_interest(5500.0, 0.01, -5)\n    Traceback (most recent call last):\n        ...\n    ValueError: days_between_payments must be > 0\n    \"\"\"\n    if days_between_payments <= 0:\n        raise ValueError(\"days_between_payments must be > 0\")\n    if daily_interest_rate < 0:\n        raise ValueError(\"daily_interest_rate must be >= 0\")\n    if principal <= 0:\n        raise ValueError(\"principal must be > 0\")\n    return principal * daily_interest_rate * days_between_payments\n\n\ndef compound_interest(\n    principal: float,\n    nominal_annual_interest_rate_percentage: float,\n    number_of_compounding_periods: float,\n) -> float:\n    \"\"\"\n    >>> compound_interest(10000.0, 0.05, 3)\n    1576.2500000000014\n    >>> compound_interest(10000.0, 0.05, 1)\n    500.00000000000045\n    >>> compound_interest(0.5, 0.05, 3)\n    0.07881250000000006\n    >>> compound_interest(10000.0, 0.06, -4)\n    Traceback (most recent call last):\n        ...","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/financial/interest.py#L20-L56","documentation":"Raised by simple_interest() in financial/interest.py when principal <= 0. It is the third and final check, so both days and rate are already valid when it fires. The message text is shared verbatim with the principal checks in compound_interest and apr_interest in the same module.","triggerScenarios":"simple_interest(-10000.0, 0.06, 3) or principal=0.0; ledger rows where a debit was stored as a negative amount; empty form input coerced to 0.","commonSituations":"Accounting systems storing liabilities as negative numbers; missing values defaulting to 0 in spreadsheets/CSV; test fixtures with a 0 principal sentinel.","solutions":["Pass a strictly positive principal amount.","If your ledger stores debts negative, negate at the boundary: `simple_interest(-balance, ...)` when balance < 0.","Validate the full triple (days > 0, rate >= 0, principal > 0) before calling to fail with one clear message."],"exampleFix":"# before\nsi = simple_interest(-10000.0, 0.06, 3)  # ValueError\n\n# after\nsi = simple_interest(10000.0, 0.06, 3)","handlingStrategy":"validation","validationCode":"if principal <= 0:\n    raise InputError(\"principal must be > 0\")","typeGuard":"def valid_principal(p) -> bool:\n    return isinstance(p, (int, float)) and p > 0","tryCatchPattern":"try:\n    si = simple_interest(principal, daily_rate, days)\nexcept ValueError as exc:\n    raise InputError(str(exc)) from exc","preventionTips":["Normalize negative-balance ledger conventions at the system edge.","Reject zero-defaulted principal fields during payload validation.","The message is shared across interest.py functions — check the traceback frame to see which call raised."],"tags":["finance","interest","principal","validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}