broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(segs):
    out = []
    cur = None
    starts = {'A': 103, 'B': 104, 'C': 105}
    switch = {'A': 101, 'B': 100, 'C': 99}
    def val(s, ch):
        o = ord(ch)
        if s == 'A':
            if 32 <= o <= 127:
                return o - 32
            if 0 <= o <= 31:
                return o + 64
            return None
        if 32 <= o <= 127:
            return o - 32
        return None
    for seg in segs:
        kind = seg[0]
        if kind == 'FNC1':
            if cur is None:
                return {'error': 'no-start'}
            out.append(102)
            continue
        if kind == 'SHIFT':
            if cur not in ('A', 'B'):
                return {'error': 'bad-shift'}
            other = 'B' if cur == 'A' else 'A'
            v = val(other, seg[1])
            if v is None:
                return {'error': 'unencodable', 'char': seg[1]}
            out += [98, v]
            continue
        s, text = seg
        if cur is None:
            out.append(starts[s])
        elif s != cur:
            out.append(switch[s])
        cur = s
        if s == 'C':
            if len(text) % 2 or not all(c in '0123456789' for c in text):
                return {'error': 'bad-c'}
            out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
        else:
            for ch in text:
                v = val(s, ch)
                if v is None:
                    return {'error': 'unencodable', 'char': ch}
                out.append(v)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['A', 'A`'], ['SHIFT', 'z']], {'error': 'unencodable', 'char': '`'}], [[['B', 'Q'], ['A', 'A`']], {'error': 'unencodable', 'char': '`'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['A', 'A`'], ['B', '{x}']], {'error': 'unencodable', 'char': '`'}]], [[[['A', 'A`'], ['C', '123'], ['A', 'HELLO']], {'error': 'unencodable', 'char': '`'}], [[['A', 'A`'], ['SHIFT', 'B'], ['C', '0099']], {'error': 'unencodable', 'char': '`'}], [[['A', 'A`'], ['B', '{x}'], ['A', 'X\x1d1']], {'error': 'unencodable', 'char': '`'}], [[['C', '1'], ['C', '12']], {'error': 'bad-c'}], [[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['A', 'A`'], ['SHIFT', 'z'], ['SHIFT', 'z'], ['A', 'X\x1d1']], {'error': 'unencodable', 'char': '`'}]], [[[['A', 'A`'], ['C', '12'], ['C', '1']], {'error': 'unencodable', 'char': '`'}], [[['A', 'A`'], ['C', '4711']], {'error': 'unencodable', 'char': '`'}], [[['A', 'A`']], {'error': 'unencodable', 'char': '`'}], [[['FNC1'], ['C', '0099'], ['B', 'Lot 7'], ['C', '4711'], ['C', '12']], {'error': 'no-start'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['B', '{x}'], ['SHIFT', 'a'], ['B', '{x}'], ['SHIFT', 'B']], {'error': 'unencodable', 'char': 'a'}]], [[[['B', '{x}'], ['A', 'X\x1d1'], ['A', 'A`']], {'error': 'unencodable', 'char': '`'}], [[['B', 'z~'], ['B', 'Lot 7'], ['SHIFT', '\t'], ['A', 'A`']], {'error': 'unencodable', 'char': '`'}], [[['B', 'z~'], ['B', '{x}'], ['A', 'A`'], ['SHIFT', 'B']], {'error': 'unencodable', 'char': '`'}], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}], [[['C', '4711'], ['B', 'ab'], ['A', 'X\x1d1']], [105, 47, 11, 100, 65, 66, 101, 56, 93, 17]], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['B', 'ab'], ['FNC1'], ['SHIFT', 'z']], {'error': 'unencodable', 'char': 'z'}]], [[[['A', 'A`'], ['SHIFT', '\x1d'], ['C', ' 1'], ['SHIFT', 'z']], {'error': 'unencodable', 'char': '`'}], [[['A', 'A`'], ['FNC1'], ['B', 'Q']], {'error': 'unencodable', 'char': '`'}], [[['B', 'ab'], ['A', 'A`']], {'error': 'unencodable', 'char': '`'}], [[['B', 'Q']], [104, 49]], [[['A', '\t'], ['C', '0099']], [103, 73, 99, 0, 99]], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['A', '_^'], ['A', 'A`']], {'error': 'unencodable', 'char': '`'}]]]
labels = ["regression: set A printable range", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(segs):
    out = []
    cur = None
    starts = {'A': 103, 'B': 104, 'C': 105}
    switch = {'A': 101, 'B': 100, 'C': 99}
    def val(s, ch):
        o = ord(ch)
        if s == 'A':
            if 32 <= o <= 96:
                return o - 32
            if 0 <= o <= 31:
                return o + 64
            return None
        if 32 <= o <= 127:
            return o - 32
        return None
    for seg in segs:
        kind = seg[0]
        if kind == 'FNC1':
            if cur is None:
                return {'error': 'no-start'}
            out.append(102)
            continue
        if kind == 'SHIFT':
            if cur not in ('A', 'B'):
                return {'error': 'bad-shift'}
            other = 'B' if cur == 'A' else 'A'
            v = val(other, seg[1])
            if v is None:
                return {'error': 'unencodable', 'char': seg[1]}
            out += [98, v]
            continue
        s, text = seg
        if cur is None:
            out.append(starts[s])
        elif s != cur:
            out.append(switch[s])
        cur = s
        if s == 'C':
            if len(text) % 2 or not all(c in '0123456789' for c in text):
                return {'error': 'bad-c'}
            out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
        else:
            for ch in text:
                v = val(s, ch)
                if v is None:
                    return {'error': 'unencodable', 'char': ch}
                out.append(v)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['A', 'A`'], ['SHIFT', 'z']], {'error': 'unencodable', 'char': '`'}], [[['B', 'Q'], ['A', 'A`']], {'error': 'unencodable', 'char': '`'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['A', 'A`'], ['B', '{x}']], {'error': 'unencodable', 'char': '`'}]], [[[['A', 'A`'], ['C', '123'], ['A', 'HELLO']], {'error': 'unencodable', 'char': '`'}], [[['A', 'A`'], ['SHIFT', 'B'], ['C', '0099']], {'error': 'unencodable', 'char': '`'}], [[['A', 'A`'], ['B', '{x}'], ['A', 'X\x1d1']], {'error': 'unencodable', 'char': '`'}], [[['C', '1'], ['C', '12']], {'error': 'bad-c'}], [[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['A', 'A`'], ['SHIFT', 'z'], ['SHIFT', 'z'], ['A', 'X\x1d1']], {'error': 'unencodable', 'char': '`'}]], [[[['A', 'A`'], ['C', '12'], ['C', '1']], {'error': 'unencodable', 'char': '`'}], [[['A', 'A`'], ['C', '4711']], {'error': 'unencodable', 'char': '`'}], [[['A', 'A`']], {'error': 'unencodable', 'char': '`'}], [[['FNC1'], ['C', '0099'], ['B', 'Lot 7'], ['C', '4711'], ['C', '12']], {'error': 'no-start'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['B', '{x}'], ['SHIFT', 'a'], ['B', '{x}'], ['SHIFT', 'B']], {'error': 'unencodable', 'char': 'a'}]], [[[['B', '{x}'], ['A', 'X\x1d1'], ['A', 'A`']], {'error': 'unencodable', 'char': '`'}], [[['B', 'z~'], ['B', 'Lot 7'], ['SHIFT', '\t'], ['A', 'A`']], {'error': 'unencodable', 'char': '`'}], [[['B', 'z~'], ['B', '{x}'], ['A', 'A`'], ['SHIFT', 'B']], {'error': 'unencodable', 'char': '`'}], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}], [[['C', '4711'], ['B', 'ab'], ['A', 'X\x1d1']], [105, 47, 11, 100, 65, 66, 101, 56, 93, 17]], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['B', 'ab'], ['FNC1'], ['SHIFT', 'z']], {'error': 'unencodable', 'char': 'z'}]], [[[['A', 'A`'], ['SHIFT', '\x1d'], ['C', ' 1'], ['SHIFT', 'z']], {'error': 'unencodable', 'char': '`'}], [[['A', 'A`'], ['FNC1'], ['B', 'Q']], {'error': 'unencodable', 'char': '`'}], [[['B', 'ab'], ['A', 'A`']], {'error': 'unencodable', 'char': '`'}], [[['B', 'Q']], [104, 49]], [[['A', '\t'], ['C', '0099']], [103, 73, 99, 0, 99]], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['A', '_^'], ['A', 'A`']], {'error': 'unencodable', 'char': '`'}]]]
