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: TrueThe 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 pageMechanism 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.
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.