S1Q3 · Transfer Amount Between Accounts¶
⚡ Quick Reference
Function: transfer_amount(accounts: dict, sender: str, recipient: str, amount: int) -> None
Core idea: validate all three conditions, then update both balances in-place.
def transfer_amount(accounts, sender, recipient, amount):
if (sender in accounts and
recipient in accounts and
amount >= 0 and
accounts[sender] >= amount):
accounts[sender] -= amount
accounts[recipient] += amount
Key rules:
- Both sender and recipient must be in accounts
- amount >= 0 (non-negative)
- accounts[sender] >= amount (sufficient balance)
- All three must pass - if any fails, do nothing
- Returns None - modifies dict in-place
Problem Statement¶
Problem
Write a function transfer_amount(accounts, sender, recipient, amount) that transfers amount from sender to recipient if the transaction is valid. Otherwise, leave the dict unchanged.
Examples:
accounts={"12345":500,"67890":1000,"98764":1500}
transfer_amount(accounts, "12345", "67890", 1000)
{"12345":500,"67890":1000,"98764":1500} ← unchanged (insufficient balance)
transfer_amount(accounts, "12345", "67890", 400)
{"12345":100,"67890":1400,"98764":1500} ← 400 transferred
Validation logic¶
Three conditions, all must be True:
1. sender in accounts → account exists
2. recipient in accounts → account exists
3. amount >= 0 → non-negative transfer
4. accounts[sender] >= amount → sufficient balance
If all pass → update. If any fails → do nothing.
Check existence before balance
accounts[sender] >= amount would raise a KeyError if sender doesn't exist. Always check sender in accounts first - Python's short-circuit and ensures balance is only checked when the key is known to exist.
Tracing all examples¶
Starting: {"12345": 500, "67890": 1000, "98764": 1500}
| Call | Condition failed | Action | Result |
|---|---|---|---|
("12345","67890",1000) |
balance 500 < 1000 | nothing | unchanged |
("12345","67890",400) |
all pass | transfer | 12345:100, 67890:1400 |
("98764","67890",1500) |
all pass | transfer | 98764:0, 67890:2900 |
("98764","67890",-100) |
amount < 0 | nothing | unchanged |
("29732","67890",100) |
29732 not in accounts | nothing | unchanged |
Solution approaches¶
def transfer_amount(accounts, sender, recipient, amount):
sender_exists = sender in accounts
recipient_exists = recipient in accounts
non_negative = amount >= 0
if not (sender_exists and recipient_exists and non_negative):
return
sufficient = accounts[sender] >= amount
if not sufficient:
return
accounts[sender] -= amount
accounts[recipient] += amount
def transfer_amount(accounts, sender, recipient, amount):
if sender not in accounts:
return
if recipient not in accounts:
return
if amount < 0:
return
if accounts[sender] < amount:
return
accounts[sender] -= amount
accounts[recipient] += amount
Guard clauses - each invalid condition returns early. The actual transfer only runs if all guards pass.
Key takeaways¶
Check existence before accessing values
sender in accounts and accounts[sender] >= amount - the key existence check must come before the balance access. Short-circuit and guarantees the balance is only checked after the key is confirmed to exist.
Modify in-place, return None
The function updates accounts directly - no new dict is created and nothing is returned. The caller sees the changes through their reference to the same dict object.
All conditions must pass - no partial updates
Either both balances update or neither does. Never deduct from sender without confirming the transfer will complete, or you risk an inconsistent state.