labels = ["regression: set A printable range", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

prompt:
Lowercase text planned into set A decodes as control characters.

Turn planned Code 128 segments into symbol values (without the checksum). Segments are [set, text], ["FNC1"] or ["SHIFT", char]. The first set segment emits its start (A 103, B 104, C 105); later set changes emit Code A 101, Code B 100 or Code C 99. Set A encodes 32..95 as ord-32 and 0..31 as ord+64; set B encodes 32..127 as ord-32; set C encodes even-length ASCII digit text as pair values. FNC1 is 102 and needs a prior start; SHIFT (98) is only valid in A or B and encodes one character in the other of A/B. Errors: no-start, bad-shift, bad-c, unencodable.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(segs):
    out = []
    cur = None
    starts = {'A': 103, 'B': 104, 'C': 105}
    switch = {'A': 100, 'B': 101, 'C': 99}
    def val(s, ch):
        o = ord(ch)
        if s == 'A':
            if 32 <= o <= 95:
                return o - 32
            if 0 <= o <= 31:
                return o + 64
            return None
        if 32 <= o <= 127:
            return o - 32
        return None
    for seg in segs:
        kind = seg[0]
        if kind == 'FNC1':
            if cur is None:
                return {'error': 'no-start'}
            out.append(102)
            continue
        if kind == 'SHIFT':
            if cur not in ('A', 'B'):
                return {'error': 'bad-shift'}
            other = 'B' if cur == 'A' else 'A'
            v = val(other, seg[1])
            if v is None:
                return {'error': 'unencodable', 'char': seg[1]}
            out += [98, v]
            continue
        s, text = seg
        if cur is None:
            out.append(starts[s])
        elif s != cur:
            out.append(switch[s])
        cur = s
        if s == 'C':
            if len(text) % 2 or not all(c in '0123456789' for c in text):
                return {'error': 'bad-c'}
            out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
        else:
            for ch in text:
                v = val(s, ch)
                if v is None:
                    return {'error': 'unencodable', 'char': ch}
                out.append(v)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Lot 7'], ['A', '\x00Q'], ['FNC1'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11]], [[['A', 'AB'], ['C', '0099'], ['B', '{x}'], ['B', 'z~']], [103, 33, 34, 99, 0, 99, 100, 91, 88, 93, 90, 94]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['C', '4711'], ['A', 'X\x1d1'], ['B', 'ab']], [105, 47, 11, 101, 56, 93, 17, 100, 65, 66]]], [[[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['B', 'z~'], ['C', '12'], ['FNC1']], [104, 90, 94, 99, 12, 102]], [[['A', 'HELLO'], ['C', '0099'], ['B', 'Lot 7']], [103, 40, 37, 44, 44, 47, 99, 0, 99, 100, 44, 79, 84, 0, 23]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['C', ' 1'], ['C', '0099'], ['FNC1'], ['SHIFT', '\x1d']], {'error': 'bad-c'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]]], [[[['B', 'ab'], ['A', 'HELLO']], [104, 65, 66, 101, 40, 37, 44, 44, 47]], [[['A', '\t'], ['C', '4711'], ['B', 'Q'], ['B', 'ab']], [103, 73, 99, 47, 11, 100, 49, 65, 66]], [[['A', '\x00Q'], ['C', '0099'], ['A', '\x00Q']], [103, 64, 49, 99, 0, 99, 101, 64, 49]], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['C', '0099'], ['B', 'Q']], [105, 0, 99, 100, 49]]], [[[['C', '12'], ['B', 'Q']], [105, 12, 100, 49]], [[['B', 'ab'], ['B', 'Q'], ['C', '4711'], ['FNC1']], [104, 65, 66, 49, 99, 47, 11, 102]], [[['B', 'Lot 7'], ['A', '_^'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 63, 62, 99, 47, 11]], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['B', 'z~'], ['A', 'X\x1d1'], ['B', '{x}'], ['C', '0099']], [104, 90, 94, 101, 56, 93, 17, 100, 91, 88, 93, 99, 0, 99]]], [[[['C', '12'], ['A', '\t'], ['FNC1'], ['FNC1']], [105, 12, 101, 73, 102, 102]], [[['B', '{x}'], ['SHIFT', 'B'], ['C', '12'], ['A', 'AB']], [104, 91, 88, 93, 98, 34, 99, 12, 101, 33, 34]], [[['B', '{x}'], ['C', '12'], ['A', '\x00Q']], [104, 91, 88, 93, 99, 12, 101, 64, 49]], [[['B', 'Q']], [104, 49]], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['B', '{x}'], ['B', 'Q']], [104, 91, 88, 93, 49]], [[['A', 'AB']], [103, 33, 34]], [[['B', 'Q'], ['B', 'z~'], ['A', 'HELLO'], ['SHIFT', 'B']], [104, 49, 90, 94, 101, 40, 37, 44, 44, 47, 98, 34]]]]
labels = ["regression: code set switch values", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(segs):
    out = []
    cur = None
    starts = {'A': 103, 'B': 104, 'C': 105}
    switch = {'A': 101, 'B': 100, 'C': 98}
    def val(s, ch):
        o = ord(ch)
        if s == 'A':
            if 32 <= o <= 95:
                return o - 32
            if 0 <= o <= 31:
                return o + 64
            return None
        if 32 <= o <= 127:
            return o - 32
        return None
    for seg in segs:
        kind = seg[0]
        if kind == 'FNC1':
            if cur is None:
                return {'error': 'no-start'}
            out.append(102)
            continue
        if kind == 'SHIFT':
            if cur not in ('A', 'B'):
                return {'error': 'bad-shift'}
            other = 'B' if cur == 'A' else 'A'
            v = val(other, seg[1])
            if v is None:
                return {'error': 'unencodable', 'char': seg[1]}
            out += [98, v]
            continue
        s, text = seg
        if cur is None:
            out.append(starts[s])
        elif s != cur:
            out.append(switch[s])
        cur = s
        if s == 'C':
            if len(text) % 2 or not all(c in '0123456789' for c in text):
                return {'error': 'bad-c'}
            out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
        else:
            for ch in text:
                v = val(s, ch)
                if v is None:
                    return {'error': 'unencodable', 'char': ch}
                out.append(v)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Lot 7'], ['A', '\x00Q'], ['FNC1'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11]], [[['A', 'AB'], ['C', '0099'], ['B', '{x}'], ['B', 'z~']], [103, 33, 34, 99, 0, 99, 100, 91, 88, 93, 90, 94]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['C', '4711'], ['A', 'X\x1d1'], ['B', 'ab']], [105, 47, 11, 101, 56, 93, 17, 100, 65, 66]]], [[[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['B', 'z~'], ['C', '12'], ['FNC1']], [104, 90, 94, 99, 12, 102]], [[['A', 'HELLO'], ['C', '0099'], ['B', 'Lot 7']], [103, 40, 37, 44, 44, 47, 99, 0, 99, 100, 44, 79, 84, 0, 23]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['C', ' 1'], ['C', '0099'], ['FNC1'], ['SHIFT', '\x1d']], {'error': 'bad-c'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]]], [[[['B', 'ab'], ['A', 'HELLO']], [104, 65, 66, 101, 40, 37, 44, 44, 47]], [[['A', '\t'], ['C', '4711'], ['B', 'Q'], ['B', 'ab']], [103, 73, 99, 47, 11, 100, 49, 65, 66]], [[['A', '\x00Q'], ['C', '0099'], ['A', '\x00Q']], [103, 64, 49, 99, 0, 99, 101, 64, 49]], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['C', '0099'], ['B', 'Q']], [105, 0, 99, 100, 49]]], [[[['C', '12'], ['B', 'Q']], [105, 12, 100, 49]], [[['B', 'ab'], ['B', 'Q'], ['C', '4711'], ['FNC1']], [104, 65, 66, 49, 99, 47, 11, 102]], [[['B', 'Lot 7'], ['A', '_^'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 63, 62, 99, 47, 11]], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['B', 'z~'], ['A', 'X\x1d1'], ['B', '{x}'], ['C', '0099']], [104, 90, 94, 101, 56, 93, 17, 100, 91, 88, 93, 99, 0, 99]]], [[[['C', '12'], ['A', '\t'], ['FNC1'], ['FNC1']], [105, 12, 101, 73, 102, 102]], [[['B', '{x}'], ['SHIFT', 'B'], ['C', '12'], ['A', 'AB']], [104, 91, 88, 93, 98, 34, 99, 12, 101, 33, 34]], [[['B', '{x}'], ['C', '12'], ['A', '\x00Q']], [104, 91, 88, 93, 99, 12, 101, 64, 49]], [[['B', 'Q']], [104, 49]], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['B', '{x}'], ['B', 'Q']], [104, 91, 88, 93, 49]], [[['A', 'AB']], [103, 33, 34]], [[['B', 'Q'], ['B', 'z~'], ['A', 'HELLO'], ['SHIFT', 'B']], [104, 49, 90, 94, 101, 40, 37, 44, 44, 47, 98, 34]]]]
labels = ["regression: code set switch values", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

prompt:
Switching from C to B decodes as a switch to A, so lowercase letters decode as control codes.

Turn planned Code 128 segments into symbol values (without the checksum). Segments are [set, text], ["FNC1"] or ["SHIFT", char]. The first set segment emits its start (A 103, B 104, C 105); later set changes emit Code A 101, Code B 100 or Code C 99. Set A encodes 32..95 as ord-32 and 0..31 as ord+64; set B encodes 32..127 as ord-32; set C encodes even-length ASCII digit text as pair values. FNC1 is 102 and needs a prior start; SHIFT (98) is only valid in A or B and encodes one character in the other of A/B. Errors: no-start, bad-shift, bad-c, unencodable.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(segs):
    out = []
    cur = None
    starts = {'A': 103, 'B': 104, 'C': 105}
    switch = {'A': 101, 'B': 100, 'C': 99}
    def val(s, ch):
        o = ord(ch)
        if s == 'A':
            if 32 <= o <= 95:
                return o - 32
            if 0 <= o <= 31:
                return o + 64
            return None
        if 32 <= o <= 127:
            return o - 32
        return None
    for seg in segs:
        kind = seg[0]
        if kind == 'FNC1':
            if cur is None:
                return {'error': 'no-start'}
            out.append(102)
            continue
        if kind == 'SHIFT':
            if cur not in ('A', 'B'):
                return {'error': 'bad-shift'}
            other = cur
            v = val(other, seg[1])
            if v is None:
                return {'error': 'unencodable', 'char': seg[1]}
            out += [98, v]
            continue
        s, text = seg
        if cur is None:
            out.append(starts[s])
        elif s != cur:
            out.append(switch[s])
        cur = s
        if s == 'C':
            if len(text) % 2 or not all(c in '0123456789' for c in text):
                return {'error': 'bad-c'}
            out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
        else:
            for ch in text:
                v = val(s, ch)
                if v is None:
                    return {'error': 'unencodable', 'char': ch}
                out.append(v)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['A', '\t'], ['A', '\t'], ['SHIFT', 'a']], [103, 73, 73, 98, 65]], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['B', 'Lot 7'], ['A', '\x00Q'], ['FNC1'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11]], [[['A', '\x00Q'], ['SHIFT', 'a'], ['SHIFT', '\t']], {'error': 'unencodable', 'char': '\t'}]], [[[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['A', 'X\x1d1'], ['SHIFT', '\t'], ['A', 'A`'], ['SHIFT', '\t']], {'error': 'unencodable', 'char': '\t'}], [[['C', '12'], ['A', 'HELLO'], ['SHIFT', '\x1d']], {'error': 'unencodable', 'char': '\x1d'}], [[['C', '1'], ['C', '12']], {'error': 'bad-c'}], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['C', ' 1'], ['C', '0099'], ['FNC1'], ['SHIFT', '\x1d']], {'error': 'bad-c'}], [[['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 56, 93, 17, 98, 90]]], [[[['B', '{x}'], ['SHIFT', '\x1d']], [104, 91, 88, 93, 98, 93]], [[['A', 'HELLO'], ['SHIFT', '\t'], ['SHIFT', 'a'], ['A', 'A`']], {'error': 'unencodable', 'char': '\t'}], [[['A', '_^'], ['SHIFT', '\t']], {'error': 'unencodable', 'char': '\t'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['B', 'Q'], ['SHIFT', 'z']], {'error': 'unencodable', 'char': 'z'}]], [[[['B', 'ab'], ['FNC1'], ['SHIFT', 'z']], {'error': 'unencodable', 'char': 'z'}], [[['B', 'Q'], ['A', 'AB'], ['SHIFT', '\x1d'], ['A', 'AB']], {'error': 'unencodable', 'char': '\x1d'}], [[['A', 'AB'], ['A', '_^'], ['SHIFT', 'z'], ['FNC1']], [103, 33, 34, 63, 62, 98, 90, 102]], [[['C', '4711'], ['B', 'ab'], ['A', 'X\x1d1']], [105, 47, 11, 100, 65, 66, 101, 56, 93, 17]], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', 'z'], ['SHIFT', '\x1d'], ['A', '\x00Q']], {'error': 'unencodable', 'char': 'z'}]], [[[['A', '\x00Q'], ['SHIFT', 'a']], [103, 64, 49, 98, 65]], [[['C', '12'], ['A', 'AB'], ['A', 'AB'], ['SHIFT', '\x1d']], {'error': 'unencodable', 'char': '\x1d'}], [[['A', 'HELLO'], ['FNC1'], ['SHIFT', 'a']], [103, 40, 37, 44, 44, 47, 102, 98, 65]], [[['B', 'Q']], [104, 49]], [[['A', '\t'], ['C', '0099']], [103, 73, 99, 0, 99]], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['B', 'z~'], ['SHIFT', 'a']], {'error': 'unencodable', 'char': 'a'}]]]
labels = ["regression: shift target set", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(segs):
    out = []
    cur = None
    starts = {'A': 103, 'B': 104, 'C': 105}
    switch = {'A': 101, 'B': 100, 'C': 99}
    def val(s, ch):
        o = ord(ch)
        if s == 'A':
            if 32 <= o <= 95:
                return o - 32
            if 0 <= o <= 31:
                return o + 64
            return None
        if 32 <= o <= 127:
            return o - 32
        return None
    for seg in segs:
        kind = seg[0]
        if kind == 'FNC1':
            if cur is None:
                return {'error': 'no-start'}
            out.append(102)
            continue
        if kind == 'SHIFT':
            if cur not in ('A', 'B'):
                return {'error': 'bad-shift'}
            other = 'A'
            v = val(other, seg[1])
            if v is None:
                return {'error': 'unencodable', 'char': seg[1]}
            out += [98, v]
            continue
        s, text = seg
        if cur is None:
            out.append(starts[s])
        elif s != cur:
            out.append(switch[s])
        cur = s
        if s == 'C':
            if len(text) % 2 or not all(c in '0123456789' for c in text):
                return {'error': 'bad-c'}
            out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
        else:
            for ch in text:
                v = val(s, ch)
                if v is None:
                    return {'error': 'unencodable', 'char': ch}
                out.append(v)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['A', '\t'], ['A', '\t'], ['SHIFT', 'a']], [103, 73, 73, 98, 65]], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['B', 'Lot 7'], ['A', '\x00Q'], ['FNC1'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11]], [[['A', '\x00Q'], ['SHIFT', 'a'], ['SHIFT', '\t']], {'error': 'unencodable', 'char': '\t'}]], [[[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['A', 'X\x1d1'], ['SHIFT', '\t'], ['A', 'A`'], ['SHIFT', '\t']], {'error': 'unencodable', 'char': '\t'}], [[['C', '12'], ['A', 'HELLO'], ['SHIFT', '\x1d']], {'error': 'unencodable', 'char': '\x1d'}], [[['C', '1'], ['C', '12']], {'error': 'bad-c'}], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['C', ' 1'], ['C', '0099'], ['FNC1'], ['SHIFT', '\x1d']], {'error': 'bad-c'}], [[['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 56, 93, 17, 98, 90]]], [[[['B', '{x}'], ['SHIFT', '\x1d']], [104, 91, 88, 93, 98, 93]], [[['A', 'HELLO'], ['SHIFT', '\t'], ['SHIFT', 'a'], ['A', 'A`']], {'error': 'unencodable', 'char': '\t'}], [[['A', '_^'], ['SHIFT', '\t']], {'error': 'unencodable', 'char': '\t'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['B', 'Q'], ['SHIFT', 'z']], {'error': 'unencodable', 'char': 'z'}]], [[[['B', 'ab'], ['FNC1'], ['SHIFT', 'z']], {'error': 'unencodable', 'char': 'z'}], [[['B', 'Q'], ['A', 'AB'], ['SHIFT', '\x1d'], ['A', 'AB']], {'error': 'unencodable', 'char': '\x1d'}], [[['A', 'AB'], ['A', '_^'], ['SHIFT', 'z'], ['FNC1']], [103, 33, 34, 63, 62, 98, 90, 102]], [[['C', '4711'], ['B', 'ab'], ['A', 'X\x1d1']], [105, 47, 11, 100, 65, 66, 101, 56, 93, 17]], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', 'z'], ['SHIFT', '\x1d'], ['A', '\x00Q']], {'error': 'unencodable', 'char': 'z'}]], [[[['A', '\x00Q'], ['SHIFT', 'a']], [103, 64, 49, 98, 65]], [[['C', '12'], ['A', 'AB'], ['A', 'AB'], ['SHIFT', '\x1d']], {'error': 'unencodable', 'char': '\x1d'}], [[['A', 'HELLO'], ['FNC1'], ['SHIFT', 'a']], [103, 40, 37, 44, 44, 47, 102, 98, 65]], [[['B', 'Q']], [104, 49]], [[['A', '\t'], ['C', '0099']], [103, 73, 99, 0, 99]], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['B', 'z~'], ['SHIFT', 'a']], {'error': 'unencodable', 'char': 'a'}]]]
labels = ["regression: shift target set", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

prompt:
A lowercase letter shifted inside set A comes out as a control code.

Turn planned Code 128 segments into symbol values (without the checksum). Segments are [set, text], ["FNC1"] or ["SHIFT", char]. The first set segment emits its start (A 103, B 104, C 105); later set changes emit Code A 101, Code B 100 or Code C 99. Set A encodes 32..95 as ord-32 and 0..31 as ord+64; set B encodes 32..127 as ord-32; set C encodes even-length ASCII digit text as pair values. FNC1 is 102 and needs a prior start; SHIFT (98) is only valid in A or B and encodes one character in the other of A/B. Errors: no-start, bad-shift, bad-c, unencodable.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(segs):
    out = []
    cur = None
    starts = {'A': 103, 'B': 104, 'C': 105}
    switch = {'A': 101, 'B': 100, 'C': 99}
    def val(s, ch):
        o = ord(ch)
        if s == 'A':
            if 32 <= o <= 95:
                return o - 32
            if 0 <= o <= 31:
                return o + 64
            return None
        if 32 <= o <= 127:
            return o - 32
        return None
    for seg in segs:
        kind = seg[0]
        if kind == 'FNC1':
            if cur is None:
                return {'error': 'no-start'}
            out.append(102)
            continue
        if kind == 'SHIFT':
            if cur not in ('A', 'B'):
                return {'error': 'bad-shift'}
            other = 'B' if cur == 'A' else 'A'
            v = val(other, seg[1])
            if v is None:
                return {'error': 'unencodable', 'char': seg[1]}
            out += [98, v]
            continue
        s, text = seg
        if cur is None:
            out.append(starts[s])
        elif s != cur:
            out.append(switch[s])
        cur = s
        if s == 'C':
            if len(text) % 2:
                return {'error': 'bad-c'}
            out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
        else:
            for ch in text:
                v = val(s, ch)
                if v is None:
                    return {'error': 'unencodable', 'char': ch}
                out.append(v)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['B', 'Lot 7'], ['C', '12'], ['C', ' 1']], {'error': 'bad-c'}], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['B', 'Lot 7'], ['A', '\x00Q'], ['FNC1'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['A', 'HELLO'], ['A', 'AB'], ['A', 'X\x1d1']], [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17]], [[['B', '{x}'], ['A', 'X\x1d1'], ['C', ' 1'], ['SHIFT', '\x1d']], {'error': 'bad-c'}]], [[[['C', ' 1'], ['FNC1']], {'error': 'bad-c'}], [[['A', '\t'], ['C', '0099'], ['A', 'HELLO'], ['C', '123']], {'error': 'bad-c'}], [[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['B', '{x}'], ['A', '_^']], [104, 91, 88, 93, 101, 63, 62]], [[['C', ' 1'], ['A', '\x00Q'], ['FNC1'], ['B', '{x}']], {'error': 'bad-c'}]], [[[['C', ' 1']], {'error': 'bad-c'}], [[['C', '123'], ['A', 'AB'], ['A', '\t'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['FNC1'], ['C', '0099'], ['B', 'Lot 7'], ['C', '4711'], ['C', '12']], {'error': 'no-start'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['B', '{x}'], ['C', ' 1']], {'error': 'bad-c'}]], [[[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['B', '{x}'], ['C', '123'], ['C', '0099']], {'error': 'bad-c'}], [[['B', 'z~']], [104, 90, 94]], [[['C', '4711']], [105, 47, 11]], [[['A', 'HELLO'], ['A', '_^'], ['A', '_^']], [103, 40, 37, 44, 44, 47, 63, 62, 63, 62]], [[['A', '\t']], [103, 73]], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}]], [[[['B', 'ab'], ['C', ' 1']], {'error': 'bad-c'}], [[['C', '0099'], ['C', '123']], {'error': 'bad-c'}], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['B', '{x}'], ['B', 'Q']], [104, 91, 88, 93, 49]], [[['A', 'AB']], [103, 33, 34]], [[['FNC1'], ['A', 'X\x1d1']], {'error': 'no-start'}], [[['C', ' 1'], ['A', '_^'], ['SHIFT', '\x1d']], {'error': 'bad-c'}]]]
