Use only in-memory state. Identifiers are nonempty strings supplied by the caller. Amounts and limits are integers, excluding booleans. There are no timestamps, threads, persistence, or external services.

Prototype: implement BalanceAccount() with initial balance zero. balance() returns the integer balance. deposit(amount) requires amount > 0, adds it, and returns the new balance. withdraw(amount) requires amount > 0; return False without mutation if funds are insufficient, otherwise debit and return True. Invalid amounts raise ValueError without mutation.

Final: implement Bank():

  • create_account(account_id) -> bool: create a zero-balance account and zero outgoing total; return False on a duplicate without resetting it.
  • balance(account_id) -> int | None: return the balance, or None for an unknown account.
  • deposit(account_id, amount) -> int | None: reject nonpositive amounts with ValueError first; return None for an unknown account, otherwise return its new balance.
  • transfer(request_id, source, target, amount) -> tuple[int, int] | None: reject a nonpositive amount with ValueError first. A previously successful request with exactly the same (source, target, amount) returns its original (source_balance, target_balance). Reusing that identifier with different arguments raises ValueError. Otherwise return None without mutation for missing accounts, identical accounts, or insufficient funds. On success move the amount, add it only to the source's outgoing total, record the successful request, and return the two resulting balances. Failures do not consume request identifiers.
  • top_spenders(limit) -> list[tuple[str, int]]: return at most limit accounts ordered by outgoing total descending, then identifier ascending. Include zero-spending accounts. Zero returns []; negative limits raise ValueError. The list is a fresh snapshot.

All raised errors and rejected requests preserve state. Separate instances are independent. Run python main.py --stage prototype, then python main.py --stage final (the default). Edit exercise.py; leave main.py unchanged.

Drag or use the arrow keys to resize. Home collapses the question; End collapses the editor. Enter or double-click resets the split.
Loading editor…
No results yet.

Complete the starter code, then run the checks.
Results and errors will appear here.