{"record":{"id":"3ddb27ad461707a2","repo":"TheAlgorithms/Python","slug":"capacity-cannot-be-negative","errorCode":null,"errorMessage":"Capacity cannot be negative","messagePattern":"Capacity cannot be negative","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"greedy_methods/fractional_cover_problem.py","lineNumber":79,"sourceCode":"    >>> fractional_cover(items=[], capacity=50)\n    0.0\n\n    >>> fractional_cover(items=[Item(10, 60)], capacity=5)\n    30.0\n\n    >>> fractional_cover(items=[Item(10, 60)], capacity=1)\n    6.0\n\n    >>> fractional_cover(items=[Item(10, 60)], capacity=0)\n    0.0\n\n    >>> fractional_cover(items=[Item(10, 60)], capacity=-1)\n    Traceback (most recent call last):\n        ...\n    ValueError: Capacity cannot be negative\n    \"\"\"\n    if capacity < 0:\n        raise ValueError(\"Capacity cannot be negative\")\n\n    total_value = 0.0\n    remaining_capacity = capacity\n\n    # Sort the items by their value-to-weight ratio in descending order\n    for item in sorted(items, key=attrgetter(\"ratio\"), reverse=True):\n        if remaining_capacity == 0:\n            break\n\n        weight_taken = min(item.weight, remaining_capacity)\n        total_value += weight_taken * item.ratio\n        remaining_capacity -= weight_taken\n\n    return total_value\n\n\nif __name__ == \"__main__\":\n    import doctest","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/greedy_methods/fractional_cover_problem.py#L61-L97","documentation":"Thrown by fractional_cover() (greedy fractional knapsack/cover) when capacity is negative. A negative capacity is physically meaningless — no item can be taken — and silently returning 0.0 would hide the caller's bug, so the function raises ValueError. Note capacity == 0 is legal and returns 0.0.","triggerScenarios":"Calling fractional_cover(items, capacity=-1), or passing a capacity computed as a difference (budget - used) that has gone negative, or unpacking a negative value from user input / a config file.","commonSituations":"Budget already consumed before the call (remaining capacity goes below zero), sign errors when converting units (e.g. passing -kg), or a default of -1 used as a 'not set' sentinel leaking into the algorithm.","solutions":["Pass a non-negative capacity; clamp at the source: max(0, remaining_budget).","Replace -1 sentinels for 'unset capacity' with None and branch before calling.","If capacity legitimately reaches 0, keep the call — it is valid and yields 0.0."],"exampleFix":"# before\nfractional_cover(items, capacity=budget - spent)  # may be negative\n\n# after\nremaining = budget - spent\nif remaining < 0:\n    raise ValueError(f\"overspent budget: {remaining}\")\nfractional_cover(items, capacity=remaining)","handlingStrategy":"validation","validationCode":"if capacity < 0:\n    raise ValueError(f\"capacity must be >= 0, got {capacity}\")","typeGuard":"def is_valid_capacity(capacity: float) -> bool:\n    return isinstance(capacity, (int, float)) and capacity >= 0","tryCatchPattern":"try:\n    value = fractional_cover(items, capacity)\nexcept ValueError as e:\n    if \"Capacity\" in str(e):\n        value = 0.0  # treat exhausted budget as empty cover\n    else:\n        raise","preventionTips":["Use None, not -1, as the 'unset capacity' sentinel.","Clamp computed capacities at the source: max(0, budget - spent).","Validate numeric config values once at startup."],"tags":["greedy","knapsack","validation","fractional-cover"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}