FA-97641 / Knitting and sewing pattern grading / Open access
Flat crochet circle planner: radius per round · case 01
A 10 cm coaster is worked to 20 cm.
ROOT CAUSE
Each round is assumed to add its height to the diameter rather than the radius.
VERIFIED REPAIR
Divide the diameter by twice the round height and round up.
Unsuccessful approach: Rounding to nearest can stop short of the target diameter.
Case contract
Base stitches per round: sc 6, hdc 8, dc 12 (others -> "error: stitch"). Each round adds one round height to the radius. rounds = ceiling(diameter/(2*height)). Round k has base*k stitches. Return [rounds, stitches in last round, total stitches base*rounds*(rounds+1)/2].
Why this case matters
Amigurumi and rug patterns size flat circles by rounds of evenly spaced increases.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(stitch, diameter, round_height):
BASE = {'sc': 6, 'hdc': 8, 'dc': 12}
if stitch not in BASE:
return 'error: stitch'
h = Fraction(round_height)
rounds = math.ceil(Fraction(diameter) / h)
b = BASE[stitch]
return [rounds, b * rounds, b * rounds * (rounds + 1) // 2]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['regression: radius per round', ['hdc', 12, '2'], [3, 24, 48]],
['repair check: radius per round', ['sc', 20, '0.75'], [14, 84, 630]],
['generated control 1', ['dc', 10, '1.5'], [4, 48, 120]],
['generated control 2', ['hdc', 5, '0.75'], [4, 32, 80]],
['generated control 3', ['sc', 10, '1.5'], [4, 24, 60]]],
[['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['regression: radius per round', ['sc', 12, '0.5'], [12, 72, 468]],
['repair check: radius per round', ['sc', 5, '2'], [2, 12, 18]],
['generated control 1', ['dc', 12, '2'], [3, 36, 72]],
['generated control 2', ['hdc', 15, '1'], [8, 64, 288]],
['generated control 3', ['tr', 20, '0.5'], 'error: stitch']],
[['treble unknown', ['tr', 10, '1'], 'error: stitch'], ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
['regression: radius per round', ['dc', 15, '0.5'], [15, 180, 1440]],
['repair check: radius per round', ['hdc', 10, '1.5'], [4, 32, 80]],
['generated control 1', ['hdc', 12, '0.5'], [12, 96, 624]],
['generated control 2', ['hdc', 30, '1'], [15, 120, 960]],
['generated control 3', ['sc', 10, '1.5'], [4, 24, 60]]],
[['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['regression: radius per round', ['dc', 10, '0.5'], [10, 120, 660]],
['repair check: radius per round', ['hdc', 10, '1.5'], [4, 32, 80]],
['generated control 1', ['tr', 5, '2'], 'error: stitch'],
['generated control 2', ['hdc', 15, '1.5'], [5, 40, 120]],
['generated control 3', ['hdc', 20, '2'], [5, 40, 120]]],
[['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['regression: radius per round', ['dc', 5, '2'], [2, 24, 36]],
['repair check: radius per round', ['hdc', 20, '0.75'], [14, 112, 840]],
['generated control 1', ['tr', 30, '2'], 'error: stitch'],
['generated control 2', ['tr', 20, '2'], 'error: stitch'],
['generated control 3', ['dc', 15, '1'], [8, 96, 432]]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| coaster | [20, 120, 1260] | [10, 60, 330] | Failed |
| dc mat | [20, 240, 2520] | [10, 120, 660] | Failed |
| treble unknown | error: stitch | error: stitch | Passed |
| regression: radius per round | [6, 48, 168] | [3, 24, 48] | Failed |
| repair check: radius per round | [27, 162, 2268] | [14, 84, 630] | Failed |
| generated control 1 | [7, 84, 336] | [4, 48, 120] | Failed |
| generated control 2 | [7, 56, 224] | [4, 32, 80] | Failed |
| generated control 3 | [7, 42, 168] | [4, 24, 60] | Failed |
SHA-256 / 9e5e228cc1baac064674222860736aa1802ea32ac5d0672bf30c0239813349b5
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(stitch, diameter, round_height):
BASE = {'sc': 6, 'hdc': 8, 'dc': 12}
if stitch not in BASE:
return 'error: stitch'
h = Fraction(round_height)
rounds = math.floor(Fraction(diameter) / (2 * h) + Fraction(1, 2))
b = BASE[stitch]
return [rounds, b * rounds, b * rounds * (rounds + 1) // 2]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['regression: radius per round', ['hdc', 12, '2'], [3, 24, 48]],
['repair check: radius per round', ['sc', 20, '0.75'], [14, 84, 630]],
['generated control 1', ['dc', 10, '1.5'], [4, 48, 120]],
['generated control 2', ['hdc', 5, '0.75'], [4, 32, 80]],
['generated control 3', ['sc', 10, '1.5'], [4, 24, 60]]],
[['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['regression: radius per round', ['sc', 12, '0.5'], [12, 72, 468]],
['repair check: radius per round', ['sc', 5, '2'], [2, 12, 18]],
['generated control 1', ['dc', 12, '2'], [3, 36, 72]],
['generated control 2', ['hdc', 15, '1'], [8, 64, 288]],
['generated control 3', ['tr', 20, '0.5'], 'error: stitch']],
[['treble unknown', ['tr', 10, '1'], 'error: stitch'], ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
['regression: radius per round', ['dc', 15, '0.5'], [15, 180, 1440]],
['repair check: radius per round', ['hdc', 10, '1.5'], [4, 32, 80]],
['generated control 1', ['hdc', 12, '0.5'], [12, 96, 624]],
['generated control 2', ['hdc', 30, '1'], [15, 120, 960]],
['generated control 3', ['sc', 10, '1.5'], [4, 24, 60]]],
[['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['regression: radius per round', ['dc', 10, '0.5'], [10, 120, 660]],
['repair check: radius per round', ['hdc', 10, '1.5'], [4, 32, 80]],
['generated control 1', ['tr', 5, '2'], 'error: stitch'],
['generated control 2', ['hdc', 15, '1.5'], [5, 40, 120]],
['generated control 3', ['hdc', 20, '2'], [5, 40, 120]]],
[['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['regression: radius per round', ['dc', 5, '2'], [2, 24, 36]],
['repair check: radius per round', ['hdc', 20, '0.75'], [14, 112, 840]],
['generated control 1', ['tr', 30, '2'], 'error: stitch'],
['generated control 2', ['tr', 20, '2'], 'error: stitch'],
['generated control 3', ['dc', 15, '1'], [8, 96, 432]]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| coaster | [10, 60, 330] | [10, 60, 330] | Passed |
| dc mat | [10, 120, 660] | [10, 120, 660] | Passed |
| treble unknown | error: stitch | error: stitch | Passed |
| regression: radius per round | [3, 24, 48] | [3, 24, 48] | Passed |
| repair check: radius per round | [13, 78, 546] | [14, 84, 630] | Failed |
| generated control 1 | [3, 36, 72] | [4, 48, 120] | Failed |
| generated control 2 | [3, 24, 48] | [4, 32, 80] | Failed |
| generated control 3 | [3, 18, 36] | [4, 24, 60] | Failed |
SHA-256 / 479c37e138c1e53e87ff14f4d72fafbab8473a2e7d30acee2f71a4e082f1a8e3
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(stitch, diameter, round_height):
BASE = {'sc': 6, 'hdc': 8, 'dc': 12}
if stitch not in BASE:
return 'error: stitch'
h = Fraction(round_height)
rounds = math.ceil(Fraction(diameter) / (2 * h))
b = BASE[stitch]
return [rounds, b * rounds, b * rounds * (rounds + 1) // 2]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['regression: radius per round', ['hdc', 12, '2'], [3, 24, 48]],
['repair check: radius per round', ['sc', 20, '0.75'], [14, 84, 630]],
['generated control 1', ['dc', 10, '1.5'], [4, 48, 120]],
['generated control 2', ['hdc', 5, '0.75'], [4, 32, 80]],
['generated control 3', ['sc', 10, '1.5'], [4, 24, 60]]],
[['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['regression: radius per round', ['sc', 12, '0.5'], [12, 72, 468]],
['repair check: radius per round', ['sc', 5, '2'], [2, 12, 18]],
['generated control 1', ['dc', 12, '2'], [3, 36, 72]],
['generated control 2', ['hdc', 15, '1'], [8, 64, 288]],
['generated control 3', ['tr', 20, '0.5'], 'error: stitch']],
[['treble unknown', ['tr', 10, '1'], 'error: stitch'], ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
['regression: radius per round', ['dc', 15, '0.5'], [15, 180, 1440]],
['repair check: radius per round', ['hdc', 10, '1.5'], [4, 32, 80]],
['generated control 1', ['hdc', 12, '0.5'], [12, 96, 624]],
['generated control 2', ['hdc', 30, '1'], [15, 120, 960]],
['generated control 3', ['sc', 10, '1.5'], [4, 24, 60]]],
[['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['regression: radius per round', ['dc', 10, '0.5'], [10, 120, 660]],
['repair check: radius per round', ['hdc', 10, '1.5'], [4, 32, 80]],
['generated control 1', ['tr', 5, '2'], 'error: stitch'],
['generated control 2', ['hdc', 15, '1.5'], [5, 40, 120]],
['generated control 3', ['hdc', 20, '2'], [5, 40, 120]]],
[['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['regression: radius per round', ['dc', 5, '2'], [2, 24, 36]],
['repair check: radius per round', ['hdc', 20, '0.75'], [14, 112, 840]],
['generated control 1', ['tr', 30, '2'], 'error: stitch'],
['generated control 2', ['tr', 20, '2'], 'error: stitch'],
['generated control 3', ['dc', 15, '1'], [8, 96, 432]]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| coaster | [10, 60, 330] | [10, 60, 330] | Passed |
| dc mat | [10, 120, 660] | [10, 120, 660] | Passed |
| treble unknown | error: stitch | error: stitch | Passed |
| regression: radius per round | [3, 24, 48] | [3, 24, 48] | Passed |
| repair check: radius per round | [14, 84, 630] | [14, 84, 630] | Passed |
| generated control 1 | [4, 48, 120] | [4, 48, 120] | Passed |
| generated control 2 | [4, 32, 80] | [4, 32, 80] | Passed |
| generated control 3 | [4, 24, 60] | [4, 24, 60] | Passed |
SHA-256 / 3f383fa5cc369a64e57f55fc5a9c37b8e2c3a6d1b581e9f917d2f9215fa1621a
Verification & scope
A deterministic toy contract stated in full here; it is a bounded teaching model, not an authoritative reference or standards implementation. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:52:34.148168+00:00.
Case digest / fb0a2a9405dca6171c77f027142beb21d8a24b9327f03a22f92332e0e0d15a9e