Example

A boundary table convicts a rule, not a single input

Run the six-cell seam table against a page-count function and watch the divergence pattern convict a rule defect, not one input.

Forty-seven passing tests and the refunds are still wrong. The suite samples middles, and middles never land on a seam. This program runs the chapter’s six-cell boundary table against a page-count function and reads the shape of the divergences: one failing input is an observation, a pattern of them is evidence about the rule. It composes the chapter’s paginate, its defective chunk_count, and the metamorphic relation the chapter proposes as oracle.

Run it

Save this as boundary_table.py and run it with Python 3.11 or later. It uses the standard library only.

"""Chapter 7: a boundary table separates a single-point defect from a broken rule."""

SIZE = 10
CELLS = [("empty", 0), ("single", 1), ("seam-1", 9), ("seam", 10),
         ("seam+1", 11), ("large", 20)]


def paginate(items, page_size):
    """Split items into pages of page_size. Returns list of pages."""
    pages = []
    for i in range(0, len(items), page_size):
        pages.append(items[i:i + page_size])
    return pages


def chunk_count(n, size):
    """How many pages for n items at page size `size`?"""
    return (n // size) + 1          # defect: exact multiples get a phantom page


def chunk_count_fixed(n, size):
    """The ceiling form: one extra page only when a real remainder exists."""
    return (n + size - 1) // size


def spec_pages(n, size):
    """What the spec requires: no page for an empty input, else the ceiling."""
    return 0 if n == 0 else (n + size - 1) // size


print(f"boundary table (page size {SIZE})")
print(f"{'cell':8} {'n':>4} {'spec':>5} {'H1':>5} {'H2':>5} {'observed':>9}  verdict")
diverged = []
for label, n in CELLS:
    expected = spec_pages(n, SIZE)
    observed = chunk_count(n, SIZE)
    h1 = 1 if n == 0 else expected          # empty-only defect
    h2 = (n // SIZE) + 1                    # fencepost defect
    if observed != expected:
        diverged.append(label)
    print(f"{label:8} {n:>4} {expected:>5} {h1:>5} {h2:>5} {observed:>9}  "
          f"{'match' if observed == expected else 'DIVERGES'}")

print(f"diverging cells: {diverged}")
print(f"all diverging cells are exact multiples of {SIZE}: "
      f"{all(n % SIZE == 0 for label, n in CELLS if label in diverged)}")

# The metamorphic relation, checked without a property-testing framework.
violations = [(k, size) for size in range(1, 11) for k in range(1, 11)
              if chunk_count(k * size, size) != k]
print(f"relation chunk_count(k * size, size) == k violated at {len(violations)} pairs")
k, size = violations[0]
print(f"smallest counterexample: k={k}, size={size}, chunk_count = {chunk_count(k, size)}")
print("ceiling form passes every cell: "
      f"{all(chunk_count_fixed(n, SIZE) == spec_pages(n, SIZE) for _, n in CELLS)}")
print(f"paginate handles the empty input: {paginate([], SIZE) == []}")

Expect three diverging cells, not one, all at exact multiples of the page size.

Expected outcome

boundary table (page size 10)
cell        n  spec    H1    H2  observed  verdict
empty       0     0     1     1         1  DIVERGES
single      1     1     1     1         1  match
seam-1      9     1     1     1         1  match
seam       10     1     1     2         2  DIVERGES
seam+1     11     2     2     2         2  match
large      20     2     2     3         3  DIVERGES
diverging cells: ['empty', 'seam', 'large']
all diverging cells are exact multiples of 10: True
relation chunk_count(k * size, size) == k violated at 100 pairs
smallest counterexample: k=1, size=1, chunk_count = 2
ceiling form passes every cell: True
paginate handles the empty input: True

The table matches the chapter’s own illustration cell for cell, including the observations 1, 2 and 3 at n = 0, 10 and 20.

The pattern names the mechanism

H1 and H2 agree at n = 0: both predict a diverging cell there. Only H2 predicts divergence at n = 10 and n = 20, and the run diverges at both. So the defect is not empty-only: it is the N = 0 instance of a general off-by-one, and the fix is the ceiling rule, not an empty-case patch.

The chapter states the relation that convicts the arithmetic without an absolute oracle at the seam:

def chunk_count(n, size):
    """How many pages for n items at page size `size`?"""
    return (n // size) + 1          # defect: exact multiples get a phantom page

Mechanism and limitations

Documented: the chapter states that the buggy (n // size) + 1 assumes integer division always discarded a remainder, true across every regime interior and false exactly where the remainder is zero; that the illustration diverges at n = 0, 10 and 20; that the ceiling form (n + size - 1) // size is the rule-level fix while an empty-case patch is a silencing patch leaving n = 10 and n = 20 broken; and that its Hypothesis test shrinks to k = 1, size = 1.

Observed: the run above. Three cells diverged, at 0, 10 and 20, and all three were exact multiples of the page size. The relation was violated at every one of the hundred pairs tested, the smallest counterexample being k = 1, size = 1, the case the chapter’s shrinking test reaches. The ceiling form passed every cell and plain paginate was correct for the empty input, so the defect is in the sibling’s arithmetic.

Not shown. The chapter’s own test uses Hypothesis, unavailable here, so the relation is checked by an explicit loop over a bounded grid rather than by random generation with shrinking; the smallest counterexample found is the smallest in that grid, not a proved minimum. No property is asserted over arbitrary sizes.

Read the chapter .

Understand this example

Copy this prompt into your AI tool. No code runs here.

Apply this example

Copy this prompt into your AI tool. No code runs here.