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 partner sends NDJSON — one JSON object per line — and you re-emit it into the lake. Two runs over the same input must produce identical bytes, so a checksum means something and a diff shows only real changes.
Write normalise_ndjson(text, key_fields). It returns the re-emitted text, how many records survived, and which lines were rejected.
Function to write
normalise_ndjson(text: str, key_fields: list[str]) -> dictA dict with the rendered `ndjson`, the surviving record count, and the rejected lines.
How to approach it
Run it twice and compare the strings — then look at what happened to the bad lines.
Sample cases
+ 2 held back until you submit
two records, a blank line and two bad lines
Everything at once: sorting, key ordering, a blank line skipped, and two different kinds of bad line.
Input
Argument 1
'{"sku":"B7","order_id":1042}
{"order_id":1041,"sku":"A1"}
not json
[1,2]
'Argument 2
[
'order_id'
]Returns
{
'ndjson': '{"order_id":1041,"sku":"A1"}
{"order_id":1042,"sku":"B7"}',
'records': 2,
'rejected': [
{
'line': 3,
'text': 'not json'
},
{
'line': 4,
'text': '[1,2]'
}
]
}already sorted and already canonical
Input that is already correct comes back byte-identical, which is what makes a re-run diffable.
Input
Argument 1
'{"order_id":1041}
{"order_id":1042}
'Argument 2
[
'order_id'
]Returns
{
'ndjson': '{"order_id":1041}
{"order_id":1042}',
'records': 2,
'rejected': []
}empty input
No text means no records, an empty rendering, and no rejections — not an error.
Input
Argument 1
''Argument 2
[
'order_id'
]Returns
{
'ndjson': '',
'records': 0,
'rejected': []
}Constraints
{'ndjson': <text>, 'records': <count>, 'rejected': <list>}.key_fields in order. Records with the same key keep their input order.{'line': <0-based index>, 'text': <the line>}.None.Worked example
The input holds a record for sku B7, a blank line, a record for sku A1, the text not json, and the array [1,2]. The sort key is order_id.
Sorted and rendered canonically, A1 comes first and both lines come back with their keys in the same order — note that the B7 record arrived with sku first and leaves with order_id first. Two lines are rejected: not json will not decode at all, and [1,2] decodes perfectly well into something that is not a record.
What this tests
That byte-stable output is engineered rather than incidental — sorted keys, fixed separators, a deterministic row order — and that a bad line is data to report rather than an exception that loses the batch.
normalise_ndjson(text: str, key_fields: list[str]) -> 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.