FA-97646 / Knitting and sewing pattern grading / Open access
Flat crochet circle planner: last round count · case 01
A double crochet circle claims only 6 increases per round.
ROOT CAUSE
Increases per round assume the single crochet rate for every stitch type.
VERIFIED REPAIR
Last round has base*rounds stitches.
Unsuccessful approach: Counting one extra round overstates the final round.
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) / (2 * h))
b = BASE[stitch]
return [rounds, b + 6 * (rounds - 1), 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: last round count', ['dc', 10, '1.5'], [4, 48, 120]],
['repair check: last round count', ['sc', 10, '1.5'], [4, 24, 60]],
['generated control 1', ['dc', 15, '0.75'], [10, 120, 660]],
['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
['generated control 3', ['dc', 12, '0.5'], [12, 144, 936]]],
[['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['repair check: last round count', ['hdc', 5, '0.75'], [4, 32, 80]],
['generated control 1', ['tr', 15, '0.75'], 'error: stitch'],
['generated control 2', ['tr', 10, '2'], 'error: stitch'],
['generated control 3', ['tr', 15, '1'], 'error: stitch'],
['generated control 4', ['sc', 5, '0.75'], [4, 24, 60]]],
[['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: last round count', ['dc', 12, '0.75'], [8, 96, 432]],
['repair check: last round count', ['hdc', 20, '0.5'], [20, 160, 1680]],
['generated control 1', ['tr', 10, '0.5'], 'error: stitch'],
['generated control 2', ['tr', 15, '1.5'], 'error: stitch'],
['generated control 3', ['dc', 5, '1.5'], [2, 24, 36]]],
[['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: last round count', ['hdc', 5, '1.5'], [2, 16, 24]],
['repair check: last round count', ['sc', 30, '1.5'], [10, 60, 330]],
['generated control 1', ['sc', 15, '1'], [8, 48, 216]],
['generated control 2', ['tr', 5, '0.5'], 'error: stitch'],
['generated control 3', ['tr', 20, '1.5'], 'error: stitch']],
[['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: last round count', ['hdc', 12, '1.5'], [4, 32, 80]],
['repair check: last round count', ['sc', 10, '1'], [5, 30, 90]],
['generated control 1', ['dc', 30, '2'], [8, 96, 432]],
['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
['generated control 3', ['dc', 15, '0.75'], [10, 120, 660]]]]
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, 66, 660] | [10, 120, 660] | Failed |
| treble unknown | error: stitch | error: stitch | Passed |
| regression: last round count | [4, 30, 120] | [4, 48, 120] | Failed |
| repair check: last round count | [4, 24, 60] | [4, 24, 60] | Passed |
| generated control 1 | [10, 66, 660] | [10, 120, 660] | Failed |
| generated control 2 | error: stitch | error: stitch | Passed |
| generated control 3 | [12, 78, 936] | [12, 144, 936] | Failed |
SHA-256 / d5ca42dff3b1ad0a3ac086e86301a6599f9fe095c173dea824c8e046f9bf93e0
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.ceil(Fraction(diameter) / (2 * h))
b = BASE[stitch]
return [rounds, b * (rounds + 1), 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: last round count', ['dc', 10, '1.5'], [4, 48, 120]],
['repair check: last round count', ['sc', 10, '1.5'], [4, 24, 60]],
['generated control 1', ['dc', 15, '0.75'], [10, 120, 660]],
['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
['generated control 3', ['dc', 12, '0.5'], [12, 144, 936]]],
[['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['repair check: last round count', ['hdc', 5, '0.75'], [4, 32, 80]],
['generated control 1', ['tr', 15, '0.75'], 'error: stitch'],
['generated control 2', ['tr', 10, '2'], 'error: stitch'],
['generated control 3', ['tr', 15, '1'], 'error: stitch'],
['generated control 4', ['sc', 5, '0.75'], [4, 24, 60]]],
[['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: last round count', ['dc', 12, '0.75'], [8, 96, 432]],
['repair check: last round count', ['hdc', 20, '0.5'], [20, 160, 1680]],
['generated control 1', ['tr', 10, '0.5'], 'error: stitch'],
['generated control 2', ['tr', 15, '1.5'], 'error: stitch'],
['generated control 3', ['dc', 5, '1.5'], [2, 24, 36]]],
[['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: last round count', ['hdc', 5, '1.5'], [2, 16, 24]],
['repair check: last round count', ['sc', 30, '1.5'], [10, 60, 330]],
['generated control 1', ['sc', 15, '1'], [8, 48, 216]],
['generated control 2', ['tr', 5, '0.5'], 'error: stitch'],
['generated control 3', ['tr', 20, '1.5'], 'error: stitch']],
[['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: last round count', ['hdc', 12, '1.5'], [4, 32, 80]],
['repair check: last round count', ['sc', 10, '1'], [5, 30, 90]],
['generated control 1', ['dc', 30, '2'], [8, 96, 432]],
['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
['generated control 3', ['dc', 15, '0.75'], [10, 120, 660]]]]
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, 66, 330] | [10, 60, 330] | Failed |
| dc mat | [10, 132, 660] | [10, 120, 660] | Failed |
| treble unknown | error: stitch | error: stitch | Passed |
| regression: last round count | [4, 60, 120] | [4, 48, 120] | Failed |
| repair check: last round count | [4, 30, 60] | [4, 24, 60] | Failed |
| generated control 1 | [10, 132, 660] | [10, 120, 660] | Failed |
| generated control 2 | error: stitch | error: stitch | Passed |
| generated control 3 | [12, 156, 936] | [12, 144, 936] | Failed |
SHA-256 / a633e23709ddfcdfbda202db3b3de6b501e422b80c4851f7fa9f4d186e6f6f8c
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: last round count', ['dc', 10, '1.5'], [4, 48, 120]],
['repair check: last round count', ['sc', 10, '1.5'], [4, 24, 60]],
['generated control 1', ['dc', 15, '0.75'], [10, 120, 660]],
['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
['generated control 3', ['dc', 12, '0.5'], [12, 144, 936]]],
[['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
['repair check: last round count', ['hdc', 5, '0.75'], [4, 32, 80]],
['generated control 1', ['tr', 15, '0.75'], 'error: stitch'],
['generated control 2', ['tr', 10, '2'], 'error: stitch'],
['generated control 3', ['tr', 15, '1'], 'error: stitch'],
['generated control 4', ['sc', 5, '0.75'], [4, 24, 60]]],
[['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: last round count', ['dc', 12, '0.75'], [8, 96, 432]],
['repair check: last round count', ['hdc', 20, '0.5'], [20, 160, 1680]],
['generated control 1', ['tr', 10, '0.5'], 'error: stitch'],
['generated control 2', ['tr', 15, '1.5'], 'error: stitch'],
['generated control 3', ['dc', 5, '1.5'], [2, 24, 36]]],
[['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: last round count', ['hdc', 5, '1.5'], [2, 16, 24]],
['repair check: last round count', ['sc', 30, '1.5'], [10, 60, 330]],
['generated control 1', ['sc', 15, '1'], [8, 48, 216]],
['generated control 2', ['tr', 5, '0.5'], 'error: stitch'],
['generated control 3', ['tr', 20, '1.5'], 'error: stitch']],
[['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: last round count', ['hdc', 12, '1.5'], [4, 32, 80]],
['repair check: last round count', ['sc', 10, '1'], [5, 30, 90]],
['generated control 1', ['dc', 30, '2'], [8, 96, 432]],
['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
['generated control 3', ['dc', 15, '0.75'], [10, 120, 660]]]]
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: last round count | [4, 48, 120] | [4, 48, 120] | Passed |
| repair check: last round count | [4, 24, 60] | [4, 24, 60] | Passed |
| generated control 1 | [10, 120, 660] | [10, 120, 660] | Passed |
| generated control 2 | error: stitch | error: stitch | Passed |
| generated control 3 | [12, 144, 936] | [12, 144, 936] | Passed |
SHA-256 / 9f9fba4ec548fc7612aa39c32a7c6f888ceb542a4d444948ac219a234d796e11
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.180168+00:00.
Case digest / 9cd47144ad4e39de7dc521b4088f37b9ef1c5da6293207b4f67d8d60ffffd73a