labels = ["regression: set C text validation", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(segs):
    out = []
    cur = None
    starts = {'A': 103, 'B': 104, 'C': 105}
    switch = {'A': 101, 'B': 100, 'C': 99}
    def val(s, ch):
        o = ord(ch)
        if s == 'A':
            if 32 <= o <= 95:
                return o - 32
            if 0 <= o <= 31:
                return o + 64
            return None
        if 32 <= o <= 127:
            return o - 32
        return None
    for seg in segs:
        kind = seg[0]
        if kind == 'FNC1':
            if cur is None:
                return {'error': 'no-start'}
            out.append(102)
            continue
        if kind == 'SHIFT':
            if cur not in ('A', 'B'):
                return {'error': 'bad-shift'}
            other = 'B' if cur == 'A' else 'A'
            v = val(other, seg[1])
            if v is None:
                return {'error': 'unencodable', 'char': seg[1]}
            out += [98, v]
            continue
        s, text = seg
        if cur is None:
            out.append(starts[s])
        elif s != cur:
            out.append(switch[s])
        cur = s
        if s == 'C':
            if not text.isdigit():
                return {'error': 'bad-c'}
            out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
        else:
            for ch in text:
                v = val(s, ch)
                if v is None:
                    return {'error': 'unencodable', 'char': ch}
                out.append(v)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['B', 'Lot 7'], ['C', '12'], ['C', ' 1']], {'error': 'bad-c'}], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['B', 'Lot 7'], ['A', '\x00Q'], ['FNC1'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['A', 'HELLO'], ['A', 'AB'], ['A', 'X\x1d1']], [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17]], [[['B', '{x}'], ['A', 'X\x1d1'], ['C', ' 1'], ['SHIFT', '\x1d']], {'error': 'bad-c'}]], [[[['C', ' 1'], ['FNC1']], {'error': 'bad-c'}], [[['A', '\t'], ['C', '0099'], ['A', 'HELLO'], ['C', '123']], {'error': 'bad-c'}], [[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['B', '{x}'], ['A', '_^']], [104, 91, 88, 93, 101, 63, 62]], [[['C', ' 1'], ['A', '\x00Q'], ['FNC1'], ['B', '{x}']], {'error': 'bad-c'}]], [[[['C', ' 1']], {'error': 'bad-c'}], [[['C', '123'], ['A', 'AB'], ['A', '\t'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['FNC1'], ['C', '0099'], ['B', 'Lot 7'], ['C', '4711'], ['C', '12']], {'error': 'no-start'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['B', '{x}'], ['C', ' 1']], {'error': 'bad-c'}]], [[[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['B', '{x}'], ['C', '123'], ['C', '0099']], {'error': 'bad-c'}], [[['B', 'z~']], [104, 90, 94]], [[['C', '4711']], [105, 47, 11]], [[['A', 'HELLO'], ['A', '_^'], ['A', '_^']], [103, 40, 37, 44, 44, 47, 63, 62, 63, 62]], [[['A', '\t']], [103, 73]], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}]], [[[['B', 'ab'], ['C', ' 1']], {'error': 'bad-c'}], [[['C', '0099'], ['C', '123']], {'error': 'bad-c'}], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['B', '{x}'], ['B', 'Q']], [104, 91, 88, 93, 49]], [[['A', 'AB']], [103, 33, 34]], [[['FNC1'], ['A', 'X\x1d1']], {'error': 'no-start'}], [[['C', ' 1'], ['A', '_^'], ['SHIFT', '\x1d']], {'error': 'bad-c'}]]]
