Reject a negative quantity before multiplying an amount
Reject a negative quantity before multiplying an amount
Reject a negative quantity before multiplying it by an amount: test quantity < 0 first and return a defined validation status. For quantity -2 and unit amount Decimal('3.50'), direct multiplication produces the plausible-looking total -7.00; the corrected function returns negative_quantity and creates no total.
The direct multiplication is useful as a contrast, not as a correction. It performs valid numeric arithmetic, but it does not enforce the application rule that this input is invalid. line_total() puts that rule before the multiplication and returns a small result mapping. The caller can distinguish rejection from a valid zero total because the rejected mapping has no total key.
The assertions prove the branch taken for this literal fixture, the unchanged source mapping, and the absence of a calculated amount in the rejection result. They do not validate whether negative quantities should be accepted in another domain, such as returns or inventory adjustments. Decimal preserves significance in multiplication, which is why -2 * Decimal('3.50') displays as -7.00. No newer Python API is required.
AI assistance disclosure: this article was drafted with AI assistance and uses a synthetic, locally reproducible fixture.
from decimal import Decimal
record = {"quantity": -2, "unit_amount": Decimal("3.50")}
unsafe_total = Decimal(record["quantity"]) * record["unit_amount"]
def line_total(item):
if item["quantity"] < 0:
return {"status": "negative_quantity"}
return {
"status": "ok",
"total": Decimal(item["quantity"]) * item["unit_amount"],
}
result = line_total(record)
assert record == {"quantity": -2, "unit_amount": Decimal("3.50")}
assert unsafe_total == Decimal("-7.00")
assert result == {"status": "negative_quantity"}
assert "total" not in result
print(f"input: {record}")
print(f"unsafe total: {unsafe_total}")
print(f"status: {result['status']}")
print(f"amount calculated: {'total' in result}")
input: {'quantity': -2, 'unit_amount': Decimal('3.50')}
unsafe total: -7.00
status: negative_quantity
amount calculated: False