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 load job tags each row with a status. The next step should process the rows that did not fail first, and the failed rows at the end, because they are only reported. Within each side, the rows must keep the order they arrived in, since the order is the order of the source file.
Write move_failed_last(rows). rows is a list of dicts with an id and a status. Return a dict {"rows": list, "ok_count": int}: the reordered rows, and how many rows are in the first part.
Function to write
move_failed_last(rows: list[dict]) -> dictA dict with the reordered rows (not failed first, failed last, each in original order) and the count of rows that did not fail.
How to approach it
Walk the rows once and copy every row that did not fail to the front. Walk them a second time and copy the failed ones after. Do not sort.
Sample cases
+ 2 held back until you submit
failures in the middle
`r2` and `r4` move to the end. The others keep their order: `r1`, `r3`, `r5`.
Input
Argument 1
| id | status |
|---|---|
| r1 | ok |
| r2 | failed |
| r3 | ok |
| r4 | failed |
| r5 | retried |
Returns
{
'rows': [
{
'id': 'r1',
'status': 'ok'
},
{
'id': 'r3',
'status': 'ok'
},
{
'id': 'r5',
'status': 'retried'
},
{
'id': 'r2',
'status': 'failed'
},
{
'id': 'r4',
'status': 'failed'
}
],
'ok_count': 3
}nothing failed
With no failures, the rows come back in the same order.
Input
Argument 1
| id | status |
|---|---|
| a | ok |
| b | ok |
Returns
{
'rows': [
{
'id': 'a',
'status': 'ok'
},
{
'id': 'b',
'status': 'ok'
}
],
'ok_count': 2
}everything failed
Every row is a failure, so the order stays the same and `ok_count` is 0.
Input
Argument 1
| id | status |
|---|---|
| a | failed |
| b | failed |
Returns
{
'rows': [
{
'id': 'a',
'status': 'failed'
},
{
'id': 'b',
'status': 'failed'
}
],
'ok_count': 0
}no rows
An empty batch gives an empty list and an `ok_count` of 0.
Input
Argument 1
[] (empty list)
Returns
{
'rows': [],
'ok_count': 0
}Constraints
status is exactly "failed". Every other status counts as not failed.ok_count is the number of rows that did not fail.{"rows": [], "ok_count": 0}.Worked example
Take the rows r1 ok, r2 failed, r3 ok, r4 failed, r5 retried. Pass 1: walk the rows, and copy every row that is not failed to the next free place at the front. That writes r1, r3 and r5, and the write position is now 3, which is the ok_count. Pass 2: walk the rows again, and copy each failed row after them: r2, then r4. The answer is r1, r3, r5, r2, r4, with ok_count 3.
The trap: sorting by the status text puts failed before ok and retried, because f comes before o. That moves the failures to the front instead of the end.
What this tests
A stable partition with a write pointer, the same idea as 'Move Zeroes'. The write pointer marks the next free place, and the read pointer walks the rows. Doing it in two passes keeps both sides in order, which an in-place swap would not. Data engineers use this to separate good and bad rows, or to push nulls to the end, without sorting.
move_failed_last(rows: list[dict]) -> 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.