labels = ["regression: set C text validation", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

prompt:
A space-padded quantity is encoded as a digit pair value because int() ignores whitespace.

Turn planned Code 128 segments into symbol values (without the checksum). Segments are [set, text], ["FNC1"] or ["SHIFT", char]. The first set segment emits its start (A 103, B 104, C 105); later set changes emit Code A 101, Code B 100 or Code C 99. Set A encodes 32..95 as ord-32 and 0..31 as ord+64; set B encodes 32..127 as ord-32; set C encodes even-length ASCII digit text as pair values. FNC1 is 102 and needs a prior start; SHIFT (98) is only valid in A or B and encodes one character in the other of A/B. Errors: no-start, bad-shift, bad-c, unencodable.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(segs):
    out = []
    cur = None
    starts = {'A': 103, 'B': 104, 'C': 105}
    switch = {'A': 101, 'B': 100, 'C': 99}
    def val(s, ch):
        o = ord(ch)
        if s == 'A':
            if 32 <= o <= 95:
                return o - 32
            if 0 <= o <= 31:
                return o + 64
            return None
        if 32 <= o <= 127:
            return o - 32
        return None
    for seg in segs:
        kind = seg[0]
        if kind == 'FNC1':
            if cur is None:
                cur = 'B'
            out.append(102)
            continue
        if kind == 'SHIFT':
            if cur not in ('A', 'B'):
                return {'error': 'bad-shift'}
            other = 'B' if cur == 'A' else 'A'
            v = val(other, seg[1])
            if v is None:
                return {'error': 'unencodable', 'char': seg[1]}
            out += [98, v]
            continue
        s, text = seg
        if cur is None:
            out.append(starts[s])
        elif s != cur:
            out.append(switch[s])
        cur = s
        if s == 'C':
            if len(text) % 2 or not all(c in '0123456789' for c in text):
                return {'error': 'bad-c'}
            out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
        else:
            for ch in text:
                v = val(s, ch)
                if v is None:
                    return {'error': 'unencodable', 'char': ch}
                out.append(v)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['FNC1'], ['B', 'Lot 7'], ['A', '\x00Q']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'z'], ['C', '123']], {'error': 'no-start'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['FNC1'], ['A', '\t']], {'error': 'no-start'}]], [[[['FNC1'], ['B', 'z~'], ['B', 'Q'], ['FNC1'], ['A', '\x00Q']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'a']], {'error': 'no-start'}], [[['C', '1'], ['C', '12']], {'error': 'bad-c'}], [[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['FNC1'], ['B', 'Lot 7']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', 'a'], ['C', '1'], ['FNC1']], {'error': 'no-start'}], [[['FNC1'], ['B', 'z~']], {'error': 'no-start'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['C', '12']], [105, 12]], [[['FNC1'], ['FNC1'], ['A', 'HELLO'], ['C', '4711']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', 'z'], ['FNC1']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'B']], {'error': 'no-start'}], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}], [[['C', '4711'], ['B', 'ab'], ['A', 'X\x1d1']], [105, 47, 11, 100, 65, 66, 101, 56, 93, 17]], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['FNC1'], ['A', '\t'], ['A', 'A`']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', '\x1d'], ['B', 'z~'], ['A', 'AB']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', '\x1d']], {'error': 'no-start'}], [[['B', 'Q']], [104, 49]], [[['A', '\t'], ['C', '0099']], [103, 73, 99, 0, 99]], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['B', '{x}'], ['B', 'Q']], [104, 91, 88, 93, 49]], [[['A', 'AB']], [103, 33, 34]], [[['FNC1'], ['A', 'X\x1d1']], {'error': 'no-start'}]]]
labels = ["regression: FNC1 before a start character", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(segs):
    out = []
    cur = None
    starts = {'A': 103, 'B': 104, 'C': 105}
    switch = {'A': 101, 'B': 100, 'C': 99}
    def val(s, ch):
        o = ord(ch)
        if s == 'A':
            if 32 <= o <= 95:
                return o - 32
            if 0 <= o <= 31:
                return o + 64
            return None
        if 32 <= o <= 127:
            return o - 32
        return None
    for seg in segs:
        kind = seg[0]
        if kind == 'FNC1':
            if cur is None:
                out.append(105)
            out.append(102)
            continue
        if kind == 'SHIFT':
            if cur not in ('A', 'B'):
                return {'error': 'bad-shift'}
            other = 'B' if cur == 'A' else 'A'
            v = val(other, seg[1])
            if v is None:
                return {'error': 'unencodable', 'char': seg[1]}
            out += [98, v]
            continue
        s, text = seg
        if cur is None:
            out.append(starts[s])
        elif s != cur:
            out.append(switch[s])
        cur = s
        if s == 'C':
            if len(text) % 2 or not all(c in '0123456789' for c in text):
                return {'error': 'bad-c'}
            out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
        else:
            for ch in text:
                v = val(s, ch)
                if v is None:
                    return {'error': 'unencodable', 'char': ch}
                out.append(v)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['FNC1'], ['B', 'Lot 7'], ['A', '\x00Q']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'z'], ['C', '123']], {'error': 'no-start'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['FNC1'], ['A', '\t']], {'error': 'no-start'}]], [[[['FNC1'], ['B', 'z~'], ['B', 'Q'], ['FNC1'], ['A', '\x00Q']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'a']], {'error': 'no-start'}], [[['C', '1'], ['C', '12']], {'error': 'bad-c'}], [[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['FNC1'], ['B', 'Lot 7']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', 'a'], ['C', '1'], ['FNC1']], {'error': 'no-start'}], [[['FNC1'], ['B', 'z~']], {'error': 'no-start'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['C', '12']], [105, 12]], [[['FNC1'], ['FNC1'], ['A', 'HELLO'], ['C', '4711']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', 'z'], ['FNC1']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'B']], {'error': 'no-start'}], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}], [[['C', '4711'], ['B', 'ab'], ['A', 'X\x1d1']], [105, 47, 11, 100, 65, 66, 101, 56, 93, 17]], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['FNC1'], ['A', '\t'], ['A', 'A`']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', '\x1d'], ['B', 'z~'], ['A', 'AB']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', '\x1d']], {'error': 'no-start'}], [[['B', 'Q']], [104, 49]], [[['A', '\t'], ['C', '0099']], [103, 73, 99, 0, 99]], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['B', '{x}'], ['B', 'Q']], [104, 91, 88, 93, 49]], [[['A', 'AB']], [103, 33, 34]], [[['FNC1'], ['A', 'X\x1d1']], {'error': 'no-start'}]]]
