Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python rollback exercise: reject a later failure without keeping earlier edits

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A staged-state exercise verifies that a rejected batch leaves the previously accepted state unchanged.

Download Python source kit

Operation contract

The inventory adjustment copies current quantities into a candidate map, applies validated changes there, and returns the replacement only after every change passes. The first edit in the failing fixture would be valid, but a later edit would make stock negative. The caller keeps its original dictionary because the function never mutates it.

Failure and ownership boundary

The operation accepts at most 32 changes, known keys and bounded exact integers. This is local state staging, not a database transaction or protection against another thread replacing stock at the same time. Extend the exercise by checking empty batches, duplicate key edits and a failure at each possible position. Python locks: protect the complete inventory transition requires a wider critical section.

Working program

python
def adjusted_stock(stock, changes):
    if len(changes) > 32 or any(type(value) is not int or not 0 <= value <= 1000 for value in stock.values()):
        raise ValueError("stock budget")
    candidate = stock.copy()
    for label, delta in changes:
        if label not in candidate or type(delta) is not int or abs(delta) > 1000:
            raise ValueError("invalid adjustment")
        quantity = candidate[label] + delta
        if not 0 <= quantity <= 1000:
            raise ValueError("quantity out of range")
        candidate[label] = quantity
    return candidate

stock = {"paper": 12, "ink": 4}
try:
    adjusted_stock(stock, [("paper", -2), ("ink", -5)])
except ValueError:
    print("batch rejected")
print(stock)
print(adjusted_stock(stock, [("paper", -2)]))

Output

Output
batch rejected
{'paper': 12, 'ink': 4}
{'paper': 10, 'ink': 4}

Costs and limits

Copying s stock entries costs O(s) time and storage, then c changes cost expected O(c) dictionary work. The fixture does not cap the caller’s pre-existing map size; an external service must set that limit too.

Common Mistakes

  • Mutating the original map and trying to undo edits is a different failure contract.
  • A returned replacement must still be published under an appropriate concurrency policy.

Connected lessons

Python inventory project: validate a batch before replacing stored state, Python locks: protect the complete inventory transition, Python SQLite project: transactional batches, duplicate IDs and reopen checks.

python
rollback-exercise
Storage details