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
Before the loader writes anything, it checks each row against the table's declared schema. Today it stops at the first bad row, which means a file with fifty problems takes fifty runs to fix. The team wants one pass that reports every problem in every row.
Write validate_rows(rows, schema). The schema maps a field name to one of str, int, float or bool.
Function to write
validate_rows(rows: list[dict], schema: dict) -> dictA dict with valid — the passing rows — and rejected, each with an index and its list of reasons.
How to approach it
Write the per-field check first; the row check is a loop that collects rather than returns.
Sample cases
+ 2 held back until you submit
a mixed load file
A clean row, a stringified number, a missing field, an extra field, and a row that fails three rules at once.
Input
Argument 1
[
{
'sku': 'A1',
'qty': 2,
'price': 9.99,
'active': True
},
{
'sku': 'B2',
'qty': '2',
'price': 5,
'active': False
},
{
'sku': 'C3',
'price': 1.5,
'active': True
},
{
'sku': 'D4',
'qty': 1,
'price': 7,
'active': True,
'note': 'extra fields are fine'
},
{
'sku': 55,
'qty': None,
'price': 3,
'active': 'yes'
}
]Argument 2
{
'sku': 'str',
'qty': 'int',
'price': 'float',
'active': 'bool'
}Returns
{
'valid': [
{
'sku': 'A1',
'qty': 2,
'price': 9.99,
'active': True
},
{
'sku': 'D4',
'qty': 1,
'price': 7,
'active': True,
'note': 'extra fields are fine'
}
],
'rejected': [
{
'index': 1,
'reasons': [
'qty: expected int, got str'
]
},
{
'index': 2,
'reasons': [
'qty: missing'
]
},
{
'index': 4,
'reasons': [
'sku: expected str, got int',
'qty: expected int, got NoneType',
'active: expected bool, got str'
]
}
]
}an empty file
No rows means both lists come back empty rather than the key being absent.
Input
Argument 1
[] (empty list)
Argument 2
{
'sku': 'str',
'qty': 'int',
'price': 'float',
'active': 'bool'
}Returns
{
'valid': [],
'rejected': []
}an empty schema
With nothing declared there is nothing to fail, so every row is valid.
Input
Argument 1
[
{
'sku': 'A1',
'qty': 2,
'price': 9.99,
'active': True
},
{
'sku': 'B2',
'qty': '2',
'price': 5,
'active': False
},
{
'sku': 'C3',
'price': 1.5,
'active': True
},
{
'sku': 'D4',
'qty': 1,
'price': 7,
'active': True,
'note': 'extra fields are fine'
},
{
'sku': 55,
'qty': None,
'price': 3,
'active': 'yes'
}
]Argument 2
{}Returns
{
'valid': [
{
'sku': 'A1',
'qty': 2,
'price': 9.99,
'active': True
},
{
'sku': 'B2',
'qty': '2',
'price': 5,
'active': False
},
{
'sku': 'C3',
'price': 1.5,
'active': True
},
{
'sku': 'D4',
'qty': 1,
'price': 7,
'active': True,
'note': 'extra fields are fine'
},
{
'sku': 55,
'qty': None,
'price': 3,
'active': 'yes'
}
],
'rejected': []
}Constraints
field: missing. A wrong type reports field: expected <declared>, got <actual>, where the actual type is Python's own name for it.float: 7 is a legitimate price.bool. True is not an int here and 1 is not a bool, even though Python's isinstance says otherwise.valid — copies of the passing rows in order — and rejected, each entry carrying the row's index in the input and its reasons.Worked example
Row B2 sends its quantity as the string 2. It is obviously a quantity to a human and it is still a rejection: the loader is about to write into an integer column, and a silent coercion here is how a column ends up holding both kinds of value forever.
The last row fails three rules at once — a numeric sku, a null qty and a string where a bool was declared. Returning only the first of those means the person fixing the file learns about one problem per round trip. Returning all three is the entire point of the exercise, and it costs one list instead of an early return.
What this tests
Accumulating errors instead of failing fast, and knowing Python's type hierarchy well enough to write a check that means what a schema means. isinstance(True, int) being true is not a curiosity — it is a live bug in most hand-written validators.
validate_rows(rows: list[dict], schema: 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.