labels = ["regression: FNC1 before a start character", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

prompt:
GS1 symbols begin with value 102 and no start code, so scanners reject them.

Turn planned Code 128 segments into symbol values (without the checksum). Segments are [set, text], ["FNC1"] or ["SHIFT", char]. The first set segment emits its start (A 103, B 104, C 105); later set changes emit Code A 101, Code B 100 or Code C 99. Set A encodes 32..95 as ord-32 and 0..31 as ord+64; set B encodes 32..127 as ord-32; set C encodes even-length ASCII digit text as pair values. FNC1 is 102 and needs a prior start; SHIFT (98) is only valid in A or B and encodes one character in the other of A/B. Errors: no-start, bad-shift, bad-c, unencodable.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, mode, ratio):
    std = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%'
    if ratio not in (2, 3):
        return {'error': 'ratio'}
    if mode == 'standard':
        for ch in text:
            if ch not in std:
                return {'error': 'char', 'char': ch}
        enc = text
    else:
        punct = {'$': '/D', '%': '/E', '+': '/K', '/': '/O', '!': '/A', '"': '/B', '#': '/C', '&': '/F', "'": '/G',
                 '(': '/H', ')': '/I', '*': '/J', ',': '/L', ':': '/Z', ';': '%F', '<': '%G', '=': '%H', '>': '%I',
                 '?': '%J', '@': '%V', '[': '%K', '\\': '%L', ']': '%M', '^': '%N', '_': '%O', '`': '%W',
                 '{': '%P', '|': '%Q', '}': '%R', '~': '%S'}
        enc = ''
        for ch in text:
            o = ord(ch)
            if o > 127:
                return {'error': 'char', 'char': ch}
            if ch in punct:
                enc += punct[ch]
            elif 'a' <= ch <= 'z':
                enc += '+' + ch.upper()
            elif 1 <= o <= 26:
                enc += '$' + chr(o + 64)
            elif o == 0:
                enc += '%U'
            elif 27 <= o <= 31:
                enc += '%' + chr(o - 27 + 65)
            elif o == 127:
                enc += '%T'
            else:
                enc += ch
    count = len(enc) + 2
    return {'data': '*' + enc + '*', 'modules': count * (6 + 3 * ratio) + count}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('PN/7PN/7$5', 'full', 3), {'data': '*PN/O7PN/O7/D5*', 'modules': 239}], [('', 'standard', 3), {'data': '**', 'modules': 31}], [('café', 'standard', 4), {'error': 'ratio'}], [('ABPN/7PN/7', 'full', 1), {'error': 'ratio'}], [('a+ba+b', 'full', 4), {'error': 'ratio'}], [('Z-9a+blot', 'standard', 2), {'error': 'char', 'char': 'a'}], [('café\t', 'full', 4), {'error': 'ratio'}], [('\x1b', 'full', 2), {'data': '*%A*', 'modules': 51}]], [[('\x1blotlot', 'full', 2), {'data': '*%A+L+O+T+L+O+T*', 'modules': 207}], [('\t\x7fq', 'full', 2), {'data': '*$I%T+Q*', 'modules': 103}], [('', 'standard', 1), {'error': 'ratio'}], [('PN/7\x1blot', 'full', 4), {'error': 'ratio'}], [('\x00caféq', 'full', 4), {'error': 'ratio'}], [('q$5café', 'standard', 4), {'error': 'ratio'}], [('', 'full', 4), {'error': 'ratio'}], [('#1', 'full', 2), {'data': '*/C1*', 'modules': 64}]], [[('$5 \x00', 'full', 2), {'data': '*/D5 %U*', 'modules': 103}], [('', 'full', 2), {'data': '**', 'modules': 25}], [('#1café', 'standard', 4), {'error': 'ratio'}], [(' ', 'full', 1), {'error': 'ratio'}], [('*\x1bcafé', 'full', 2), {'error': 'char', 'char': 'é'}], [('', 'full', 4), {'error': 'ratio'}], [('\x7f#1', 'standard', 4), {'error': 'ratio'}], [('ABPN/7Z-9', 'full', 2), {'data': '*ABPN/O7Z-9*', 'modules': 155}]], [[('AB12', 'standard', 2), {'data': '*AB12*', 'modules': 77}], [('', 'full', 2), {'data': '**', 'modules': 25}], [('#1café', 'full', 2), {'error': 'char', 'char': 'é'}], [(' ABPN/7', 'full', 1), {'error': 'ratio'}], [('qAB', 'standard', 3), {'error': 'char', 'char': 'q'}], [('Z-950%', 'full', 1), {'error': 'ratio'}], [('', 'full', 4), {'error': 'ratio'}], [('*', 'full', 2), {'data': '*/J*', 'modules': 51}]], [[('$5lot', 'full', 3), {'data': '*/D5+L+O+T*', 'modules': 175}], [('a+ba+b', 'full', 3), {'data': '*+A/K+B+A/K+B*', 'modules': 223}], [('AB\x1b', 'standard', 1), {'error': 'ratio'}], [('Z-9$512', 'standard', 4), {'error': 'ratio'}], [('xq', 'standard', 1), {'error': 'ratio'}], [('\x7f$5', 'full', 1), {'error': 'ratio'}], [('\x7f#1', 'full', 4), {'error': 'ratio'}], [('  \t', 'full', 2), {'data': '*  $I*', 'modules': 77}]]]
labels = ["regression: intercharacter gap count", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, mode, ratio):
    std = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%'
    if ratio not in (2, 3):
        return {'error': 'ratio'}
    if mode == 'standard':
        for ch in text:
            if ch not in std:
                return {'error': 'char', 'char': ch}
        enc = text
    else:
        punct = {'$': '/D', '%': '/E', '+': '/K', '/': '/O', '!': '/A', '"': '/B', '#': '/C', '&': '/F', "'": '/G',
                 '(': '/H', ')': '/I', '*': '/J', ',': '/L', ':': '/Z', ';': '%F', '<': '%G', '=': '%H', '>': '%I',
                 '?': '%J', '@': '%V', '[': '%K', '\\': '%L', ']': '%M', '^': '%N', '_': '%O', '`': '%W',
                 '{': '%P', '|': '%Q', '}': '%R', '~': '%S'}
        enc = ''
        for ch in text:
            o = ord(ch)
            if o > 127:
                return {'error': 'char', 'char': ch}
            if ch in punct:
                enc += punct[ch]
            elif 'a' <= ch <= 'z':
                enc += '+' + ch.upper()
            elif 1 <= o <= 26:
                enc += '$' + chr(o + 64)
            elif o == 0:
                enc += '%U'
            elif 27 <= o <= 31:
                enc += '%' + chr(o - 27 + 65)
            elif o == 127:
                enc += '%T'
            else:
                enc += ch
    count = len(enc) + 2
    return {'data': '*' + enc + '*', 'modules': count * (6 + 3 * ratio) + (count - 2)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('PN/7PN/7$5', 'full', 3), {'data': '*PN/O7PN/O7/D5*', 'modules': 239}], [('', 'standard', 3), {'data': '**', 'modules': 31}], [('café', 'standard', 4), {'error': 'ratio'}], [('ABPN/7PN/7', 'full', 1), {'error': 'ratio'}], [('a+ba+b', 'full', 4), {'error': 'ratio'}], [('Z-9a+blot', 'standard', 2), {'error': 'char', 'char': 'a'}], [('café\t', 'full', 4), {'error': 'ratio'}], [('\x1b', 'full', 2), {'data': '*%A*', 'modules': 51}]], [[('\x1blotlot', 'full', 2), {'data': '*%A+L+O+T+L+O+T*', 'modules': 207}], [('\t\x7fq', 'full', 2), {'data': '*$I%T+Q*', 'modules': 103}], [('', 'standard', 1), {'error': 'ratio'}], [('PN/7\x1blot', 'full', 4), {'error': 'ratio'}], [('\x00caféq', 'full', 4), {'error': 'ratio'}], [('q$5café', 'standard', 4), {'error': 'ratio'}], [('', 'full', 4), {'error': 'ratio'}], [('#1', 'full', 2), {'data': '*/C1*', 'modules': 64}]], [[('$5 \x00', 'full', 2), {'data': '*/D5 %U*', 'modules': 103}], [('', 'full', 2), {'data': '**', 'modules': 25}], [('#1café', 'standard', 4), {'error': 'ratio'}], [(' ', 'full', 1), {'error': 'ratio'}], [('*\x1bcafé', 'full', 2), {'error': 'char', 'char': 'é'}], [('', 'full', 4), {'error': 'ratio'}], [('\x7f#1', 'standard', 4), {'error': 'ratio'}], [('ABPN/7Z-9', 'full', 2), {'data': '*ABPN/O7Z-9*', 'modules': 155}]], [[('AB12', 'standard', 2), {'data': '*AB12*', 'modules': 77}], [('', 'full', 2), {'data': '**', 'modules': 25}], [('#1café', 'full', 2), {'error': 'char', 'char': 'é'}], [(' ABPN/7', 'full', 1), {'error': 'ratio'}], [('qAB', 'standard', 3), {'error': 'char', 'char': 'q'}], [('Z-950%', 'full', 1), {'error': 'ratio'}], [('', 'full', 4), {'error': 'ratio'}], [('*', 'full', 2), {'data': '*/J*', 'modules': 51}]], [[('$5lot', 'full', 3), {'data': '*/D5+L+O+T*', 'modules': 175}], [('a+ba+b', 'full', 3), {'data': '*+A/K+B+A/K+B*', 'modules': 223}], [('AB\x1b', 'standard', 1), {'error': 'ratio'}], [('Z-9$512', 'standard', 4), {'error': 'ratio'}], [('xq', 'standard', 1), {'error': 'ratio'}], [('\x7f$5', 'full', 1), {'error': 'ratio'}], [('\x7f#1', 'full', 4), {'error': 'ratio'}], [('  \t', 'full', 2), {'data': '*  $I*', 'modules': 77}]]]
