Batu Lab NotesPractical developer guides

Find the most common validation failures with Counter

By Batu ยท English technical notes

Also published in our Blogger archive.

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