Before calculating a summary from a research export, decide which values your codebook treats as missing. One site might leave a field blank while another sends 999. A numeric conversion will accept 999 and carry it into a mean.
Here is a fictional symptom score with a range of 0–20. The agreed missing tokens are blank and NA. The check keeps those rows separate and flags a numeric value outside the range for review.
from csv import DictReader from io import StringIO source = StringIO("record,score\nA,6\nB,NA\nC,999\nD,0\n") valid = [] missing = [] review = [] for row in DictReader(source): record = row["record"] raw = row["score"].strip() if raw in {"", "NA"}: missing.append(record) continue try: score = int(raw) except ValueError: review.append((record, raw)) continue if 0 <= score <= 20: valid.append((record, score)) else: review.append((record, raw)) print("Valid:", valid) print("Missing:", missing) print("Review:", review) Valid: [('A', 6), ('D', 0)] Missing: ['B'] Review: [('C', '999')] The zero is a valid score. Keep the raw export and ask the data owner what 999 means before adding it to the missing-token list. The range and tokens belong to this example. Use the definitions from your own codebook.

