Quality Gate

An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.

Domain
Python
Difficulty
easy
Seniority
L3

Problem

A sensor rig streams a batch of readings, and quality control needs the position of the first reading that slips out of spec, where in spec means strictly above zero. Return that index, or -1 when every reading passes and when the batch is empty.

Not everything passes inspection.

Example 1

Input:

readings = [4,9,2]

Output:

-1

Example 2

Input:

readings = [5,-2,0,4]

Output:

1

Worked solution and explanation

What this problem really is

Strip the inspection costume and this is a left-to-right search for the first element that breaks a predicate. Everyone can test reading <= 0. What separates candidates is two decisions: return the moment you hit the first failure instead of grinding through the rest of the batch, and produce a clean sentinel for the two batches that have no failure at all, the all-pass batch and the empty one. Miss that and your report either points at the wrong reading or crashes on an empty stream.


Why a shortcut betrays you

It is tempting to reduce the batch to a number. But min(readings) tells you the worst reading, not WHERE it sits, and it throws on the empty batch. all(r > 0 for r in readings) collapses everything to a yes or no and discards the index the caller actually asked for. A position question forces you to walk the readings in order: there is no summary statistic that hands you the first failing spot.

Collect then pick
[i for i, r in enumerate(readings) if r <= 0][0] builds the whole list of failing positions, then grabs the first. It scans every reading even after the answer is known, and it raises IndexError on an all-pass or empty batch because that list is empty.
Scan and stop
The loop returns at the first failing index and never allocates a list. When it falls through, there was no failure, so -1 comes back for free, covering the all-pass and empty batches with the same line.

Step 1: Test each reading against the predicate

Walk the readings in order and compare each against the bar. A reading of exactly 0 counts as a failure, because in spec means strictly greater than zero.

Step 2: Return the index on the first failure

The answer is known the instant you see a non-positive reading, so return its index right there. There is no reason to look at the rest of the batch, and returning the FIRST index is the whole point.

Step 3: Return -1 once the loop finishes

Falling out of the loop means nothing failed, including the case where there was nothing to check. Returning -1 here is what makes the all-pass batch and the empty batch share one clean sentinel.


The solution

First-failure scan with early return
def first_failing_reading(readings):
    for index, reading in enumerate(readings):
        if reading <= 0:
            return index
    return -1

Common follow-up questions