compute_totals_per_client from yesterday gives you all six totals. But sometimes you only need to know: is there a fire? Which client hit the budget wall first? Scanning all six every time wastes work.
I guess I'd stop as soon as I find the first one over budget. No point continuing the scan.
That is exactly what while with break does. Start at index zero, check the condition, advance the index, break when you find the answer. Unlike for, while gives you explicit control over when to stop:
i = 0
while i < len(clients):
total = clients[i]["rate"] * clients[i]["hours"]
if total > budget:
break # stop here
i += 1What happens to i after the break? Does it reset, or can I use it to know which client triggered it?
i holds its value after break — it points to the offending client. If the loop finishes without breaking, i == len(clients) and you return an empty dict to signal nothing found. That exhaustion check is the edge case to handle:
def find_first_over_budget(clients: list, budget: float) -> dict:
i = 0
while i < len(clients):
total = clients[i].get("rate", 0) * clients[i].get("hours", 0)
if total > budget:
print(f"Over budget: {clients[i]['name']} at ${total:.2f}")
return clients[i]
i += 1
return {}So once it finds the first over-budget client it returns immediately. No unnecessary computation.
Early exit. The loop that stops when it has the answer — efficient and readable. Six clients or sixty, it only does work up to the first hit.
My end-of-month review just got a priority flag built in.
One caution: the order of the client list matters. Sort by total descending before scanning if you want the highest over-budget client, not just the first one in the list.
while condition: runs until the condition is False. break exits immediately:
i = 0
while i < len(items):
if condition(items[i]):
break # exit — i points to the match
i += 1
# after loop: i == len(items) means no match found| Pattern | Use when |
|---|---|
for item in list: | Process every item |
while i < len(list): | Stop early; need the index after the loop |
compute_totals_per_client from yesterday gives you all six totals. But sometimes you only need to know: is there a fire? Which client hit the budget wall first? Scanning all six every time wastes work.
I guess I'd stop as soon as I find the first one over budget. No point continuing the scan.
That is exactly what while with break does. Start at index zero, check the condition, advance the index, break when you find the answer. Unlike for, while gives you explicit control over when to stop:
i = 0
while i < len(clients):
total = clients[i]["rate"] * clients[i]["hours"]
if total > budget:
break # stop here
i += 1What happens to i after the break? Does it reset, or can I use it to know which client triggered it?
i holds its value after break — it points to the offending client. If the loop finishes without breaking, i == len(clients) and you return an empty dict to signal nothing found. That exhaustion check is the edge case to handle:
def find_first_over_budget(clients: list, budget: float) -> dict:
i = 0
while i < len(clients):
total = clients[i].get("rate", 0) * clients[i].get("hours", 0)
if total > budget:
print(f"Over budget: {clients[i]['name']} at ${total:.2f}")
return clients[i]
i += 1
return {}So once it finds the first over-budget client it returns immediately. No unnecessary computation.
Early exit. The loop that stops when it has the answer — efficient and readable. Six clients or sixty, it only does work up to the first hit.
My end-of-month review just got a priority flag built in.
One caution: the order of the client list matters. Sort by total descending before scanning if you want the highest over-budget client, not just the first one in the list.
while condition: runs until the condition is False. break exits immediately:
i = 0
while i < len(items):
if condition(items[i]):
break # exit — i points to the match
i += 1
# after loop: i == len(items) means no match found| Pattern | Use when |
|---|---|
for item in list: | Process every item |
while i < len(list): | Stop early; need the index after the loop |
Daniel scans his client list each month for the first project that blew past a revenue budget — the one that needs an immediate scope conversation. Write `find_first_over_budget(clients, budget)` that returns the first client dict where `rate * hours` exceeds `budget`, or an empty dict if none found.
Tap each step for scaffolded hints.
No blank-editor panic.