TheAlgorithms/Python · error · ValueError

Weight can not be negative.

Error message

Weight can not be negative.

What it means

Thrown by calc_profit() when any element of weight is negative. Negative weights break the greedy knapsack invariant (taking an item consumes capacity) and would also cause a ZeroDivisionError later in profit_by_weight = [p / w ...] if a zero slipped through, so all weights must be non-negative (and in practice positive).

Source

Thrown at knapsack/greedy_knapsack.py:40

    Function description is as follows-
    :param profit: Take a list of profits
    :param weight: Take a list of weight if bags corresponding to the profits
    :param max_weight: Maximum weight that could be carried
    :return: Maximum expected gain

    >>> calc_profit([1, 2, 3], [3, 4, 5], 15)
    6
    >>> calc_profit([10, 9 , 8], [3 ,4 , 5], 25)
    27
    """
    if len(profit) != len(weight):
        raise ValueError("The length of profit and weight must be same.")
    if max_weight <= 0:
        raise ValueError("max_weight must greater than zero.")
    if any(p < 0 for p in profit):
        raise ValueError("Profit can not be negative.")
    if any(w < 0 for w in weight):
        raise ValueError("Weight can not be negative.")

    # List created to store profit gained for the 1kg in case of each weight
    # respectively.  Calculate and append profit/weight for each element.
    profit_by_weight = [p / w for p, w in zip(profit, weight)]

    # Creating a copy of the list and sorting profit/weight in ascending order
    sorted_profit_by_weight = sorted(profit_by_weight)

    # declaring useful variables
    length = len(sorted_profit_by_weight)
    limit = 0
    gain = 0
    i = 0

    # loop till the total weight do not reach max limit e.g. 15 kg and till i<length
    while limit <= max_weight and i < length:
        # flag value for encountered greatest element in sorted_profit_by_weight
        biggest_profit_by_weight = sorted_profit_by_weight[length - i - 1]

View on GitHub (pinned to f5988cc097)

Solutions

  1. Filter out items with weight <= 0 before calling (zero weights crash the ratio computation even though the guard only checks negatives).
  2. Fix the data source so weights are physical, positive quantities.
  3. Assert all(w > 0 for w in weight) where the list is constructed.

Example fix

# before
calc_profit([10, 20], [-5, 5], 100)  # ValueError

# after
pairs = [(p, w) for p, w in zip(profit, weight) if w > 0]
calc_profit([p for p, _ in pairs], [w for _, w in pairs], 100)
Defensive patterns

Strategy: validation

Validate before calling

assert all(w > 0 for w in weight), "weights must be positive"
# (zero weights also crash the internal p/w division even though the guard checks only negatives)

Type guard

def all_weights_positive(weight: list[float]) -> bool:
    return all(isinstance(w, (int, float)) and w > 0 for w in weight)

Try / catch

try:
    gain = calc_profit(profit, weight, max_weight)
except ValueError as e:
    if "Weight" in str(e):
        keep = [(p, w) for p, w in zip(profit, weight) if w > 0]
        gain = calc_profit([p for p, _ in keep], [w for _, w in keep], max_weight)
    else:
        raise

Prevention

When it happens

Trigger: Calling calc_profit with a weight list containing a negative value, e.g. calc_profit([10, 20], [-5, 5], 100). Also any zero weight would pass this guard but crash on division — validate positivity yourself.

Common situations: Signed weights from a data feed (e.g. deltas); tare/offset arithmetic producing negatives; missing validation after unit conversions.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/cc05dd4dbdf4e5ae. Report an issue: GitHub.