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
The finance dashboard shows a running balance per account. The ledger table is written by the payments service in whatever order the events were processed, so the rows are neither grouped by account nor ordered by day.
Write running_total(rows, key_field, value_field, order_field). Return the rows with a running_total field added, ordered by key then by the ordering field.
Function to write
running_total(rows: list[dict], key_field: str, value_field: str, order_field: str) -> list[dict]Copies of the rows with a running_total field, ordered by key then by the ordering field.
How to approach it
Sort first, then keep the totals in a dict keyed by group rather than in one variable.
Sample cases
+ 2 held back until you submit
three accounts interleaved
The rows arrive ungrouped and out of order, one amount is negative and one is unusable.
Input
Argument 1
| account | day | amount |
|---|---|---|
| a2 | 2026-03-02 | 40 |
| a1 | 2026-03-01 | 10 |
| a1 | 2026-03-03 | 5.5 |
| a2 | 2026-03-01 | 100 |
| a1 | 2026-03-02 | -2.5 |
| a3 | 2026-03-01 | not a number |
Argument 2
'account'Argument 3
'amount'Argument 4
'day'Returns
| account | day | amount | running_total |
|---|---|---|---|
| a1 | 2026-03-01 | 10 | 10 |
| a1 | 2026-03-02 | -2.5 | 7.5 |
| a1 | 2026-03-03 | 5.5 | 13 |
| a2 | 2026-03-01 | 100 | 100 |
| a2 | 2026-03-02 | 40 | 140 |
| a3 | 2026-03-01 | not a number | 0 |
no rows
An empty ledger returns an empty list rather than one row of zeroes.
Input
Argument 1
[] (empty list)
Argument 2
'account'Argument 3
'amount'Argument 4
'day'Returns
[] (empty list)
one account only
A single account still has to be sorted before the total means anything.
Input
Argument 1
| account | day | amount |
|---|---|---|
| solo | 2026-03-02 | 3 |
| solo | 2026-03-01 | 7 |
Argument 2
'account'Argument 3
'amount'Argument 4
'day'Returns
| account | day | amount | running_total |
|---|---|---|---|
| solo | 2026-03-01 | 7 | 7 |
| solo | 2026-03-02 | 3 | 10 |
Constraints
order_field, ascending, compared as text.key_field then order_field, both ascending.Worked example
Account a1 has three rows spread through the file: 10.0 on the first, -2.5 on the second and 5.5 on the third. Sorted, its running total reads 10.0, then 7.5, then 13.0. Left in arrival order it reads 10.0, then 15.5, then 13.0 — which rises and then falls, and is exactly the kind of chart that gets escalated.
The trap that survives testing longest is a single total variable declared outside the loop. It gives the right answer on a file containing one account, and every developer's first test file contains one account. On real data a2 starts from wherever a1 finished.
What this tests
Carrying per-group state through one pass, and knowing that sorting is a precondition for accumulation rather than a presentational nicety. The state has to live in a dict keyed by group, not in a variable.
running_total(rows: list[dict], key_field: str, value_field: str, order_field: str) -> list[dict]Submit 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.