Validation Pipelines
Validate Value Ranges
Report values that fall outside an allowed [lo, hi] band. Rather than flagging every element (True/False), collect the offending values for an error report. By hand, loop with an index and append any out-of-band value. With pandas, filter with a boolean mask to get the violating rows directly.
By hand
Loop with range(len(values)) and test values[i] < lo or values[i] > hi.
Collect offending values in invalid. The trace shows invalid growing
only on the out-of-band iterations (index 1: −3, index 4: 89, index 6: −1).
values = [12, -3, 45, 7, 89, 5, -1]
lo = 0
hi = 50
invalid = []
for i in range(len(values)):
if values[i] < lo or values[i] > hi:
invalid.append(values[i])
print('RESULT:', invalid)
values ← [12, -3, 45, 7, 89, 5, -1]
1values = [12, -3, 45, 7, 89, 5, -1]2lo = 0values this step[12, -3, 45, 7, 89, 5, -1]valueslo ← 0
1values = [12, -3, 45, 7, 89, 5, -1]2lo = 03hi = 50values this step0lohi ← 50
2lo = 03hi = 504invalid = []values this step50hiinvalid ← []
3hi = 504invalid = []5for i in range(len(values)):values this step[]invalidi ← 0
4invalid = []5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:values this step0iif values[i] < lo or values[i] > hi:
5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:7 invalid.append(values[i])i ← 1
4invalid = []5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:values this step0 → 1iif values[i] < lo or values[i] > hi:
5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:7 invalid.append(values[i])invalid ← [-3]
6 if values[i] < lo or values[i] > hi:7 invalid.append(values[i])8print('RESULT:', invalid)values this step[] → [-3]invalidi ← 2
4invalid = []5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:values this step1 → 2iif values[i] < lo or values[i] > hi:
5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:7 invalid.append(values[i])i ← 3
4invalid = []5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:values this step2 → 3iif values[i] < lo or values[i] > hi:
5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:7 invalid.append(values[i])i ← 4
4invalid = []5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:values this step3 → 4iif values[i] < lo or values[i] > hi:
5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:7 invalid.append(values[i])invalid ← [-3, 89]
6 if values[i] < lo or values[i] > hi:7 invalid.append(values[i])8print('RESULT:', invalid)values this step[-3] → [-3, 89]invalidi ← 5
4invalid = []5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:values this step4 → 5iif values[i] < lo or values[i] > hi:
5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:7 invalid.append(values[i])i ← 6
4invalid = []5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:values this step5 → 6iif values[i] < lo or values[i] > hi:
5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:7 invalid.append(values[i])invalid ← [-3, 89, -1]
6 if values[i] < lo or values[i] > hi:7 invalid.append(values[i])8print('RESULT:', invalid)values this step[-3, 89] → [-3, 89, -1]invalidfor i in range(len(values)):
4invalid = []5for i in range(len(values)):6 if values[i] < lo or values[i] > hi:stdout ← RESULT: [-3, 89, -1]
7 invalid.append(values[i])8print('RESULT:', invalid)values this stepRESULT: [-3, 89, -1]stdout
With pandas
Build a boolean mask with (df['x'] < lo) | (df['x'] > hi), then use it to
filter the DataFrame. The violating rows keep their original index labels,
so the snapshot shows both which positions (index: [1, 4, 6]) and which
values are invalid.
import pandas as pd
from dalib.display import set_display
set_display()
values = [12, -3, 45, 7, 89, 5, -1]
lo = 0
hi = 50
df = pd.DataFrame({'x': values})
mask = (df['x'] < lo) | (df['x'] > hi)
invalid = df[mask]
result = invalid['x'].tolist()
print('lo:', lo, 'hi:', hi)
print('violations:', len(result))
print('index:', invalid.index.tolist())
print('RESULT:', result)
lo: 0 hi: 50
violations: 3
index: [1, 4, 6]
RESULT: [-3, 89, -1]
Implementation notes
- This lesson reports offending values;
range-flag(ch06) flags every element True/False. Use range-flag when you need a boolean mask for further processing; use validate-value-ranges when you need a list of errors to surface to a caller. - The violating rows preserve their original index, which is useful for tracing back to the source row in a larger DataFrame.
- Cross-reference:
range-flag(chapter 06) for the boolean-flag version of the same out-of-band check.