labels = ["regression: intercharacter gap count", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

prompt:
Label layout reserves one extra narrow module, pushing the symbol into the right quiet zone.

Encode text for Code 39 with a wide:narrow ratio of 2 or 3. Standard mode accepts only the 43 characters 0-9 A-Z - . space $ / + %. Full ASCII mode maps lowercase to "+" plus the capital, controls 1..26 to "$" plus A..Z, NUL to %U, 27..31 to %A..%E, DEL to %T, and punctuation (including the four standard shift characters $ % + /) to its two-character escape. Every symbol character, including the start/stop "*", has 6 narrow and 3 wide elements, and one narrow gap separates adjacent characters. Return the framed data and the total width in narrow modules.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, mode, ratio):
    std = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%'
    if ratio not in (2, 3):
        return {'error': 'ratio'}
    if mode == 'standard':
        for ch in text:
            if ch not in std:
                return {'error': 'char', 'char': ch}
        enc = text
    else:
        punct = {'$': '/D', '%': '/E', '+': '/K', '/': '/O', '!': '/A', '"': '/B', '#': '/C', '&': '/F', "'": '/G',
                 '(': '/H', ')': '/I', '*': '/J', ',': '/L', ':': '/Z', ';': '%F', '<': '%G', '=': '%H', '>': '%I',
                 '?': '%J', '@': '%V', '[': '%K', '\\': '%L', ']': '%M', '^': '%N', '_': '%O', '`': '%W',
                 '{': '%P', '|': '%Q', '}': '%R', '~': '%S'}
        enc = ''
        for ch in text:
            o = ord(ch)
            if o > 127:
                return {'error': 'char', 'char': ch}
            if ch in punct:
                enc += punct[ch]
            elif 'a' <= ch <= 'z':
                enc += '+' + ch.upper()
            elif 1 <= o <= 26:
                enc += '$' + chr(o + 64)
            elif o == 0:
                enc += '%U'
            elif 27 <= o <= 31:
                enc += '%' + chr(o - 27 + 65)
            elif o == 127:
                enc += '%T'
            else:
                enc += ch
    count = len(enc)
    return {'data': '*' + enc + '*', 'modules': count * (6 + 3 * ratio) + (count - 1)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('PN/7PN/7$5', 'full', 3), {'data': '*PN/O7PN/O7/D5*', 'modules': 239}], [('', 'standard', 3), {'data': '**', 'modules': 31}], [('café', 'standard', 4), {'error': 'ratio'}], [('ABPN/7PN/7', 'full', 1), {'error': 'ratio'}], [('a+ba+b', 'full', 4), {'error': 'ratio'}], [('Z-9a+blot', 'standard', 2), {'error': 'char', 'char': 'a'}], [('café\t', 'full', 4), {'error': 'ratio'}], [('\x1b', 'full', 2), {'data': '*%A*', 'modules': 51}]], [[('\x1blotlot', 'full', 2), {'data': '*%A+L+O+T+L+O+T*', 'modules': 207}], [('\t\x7fq', 'full', 2), {'data': '*$I%T+Q*', 'modules': 103}], [('', 'standard', 1), {'error': 'ratio'}], [('PN/7\x1blot', 'full', 4), {'error': 'ratio'}], [('\x00caféq', 'full', 4), {'error': 'ratio'}], [('q$5café', 'standard', 4), {'error': 'ratio'}], [('', 'full', 4), {'error': 'ratio'}], [('#1', 'full', 2), {'data': '*/C1*', 'modules': 64}]], [[('$5 \x00', 'full', 2), {'data': '*/D5 %U*', 'modules': 103}], [('', 'full', 2), {'data': '**', 'modules': 25}], [('#1café', 'standard', 4), {'error': 'ratio'}], [(' ', 'full', 1), {'error': 'ratio'}], [('*\x1bcafé', 'full', 2), {'error': 'char', 'char': 'é'}], [('', 'full', 4), {'error': 'ratio'}], [('\x7f#1', 'standard', 4), {'error': 'ratio'}], [('ABPN/7Z-9', 'full', 2), {'data': '*ABPN/O7Z-9*', 'modules': 155}]], [[('AB12', 'standard', 2), {'data': '*AB12*', 'modules': 77}], [('', 'full', 2), {'data': '**', 'modules': 25}], [('#1café', 'full', 2), {'error': 'char', 'char': 'é'}], [(' ABPN/7', 'full', 1), {'error': 'ratio'}], [('qAB', 'standard', 3), {'error': 'char', 'char': 'q'}], [('Z-950%', 'full', 1), {'error': 'ratio'}], [('', 'full', 4), {'error': 'ratio'}], [('*', 'full', 2), {'data': '*/J*', 'modules': 51}]], [[('$5lot', 'full', 3), {'data': '*/D5+L+O+T*', 'modules': 175}], [('a+ba+b', 'full', 3), {'data': '*+A/K+B+A/K+B*', 'modules': 223}], [('AB\x1b', 'standard', 1), {'error': 'ratio'}], [('Z-9$512', 'standard', 4), {'error': 'ratio'}], [('xq', 'standard', 1), {'error': 'ratio'}], [('\x7f$5', 'full', 1), {'error': 'ratio'}], [('\x7f#1', 'full', 4), {'error': 'ratio'}], [('  \t', 'full', 2), {'data': '*  $I*', 'modules': 77}]]]
labels = ["regression: start and stop characters", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, mode, ratio):
    std = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%'
    if ratio not in (2, 3):
        return {'error': 'ratio'}
    if mode == 'standard':
        for ch in text:
            if ch not in std:
                return {'error': 'char', 'char': ch}
        enc = text
    else:
        punct = {'$': '/D', '%': '/E', '+': '/K', '/': '/O', '!': '/A', '"': '/B', '#': '/C', '&': '/F', "'": '/G',
                 '(': '/H', ')': '/I', '*': '/J', ',': '/L', ':': '/Z', ';': '%F', '<': '%G', '=': '%H', '>': '%I',
                 '?': '%J', '@': '%V', '[': '%K', '\\': '%L', ']': '%M', '^': '%N', '_': '%O', '`': '%W',
                 '{': '%P', '|': '%Q', '}': '%R', '~': '%S'}
        enc = ''
        for ch in text:
            o = ord(ch)
            if o > 127:
                return {'error': 'char', 'char': ch}
            if ch in punct:
                enc += punct[ch]
            elif 'a' <= ch <= 'z':
                enc += '+' + ch.upper()
            elif 1 <= o <= 26:
                enc += '$' + chr(o + 64)
            elif o == 0:
                enc += '%U'
            elif 27 <= o <= 31:
                enc += '%' + chr(o - 27 + 65)
            elif o == 127:
                enc += '%T'
            else:
                enc += ch
    count = len(enc) + 1
    return {'data': '*' + enc + '*', 'modules': count * (6 + 3 * ratio) + (count - 1)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('PN/7PN/7$5', 'full', 3), {'data': '*PN/O7PN/O7/D5*', 'modules': 239}], [('', 'standard', 3), {'data': '**', 'modules': 31}], [('café', 'standard', 4), {'error': 'ratio'}], [('ABPN/7PN/7', 'full', 1), {'error': 'ratio'}], [('a+ba+b', 'full', 4), {'error': 'ratio'}], [('Z-9a+blot', 'standard', 2), {'error': 'char', 'char': 'a'}], [('café\t', 'full', 4), {'error': 'ratio'}], [('\x1b', 'full', 2), {'data': '*%A*', 'modules': 51}]], [[('\x1blotlot', 'full', 2), {'data': '*%A+L+O+T+L+O+T*', 'modules': 207}], [('\t\x7fq', 'full', 2), {'data': '*$I%T+Q*', 'modules': 103}], [('', 'standard', 1), {'error': 'ratio'}], [('PN/7\x1blot', 'full', 4), {'error': 'ratio'}], [('\x00caféq', 'full', 4), {'error': 'ratio'}], [('q$5café', 'standard', 4), {'error': 'ratio'}], [('', 'full', 4), {'error': 'ratio'}], [('#1', 'full', 2), {'data': '*/C1*', 'modules': 64}]], [[('$5 \x00', 'full', 2), {'data': '*/D5 %U*', 'modules': 103}], [('', 'full', 2), {'data': '**', 'modules': 25}], [('#1café', 'standard', 4), {'error': 'ratio'}], [(' ', 'full', 1), {'error': 'ratio'}], [('*\x1bcafé', 'full', 2), {'error': 'char', 'char': 'é'}], [('', 'full', 4), {'error': 'ratio'}], [('\x7f#1', 'standard', 4), {'error': 'ratio'}], [('ABPN/7Z-9', 'full', 2), {'data': '*ABPN/O7Z-9*', 'modules': 155}]], [[('AB12', 'standard', 2), {'data': '*AB12*', 'modules': 77}], [('', 'full', 2), {'data': '**', 'modules': 25}], [('#1café', 'full', 2), {'error': 'char', 'char': 'é'}], [(' ABPN/7', 'full', 1), {'error': 'ratio'}], [('qAB', 'standard', 3), {'error': 'char', 'char': 'q'}], [('Z-950%', 'full', 1), {'error': 'ratio'}], [('', 'full', 4), {'error': 'ratio'}], [('*', 'full', 2), {'data': '*/J*', 'modules': 51}]], [[('$5lot', 'full', 3), {'data': '*/D5+L+O+T*', 'modules': 175}], [('a+ba+b', 'full', 3), {'data': '*+A/K+B+A/K+B*', 'modules': 223}], [('AB\x1b', 'standard', 1), {'error': 'ratio'}], [('Z-9$512', 'standard', 4), {'error': 'ratio'}], [('xq', 'standard', 1), {'error': 'ratio'}], [('\x7f$5', 'full', 1), {'error': 'ratio'}], [('\x7f#1', 'full', 4), {'error': 'ratio'}], [('  \t', 'full', 2), {'data': '*  $I*', 'modules': 77}]]]
