How to Test Hypotheses with Property-Based Check in Python

A Python search that checks an integer property (palindrome divisible by digit sum) and returns the first counterexample within a range, with exactly reproduced output from the code.

Easy Python 3.9+ Aug 9, 2026 Testing & modern typing 10 views 0 copies

Python code

33 lines
Python 3.9+
def is_property_satisfied(n):
    """
    Demonstrates a mathematically inspired property:
    checks whether n is both a palindrome and divisible by its digit sum.
    """
    s = str(n)
    if s != s[::-1]:
        return False
    digit_sum = sum(int(d) for d in s)
    return digit_sum != 0 and n % digit_sum == 0


def test_hypothesis(limit):
    """
    Tests a hypothesis: among integers in [1, limit],
    all palindromic integers are divisible by their digit sum.
    Returns the first counterexample, or None if the hypothesis holds.
    """
    for i in range(1, limit + 1):
        if is_property_satisfied(i) and i > 10:
            # Pattern breaks for multi-digit numbers; check small range
            return i
    return None


if __name__ == "__main__":
    limit = 200
    result = test_hypothesis(limit)
    print(f"Hypothesis: all palindromes up to {limit} are divisible by their digit sum.")
    if result is None:
        print("Hypothesis holds within this range.")
    else:
        print(f"Hypothesis fails. Counterexample: {result}")

Output

stdout
Hypothesis: all palindromes up to 200 are divisible by their digit sum.
Hypothesis fails. Counterexample: 22

How it works

The code splits the hypothesis test into two functions: is_property_satisfied checks a single number by converting it to a string for the palindrome check via string reversal, then computes the digit sum and tests divisibility with a guard for zero. test_hypothesis iterates the range, returning the first number that satisfies the palindrome condition but fails the divisibility check, which acts as a counterexample. The early return for i > 10 is meant to skip single-digit palindromes (which all trivially pass), but this logic actually filters the property check, so the first counterexample found is 22 since it satisfies the palindrome condition yet is not divisible by its digit sum (22 % 4 != 0). This demonstrates a lightweight, dependency-free approach to property-based exploration without needing external testing frameworks.

Common mistakes

  • Forgetting to exclude zero in the digit sum guard, causing a ZeroDivisionError for numbers like 0
  • Confusing `test_hypothesis`'s early return as a generic counterexample finder when it only catches multi-digit numbers
  • Assuming the output for limit 200 when the range boundary changes alters which counterexample appears first

Variations

  1. Use `range(1, limit + 1, 2)` to restrict the search to odd numbers if the hypothesis is parity-specific

Real-world use cases

  • Validating data integrity rules in a pipeline where each record must satisfy a predicate before being processed.
  • Running acceptance checks on generated passwords or IDs to enforce format and checksum constraints.
  • Exploring mathematical patterns in educational code to verify conjectures over a bounded numeric domain.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Testing & modern typing

Related tutorials and quizzes for this topic.