Sign in to run and submit your work
Reading is open to everyone. Running code and saving drafts need an account so your work is yours and comes back on your next visit.
or
CODE WORKSPACE
A batch opens a receipt, writes rows, and closes it. If the sink rejects a row half way through, the receipt must still close — an open batch left behind is what makes the next run refuse to start.
Write run_batch(name, rows, fail_at) using a context manager with __enter__ and __exit__. Return the manifest of what happened.
Function to write
run_batch(name: str, rows: list[dict], fail_at: int | None) -> dictA manifest with the batch name, rows written, the open/close events, and any error message.
How to approach it
Run the failing case and look for the close event.
Sample cases
+ 2 held back until you submit
every row written
The happy path: the scope opens, three rows are written, and it closes.
Input
Argument 1
'2026-09-01'Argument 2
| id |
|---|
| 1 |
| 2 |
| 3 |
Argument 3
None
Returns
{
'batch': '2026-09-01',
'written': 3,
'events': [
'open 2026-09-01',
'close 2026-09-01'
],
'error': None
}the sink fails half way
One row written, then a failure — and the close still has to appear in the events.
Input
Argument 1
'2026-09-01'Argument 2
| id |
|---|
| 1 |
| 2 |
| 3 |
Argument 3
1Returns
{
'batch': '2026-09-01',
'written': 1,
'events': [
'open 2026-09-01',
'close 2026-09-01'
],
'error': 'sink rejected row 1'
}an empty batch
A batch with no rows still opens and closes, because the receipt is the point.
Input
Argument 1
'2026-09-01'Argument 2
[] (empty list)
Argument 3
None
Returns
{
'batch': '2026-09-01',
'written': 0,
'events': [
'open 2026-09-01',
'close 2026-09-01'
],
'error': None
}Constraints
{'batch': ..., 'written': ..., 'events': [...], 'error': ...}.events records open <name> on entry and close <name> on exit, in order.fail_at is an index that exists, raise a RuntimeError reading sink rejected row <index> at that point; error carries its message and written counts only the rows written before it.__exit__ must return False. The scope cleans up; it does not decide whether the failure matters.fail_at of None, or an index past the end, means a clean run with error of None.Worked example
Run three rows with fail_at of 1. One row is written, the sink rejects row 1, and the manifest carries sink rejected row 1.
The events are the point: open 2026-09-01 and close 2026-09-01, both of them. The starter returns early on the failure, so the close never runs — and the code looks completely reasonable, which is why this shape ships.
What this tests
That with exists to guarantee the exit rather than to look tidy, and that a context manager which suppresses exceptions has quietly converted a failed run into a successful one that wrote nothing.
run_batch(name: str, rows: list[dict], fail_at: int | None) -> dictSubmit for review to find out what your query gets right, what it gets wrong, and how it compares with the best working query for this exercise.
This scenario runs a full workspace — editor, canvas and results side by side. It needs a laptop or desktop to be usable. Open this page on a bigger screen to start building.