labels = ["regression: start and stop characters", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

prompt:
Printed symbols are wider than the layout box and get clipped.

Encode text for Code 39 with a wide:narrow ratio of 2 or 3. Standard mode accepts only the 43 characters 0-9 A-Z - . space $ / + %. Full ASCII mode maps lowercase to "+" plus the capital, controls 1..26 to "$" plus A..Z, NUL to %U, 27..31 to %A..%E, DEL to %T, and punctuation (including the four standard shift characters $ % + /) to its two-character escape. Every symbol character, including the start/stop "*", has 6 narrow and 3 wide elements, and one narrow gap separates adjacent characters. Return the framed data and the total width in narrow modules.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, mode, ratio):
    std = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%'
    if ratio not in (2, 3):
        return {'error': 'ratio'}
    if mode == 'standard':
        enc = text.upper()
        for ch in enc:
            if ch not in std:
                return {'error': 'char', 'char': ch}
    else:
        punct = {'$': '/D', '%': '/E', '+': '/K', '/': '/O', '!': '/A', '"': '/B', '#': '/C', '&': '/F', "'": '/G',
                 '(': '/H', ')': '/I', '*': '/J', ',': '/L', ':': '/Z', ';': '%F', '<': '%G', '=': '%H', '>': '%I',
                 '?': '%J', '@': '%V', '[': '%K', '\\': '%L', ']': '%M', '^': '%N', '_': '%O', '`': '%W',
                 '{': '%P', '|': '%Q', '}': '%R', '~': '%S'}
        enc = ''
        for ch in text:
            o = ord(ch)
            if o > 127:
                return {'error': 'char', 'char': ch}
            if ch in punct:
                enc += punct[ch]
            elif 'a' <= ch <= 'z':
                enc += '+' + ch.upper()
            elif 1 <= o <= 26:
                enc += '$' + chr(o + 64)
            elif o == 0:
                enc += '%U'
            elif 27 <= o <= 31:
                enc += '%' + chr(o - 27 + 65)
            elif o == 127:
                enc += '%T'
            else:
                enc += ch
    count = len(enc) + 2
    return {'data': '*' + enc + '*', 'modules': count * (6 + 3 * ratio) + (count - 1)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('Z-9a+blot', 'standard', 2), {'error': 'char', 'char': 'a'}], [('café', 'standard', 2), {'error': 'char', 'char': 'c'}], [('café', 'standard', 4), {'error': 'ratio'}], [('ABPN/7PN/7', 'full', 1), {'error': 'ratio'}], [('a+ba+b', 'full', 4), {'error': 'ratio'}], [('café\t', 'full', 4), {'error': 'ratio'}], [('Z-9', 'standard', 4), {'error': 'ratio'}], [('café', 'standard', 3), {'error': 'char', 'char': 'c'}]], [[('lotZ-9', 'standard', 2), {'error': 'char', 'char': 'l'}], [('$5lot', 'standard', 2), {'error': 'char', 'char': 'l'}], [('', 'standard', 1), {'error': 'ratio'}], [('\x1blotlot', 'full', 2), {'data': '*%A+L+O+T+L+O+T*', 'modules': 207}], [('#1', 'full', 2), {'data': '*/C1*', 'modules': 64}], [('ABa+b', 'full', 2), {'data': '*AB+A/K+B*', 'modules': 129}], [('', 'full', 3), {'data': '**', 'modules': 31}], [('café', 'standard', 2), {'error': 'char', 'char': 'c'}]], [[('lot', 'standard', 3), {'error': 'char', 'char': 'l'}], [('12q*', 'standard', 3), {'error': 'char', 'char': 'q'}], [('a+bAB', 'full', 2), {'data': '*+A/K+BAB*', 'modules': 129}], [('#1café', 'standard', 4), {'error': 'ratio'}], [('ABPN/7Z-9', 'full', 2), {'data': '*ABPN/O7Z-9*', 'modules': 155}], [(' ', 'full', 1), {'error': 'ratio'}], [('$5 \x00', 'full', 2), {'data': '*/D5 %U*', 'modules': 103}], [('a+b', 'standard', 3), {'error': 'char', 'char': 'a'}]], [[('a+b\t', 'standard', 3), {'error': 'char', 'char': 'a'}], [('Z-9x$5', 'standard', 2), {'error': 'char', 'char': 'x'}], [('qPN/7café', 'full', 2), {'error': 'char', 'char': 'é'}], [('AB\x00 ', 'full', 1), {'error': 'ratio'}], [('*', 'full', 2), {'data': '*/J*', 'modules': 51}], [('AB12', 'standard', 2), {'data': '*AB12*', 'modules': 77}], [('\x7f\tlot', 'full', 3), {'data': '*%T$I+L+O+T*', 'modules': 191}], [('x12', 'standard', 2), {'error': 'char', 'char': 'x'}]], [[('a+bcafécafé', 'standard', 2), {'error': 'char', 'char': 'a'}], [('x', 'standard', 2), {'error': 'char', 'char': 'x'}], [('$5lot', 'full', 3), {'data': '*/D5+L+O+T*', 'modules': 175}], [('\x00', 'full', 1), {'error': 'ratio'}], [('', 'standard', 2), {'data': '**', 'modules': 25}], [('', 'standard', 1), {'error': 'ratio'}], [('\x7f\x00', 'full', 4), {'error': 'ratio'}], [('1250%lot', 'standard', 2), {'error': 'char', 'char': 'l'}]]]
labels = ["regression: standard mode lowercase", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, mode, ratio):
    std = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%'
    if ratio not in (2, 3):
        return {'error': 'ratio'}
    if mode == 'standard':
        for ch in text.upper():
            if ch not in std:
                return {'error': 'char', 'char': ch}
        enc = text
    else:
        punct = {'$': '/D', '%': '/E', '+': '/K', '/': '/O', '!': '/A', '"': '/B', '#': '/C', '&': '/F', "'": '/G',
                 '(': '/H', ')': '/I', '*': '/J', ',': '/L', ':': '/Z', ';': '%F', '<': '%G', '=': '%H', '>': '%I',
                 '?': '%J', '@': '%V', '[': '%K', '\\': '%L', ']': '%M', '^': '%N', '_': '%O', '`': '%W',
                 '{': '%P', '|': '%Q', '}': '%R', '~': '%S'}
        enc = ''
        for ch in text:
            o = ord(ch)
            if o > 127:
                return {'error': 'char', 'char': ch}
            if ch in punct:
                enc += punct[ch]
            elif 'a' <= ch <= 'z':
                enc += '+' + ch.upper()
            elif 1 <= o <= 26:
                enc += '$' + chr(o + 64)
            elif o == 0:
                enc += '%U'
            elif 27 <= o <= 31:
                enc += '%' + chr(o - 27 + 65)
            elif o == 127:
                enc += '%T'
            else:
                enc += ch
    count = len(enc) + 2
    return {'data': '*' + enc + '*', 'modules': count * (6 + 3 * ratio) + (count - 1)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('Z-9a+blot', 'standard', 2), {'error': 'char', 'char': 'a'}], [('café', 'standard', 2), {'error': 'char', 'char': 'c'}], [('café', 'standard', 4), {'error': 'ratio'}], [('ABPN/7PN/7', 'full', 1), {'error': 'ratio'}], [('a+ba+b', 'full', 4), {'error': 'ratio'}], [('café\t', 'full', 4), {'error': 'ratio'}], [('Z-9', 'standard', 4), {'error': 'ratio'}], [('café', 'standard', 3), {'error': 'char', 'char': 'c'}]], [[('lotZ-9', 'standard', 2), {'error': 'char', 'char': 'l'}], [('$5lot', 'standard', 2), {'error': 'char', 'char': 'l'}], [('', 'standard', 1), {'error': 'ratio'}], [('\x1blotlot', 'full', 2), {'data': '*%A+L+O+T+L+O+T*', 'modules': 207}], [('#1', 'full', 2), {'data': '*/C1*', 'modules': 64}], [('ABa+b', 'full', 2), {'data': '*AB+A/K+B*', 'modules': 129}], [('', 'full', 3), {'data': '**', 'modules': 31}], [('café', 'standard', 2), {'error': 'char', 'char': 'c'}]], [[('lot', 'standard', 3), {'error': 'char', 'char': 'l'}], [('12q*', 'standard', 3), {'error': 'char', 'char': 'q'}], [('a+bAB', 'full', 2), {'data': '*+A/K+BAB*', 'modules': 129}], [('#1café', 'standard', 4), {'error': 'ratio'}], [('ABPN/7Z-9', 'full', 2), {'data': '*ABPN/O7Z-9*', 'modules': 155}], [(' ', 'full', 1), {'error': 'ratio'}], [('$5 \x00', 'full', 2), {'data': '*/D5 %U*', 'modules': 103}], [('a+b', 'standard', 3), {'error': 'char', 'char': 'a'}]], [[('a+b\t', 'standard', 3), {'error': 'char', 'char': 'a'}], [('Z-9x$5', 'standard', 2), {'error': 'char', 'char': 'x'}], [('qPN/7café', 'full', 2), {'error': 'char', 'char': 'é'}], [('AB\x00 ', 'full', 1), {'error': 'ratio'}], [('*', 'full', 2), {'data': '*/J*', 'modules': 51}], [('AB12', 'standard', 2), {'data': '*AB12*', 'modules': 77}], [('\x7f\tlot', 'full', 3), {'data': '*%T$I+L+O+T*', 'modules': 191}], [('x12', 'standard', 2), {'error': 'char', 'char': 'x'}]], [[('a+bcafécafé', 'standard', 2), {'error': 'char', 'char': 'a'}], [('x', 'standard', 2), {'error': 'char', 'char': 'x'}], [('$5lot', 'full', 3), {'data': '*/D5+L+O+T*', 'modules': 175}], [('\x00', 'full', 1), {'error': 'ratio'}], [('', 'standard', 2), {'data': '**', 'modules': 25}], [('', 'standard', 1), {'error': 'ratio'}], [('\x7f\x00', 'full', 4), {'error': 'ratio'}], [('1250%lot', 'standard', 2), {'error': 'char', 'char': 'l'}]]]
