Threshold Filter

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

Return the metrics from the host snapshot readings whose value meets or exceeds threshold, as a new dict keyed by their original metric names.

Above the line or below it.

Example 1

Input:

readings = {"cpu":85,"mem":40,"net":15,"disk":92}, threshold = 50

Output:

{"cpu":85,"disk":92}

Example 2

Input:

readings = {"sda":70,"sdb":45,"sdc":80}, threshold = 70

Output:

{"sda":70,"sdc":80}

Worked solution and explanation

What this really is

This is a value filter over a mapping, dressed up as a metrics check. Two things have to survive the filter: the metric names, and the readings that sit exactly on the cutoff. Almost everyone keeps the names. The answers come apart at the boundary. 'Meets or exceeds' means sda at 70 against a cutoff of 70 stays, and the second example shows exactly that. Type > out of habit and you silently drop every metric pinned at the cutoff, which is usually the one somebody wanted to see.

Values only
[value for value in readings.values() if value >= threshold] gives [85, 92]. The numbers are right, but nobody can tell which host metric they came from.
Mapping kept
Iterating readings.items() keeps each value next to its name, so the result {"cpu": 85, "disk": 92} is still a snapshot a dashboard can read.

Break down the requirements

Step 1: Iterate readings.items(), not the keys

You need the name to key the output and the value to compare. Looping over the keys and then reading readings[metric] also works, but it adds a second lookup per entry and a line the reader has to check.

Step 2: Compare with >=

'Meets or exceeds' is inclusive. Say the boundary out loud before you type it, then check it against the sda example. The negative case behaves the same way: a skew of -1.0 against a cutoff of -1.0 is kept.

Step 3: Return a fresh dict

A comprehension builds a new dict and leaves readings untouched. Deleting entries in place while iterating raises RuntimeError: dictionary changed size during iteration, and even when it runs, it corrupts a snapshot other code still reads.

The solution

Inclusive filter that keeps the keys
def dict_filter(readings, threshold):
    return {metric: value for metric, value in readings.items() if value >= threshold}

Common follow-up questions