Find the most common validation failures with Counter

A validation report is more useful when it identifies recurring categories instead of merely listing every bad record. collections.Counter counts hashable keys, so short stable failure codes are a natural input. The failure_codes() function returns zero, one, or two codes for each record. A generator feeds every returned code into Counter, producing a frequency mapping.

The sample has three email_missing_at failures and two age_below_18 failures. counts.most_common(2) returns pairs from the highest count down, and the assertions check the exact two pairs before they are printed. This makes the output suitable for a small deterministic summary while the original records remain available for detailed investigation.

Choose codes deliberately. A counter cannot tell whether several email failures share one root cause, and broad categories can hide distinct defects. most_common() uses encounter order to break equal counts, so a tie should not be presented as a stronger ranking. Counter also permits zero and negative counts, although a simple failure tally should normally increment only real failures. Its keys must be hashable; return strings, enums, or tuples rather than mutable dictionaries or lists.

AI assistance was used in preparing this article.

Source: Python Counter.most_common() documentation

Example

from collections import Counter


def failure_codes(record):
    codes = []
    if "@" not in record["email"]:
        codes.append("email_missing_at")
    if record["age"] < 18:
        codes.append("age_below_18")
    return codes


records = [
    {"email": "invalid", "age": 16},
    {"email": "valid@example.test", "age": 17},
    {"email": "also-invalid", "age": 21},
    {"email": "third-invalid", "age": 25},
]

counts = Counter(
    code
    for record in records
    for code in failure_codes(record)
)
top_failures = counts.most_common(2)

assert counts["email_missing_at"] == 3
assert counts["age_below_18"] == 2
assert top_failures == [("email_missing_at", 3), ("age_below_18", 2)]

for code, count in top_failures:
    print(f"{code}: {count}")

Expected stdout

email_missing_at: 3
age_below_18: 2

Comments

Popular posts from this blog

Compare Two Text Files in Python Without Modifying Them

Seven CSV Quality Checks to Run Before Importing Data

Explain why SQLite transactions cannot make an HTTP call atomic