{"record":{"id":"1f4e81735ce4ba05","repo":"TheAlgorithms/Python","slug":"profit-can-not-be-negative","errorCode":null,"errorMessage":"Profit can not be negative.","messagePattern":"Profit can not be negative\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"knapsack/greedy_knapsack.py","lineNumber":38,"sourceCode":"def calc_profit(profit: list, weight: list, max_weight: int) -> int:\n    \"\"\"\n    Function description is as follows-\n    :param profit: Take a list of profits\n    :param weight: Take a list of weight if bags corresponding to the profits\n    :param max_weight: Maximum weight that could be carried\n    :return: Maximum expected gain\n\n    >>> calc_profit([1, 2, 3], [3, 4, 5], 15)\n    6\n    >>> calc_profit([10, 9 , 8], [3 ,4 , 5], 25)\n    27\n    \"\"\"\n    if len(profit) != len(weight):\n        raise ValueError(\"The length of profit and weight must be same.\")\n    if max_weight <= 0:\n        raise ValueError(\"max_weight must greater than zero.\")\n    if any(p < 0 for p in profit):\n        raise ValueError(\"Profit can not be negative.\")\n    if any(w < 0 for w in weight):\n        raise ValueError(\"Weight can not be negative.\")\n\n    # List created to store profit gained for the 1kg in case of each weight\n    # respectively.  Calculate and append profit/weight for each element.\n    profit_by_weight = [p / w for p, w in zip(profit, weight)]\n\n    # Creating a copy of the list and sorting profit/weight in ascending order\n    sorted_profit_by_weight = sorted(profit_by_weight)\n\n    # declaring useful variables\n    length = len(sorted_profit_by_weight)\n    limit = 0\n    gain = 0\n    i = 0\n\n    # loop till the total weight do not reach max limit e.g. 15 kg and till i<length\n    while limit <= max_weight and i < length:","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/knapsack/greedy_knapsack.py#L20-L56","documentation":"Thrown by calc_profit() when any element of profit is negative. The greedy algorithm's correctness argument (take items by best profit/weight ratio) assumes non-negative values; a negative profit item could be selected and subtract from the total, so the function validates all profits upfront.","triggerScenarios":"Calling calc_profit with a profits list containing a negative entry, e.g. calc_profit([-10, 20], [5, 5], 100). Typically the negative value is a cost or loss figure mixed into a value list.","commonSituations":"Feeding raw P&L data where losses are negative; missing abs() when converting costs to profits; sentinel -1 values for 'no data' items surviving into the algorithm.","solutions":["Filter or fix negative profits before the call: drop the item, or convert cost to value explicitly if that is the intended semantics.","Use None or NaN sentinels for missing data and sanitize at parse time.","Add a data-quality assertion when building the lists from external data."],"exampleFix":"# before\ncalc_profit([-10, 20, 30], [5, 5, 5], 100)  # ValueError\n\n# after\npairs = [(p, w) for p, w in zip(profits, weights) if p >= 0]\ncalc_profit([p for p, _ in pairs], [w for _, w in pairs], 100)","handlingStrategy":"validation","validationCode":"assert all(p >= 0 for p in profit), \"profits must be non-negative\"","typeGuard":"def all_profits_non_negative(profit: list[float]) -> bool:\n    return all(isinstance(p, (int, float)) and p >= 0 for p in profit)","tryCatchPattern":"try:\n    gain = calc_profit(profit, weight, max_weight)\nexcept ValueError as e:\n    if \"Profit\" in str(e):\n        gain = calc_profit([max(p, 0) for p in profit], weight, max_weight)\n    else:\n        raise","preventionTips":["Sanitize financial feeds: separate losses from value lists.","Drop 'no data' sentinel items (-1) at parse time.","Add data-quality assertions where lists are constructed."],"tags":["knapsack","greedy","validation","data-quality"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}