labels = ["regression: standard mode lowercase", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

prompt:
Case-sensitive part numbers scan back in capitals without any error.

Encode text for Code 39 with a wide:narrow ratio of 2 or 3. Standard mode accepts only the 43 characters 0-9 A-Z - . space $ / + %. Full ASCII mode maps lowercase to "+" plus the capital, controls 1..26 to "$" plus A..Z, NUL to %U, 27..31 to %A..%E, DEL to %T, and punctuation (including the four standard shift characters $ % + /) to its two-character escape. Every symbol character, including the start/stop "*", has 6 narrow and 3 wide elements, and one narrow gap separates adjacent characters. Return the framed data and the total width in narrow modules.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, mode, ratio):
    std = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%'
    if ratio not in (2, 3):
        return {'error': 'ratio'}
    if mode == 'standard':
        for ch in text:
            if ch not in std:
                return {'error': 'char', 'char': ch}
        enc = text
    else:
        punct = {'!': '/A', '"': '/B', '#': '/C', '&': '/F', "'": '/G',
                 '(': '/H', ')': '/I', '*': '/J', ',': '/L', ':': '/Z', ';': '%F', '<': '%G', '=': '%H', '>': '%I',
                 '?': '%J', '@': '%V', '[': '%K', '\\': '%L', ']': '%M', '^': '%N', '_': '%O', '`': '%W',
                 '{': '%P', '|': '%Q', '}': '%R', '~': '%S'}
        enc = ''
        for ch in text:
            o = ord(ch)
            if o > 127:
                return {'error': 'char', 'char': ch}
            if ch in punct:
                enc += punct[ch]
            elif 'a' <= ch <= 'z':
                enc += '+' + ch.upper()
            elif 1 <= o <= 26:
                enc += '$' + chr(o + 64)
            elif o == 0:
                enc += '%U'
            elif 27 <= o <= 31:
                enc += '%' + chr(o - 27 + 65)
            elif o == 127:
                enc += '%T'
            else:
                enc += ch
    count = len(enc) + 2
    return {'data': '*' + enc + '*', 'modules': count * (6 + 3 * ratio) + (count - 1)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('PN/7PN/7$5', 'full', 3), {'data': '*PN/O7PN/O7/D5*', 'modules': 239}], [('PN/7', 'full', 2), {'data': '*PN/O7*', 'modules': 90}], [('café', 'standard', 4), {'error': 'ratio'}], [('ABPN/7PN/7', 'full', 1), {'error': 'ratio'}], [('a+ba+b', 'full', 4), {'error': 'ratio'}], [('Z-9a+blot', 'standard', 2), {'error': 'char', 'char': 'a'}], [('café\t', 'full', 4), {'error': 'ratio'}], [('*$5\x1b', 'full', 2), {'data': '*/J/D5%A*', 'modules': 116}]], [[(' 50% ', 'full', 2), {'data': '* 50/E *', 'modules': 103}], [('PN/750%*', 'full', 2), {'data': '*PN/O750/E/J*', 'modules': 168}], [('PN/7PN/7', 'full', 3), {'data': '*PN/O7PN/O7*', 'modules': 191}], [('', 'standard', 1), {'error': 'ratio'}], [('\x1blotlot', 'full', 2), {'data': '*%A+L+O+T+L+O+T*', 'modules': 207}], [('#1', 'full', 2), {'data': '*/C1*', 'modules': 64}], [('', 'full', 3), {'data': '**', 'modules': 31}], [('50%\x00', 'full', 3), {'data': '*50/E%U*', 'modules': 127}]], [[('$5 \x00', 'full', 2), {'data': '*/D5 %U*', 'modules': 103}], [(' a+b\x7f', 'full', 2), {'data': '* +A/K+B%T*', 'modules': 142}], [('a+b\x1b', 'full', 3), {'data': '*+A/K+B%A*', 'modules': 159}], [('#1café', 'standard', 4), {'error': 'ratio'}], [(' ', 'full', 1), {'error': 'ratio'}], [('*\x1bcafé', 'full', 2), {'error': 'char', 'char': 'é'}], [('q \x00', 'full', 2), {'data': '*+Q %U*', 'modules': 90}], [('ABPN/7Z-9', 'full', 2), {'data': '*ABPN/O7Z-9*', 'modules': 155}]], [[('*a+b50%', 'full', 2), {'data': '*/J+A/K+B50/E*', 'modules': 181}], [('$5a+b', 'full', 3), {'data': '*/D5+A/K+B*', 'modules': 175}], [('xPN/7\x00', 'full', 3), {'data': '*+XPN/O7%U*', 'modules': 175}], [('AB\x00 ', 'full', 1), {'error': 'ratio'}], [('*', 'full', 2), {'data': '*/J*', 'modules': 51}], [('AB12', 'standard', 2), {'data': '*AB12*', 'modules': 77}], [('\x7f\tlot', 'full', 3), {'data': '*%T$I+L+O+T*', 'modules': 191}], [('PN/7', 'full', 2), {'data': '*PN/O7*', 'modules': 90}]], [[('q50%', 'full', 2), {'data': '*+Q50/E*', 'modules': 103}], [('Z-9qa+b', 'full', 2), {'data': '*Z-9+Q+A/K+B*', 'modules': 168}], [('a+b', 'full', 2), {'data': '*+A/K+B*', 'modules': 103}], [('\x00', 'full', 1), {'error': 'ratio'}], [('', 'standard', 2), {'data': '**', 'modules': 25}], [('', 'standard', 1), {'error': 'ratio'}], [('\x7f\x00', 'full', 4), {'error': 'ratio'}], [('$5a+bAB', 'full', 3), {'data': '*/D5+A/K+BAB*', 'modules': 207}]]]
labels = ["regression: escaping the shift characters", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(text, mode, ratio):
    std = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%'
    if ratio not in (2, 3):
        return {'error': 'ratio'}
    if mode == 'standard':
        for ch in text:
            if ch not in std:
                return {'error': 'char', 'char': ch}
        enc = text
    else:
        punct = {'$': '/D', '%': '/E', '!': '/A', '"': '/B', '#': '/C', '&': '/F', "'": '/G',
                 '(': '/H', ')': '/I', '*': '/J', ',': '/L', ':': '/Z', ';': '%F', '<': '%G', '=': '%H', '>': '%I',
                 '?': '%J', '@': '%V', '[': '%K', '\\': '%L', ']': '%M', '^': '%N', '_': '%O', '`': '%W',
                 '{': '%P', '|': '%Q', '}': '%R', '~': '%S'}
        enc = ''
        for ch in text:
            o = ord(ch)
            if o > 127:
                return {'error': 'char', 'char': ch}
            if ch in punct:
                enc += punct[ch]
            elif 'a' <= ch <= 'z':
                enc += '+' + ch.upper()
            elif 1 <= o <= 26:
                enc += '$' + chr(o + 64)
            elif o == 0:
                enc += '%U'
            elif 27 <= o <= 31:
                enc += '%' + chr(o - 27 + 65)
            elif o == 127:
                enc += '%T'
            else:
                enc += ch
    count = len(enc) + 2
    return {'data': '*' + enc + '*', 'modules': count * (6 + 3 * ratio) + (count - 1)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('PN/7PN/7$5', 'full', 3), {'data': '*PN/O7PN/O7/D5*', 'modules': 239}], [('PN/7', 'full', 2), {'data': '*PN/O7*', 'modules': 90}], [('café', 'standard', 4), {'error': 'ratio'}], [('ABPN/7PN/7', 'full', 1), {'error': 'ratio'}], [('a+ba+b', 'full', 4), {'error': 'ratio'}], [('Z-9a+blot', 'standard', 2), {'error': 'char', 'char': 'a'}], [('café\t', 'full', 4), {'error': 'ratio'}], [('*$5\x1b', 'full', 2), {'data': '*/J/D5%A*', 'modules': 116}]], [[(' 50% ', 'full', 2), {'data': '* 50/E *', 'modules': 103}], [('PN/750%*', 'full', 2), {'data': '*PN/O750/E/J*', 'modules': 168}], [('PN/7PN/7', 'full', 3), {'data': '*PN/O7PN/O7*', 'modules': 191}], [('', 'standard', 1), {'error': 'ratio'}], [('\x1blotlot', 'full', 2), {'data': '*%A+L+O+T+L+O+T*', 'modules': 207}], [('#1', 'full', 2), {'data': '*/C1*', 'modules': 64}], [('', 'full', 3), {'data': '**', 'modules': 31}], [('50%\x00', 'full', 3), {'data': '*50/E%U*', 'modules': 127}]], [[('$5 \x00', 'full', 2), {'data': '*/D5 %U*', 'modules': 103}], [(' a+b\x7f', 'full', 2), {'data': '* +A/K+B%T*', 'modules': 142}], [('a+b\x1b', 'full', 3), {'data': '*+A/K+B%A*', 'modules': 159}], [('#1café', 'standard', 4), {'error': 'ratio'}], [(' ', 'full', 1), {'error': 'ratio'}], [('*\x1bcafé', 'full', 2), {'error': 'char', 'char': 'é'}], [('q \x00', 'full', 2), {'data': '*+Q %U*', 'modules': 90}], [('ABPN/7Z-9', 'full', 2), {'data': '*ABPN/O7Z-9*', 'modules': 155}]], [[('*a+b50%', 'full', 2), {'data': '*/J+A/K+B50/E*', 'modules': 181}], [('$5a+b', 'full', 3), {'data': '*/D5+A/K+B*', 'modules': 175}], [('xPN/7\x00', 'full', 3), {'data': '*+XPN/O7%U*', 'modules': 175}], [('AB\x00 ', 'full', 1), {'error': 'ratio'}], [('*', 'full', 2), {'data': '*/J*', 'modules': 51}], [('AB12', 'standard', 2), {'data': '*AB12*', 'modules': 77}], [('\x7f\tlot', 'full', 3), {'data': '*%T$I+L+O+T*', 'modules': 191}], [('PN/7', 'full', 2), {'data': '*PN/O7*', 'modules': 90}]], [[('q50%', 'full', 2), {'data': '*+Q50/E*', 'modules': 103}], [('Z-9qa+b', 'full', 2), {'data': '*Z-9+Q+A/K+B*', 'modules': 168}], [('a+b', 'full', 2), {'data': '*+A/K+B*', 'modules': 103}], [('\x00', 'full', 1), {'error': 'ratio'}], [('', 'standard', 2), {'data': '**', 'modules': 25}], [('', 'standard', 1), {'error': 'ratio'}], [('\x7f\x00', 'full', 4), {'error': 'ratio'}], [('$5a+bAB', 'full', 3), {'data': '*/D5+A/K+BAB*', 'modules': 207}]]]
labels = ["regression: escaping the shift characters", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), 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)

prompt:
A price such as "$5" decodes in full ASCII readers as a control character.

Encode text for Code 39 with a wide:narrow ratio of 2 or 3. Standard mode accepts only the 43 characters 0-9 A-Z - . space $ / + %. Full ASCII mode maps lowercase to "+" plus the capital, controls 1..26 to "$" plus A..Z, NUL to %U, 27..31 to %A..%E, DEL to %T, and punctuation (including the four standard shift characters $ % + /) to its two-character escape. Every symbol character, including the start/stop "*", has 6 narrow and 3 wide elements, and one narrow gap separates adjacent characters. Return the framed data and the total width in narrow modules.

split: open-access