diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-10-20 02:43:08 +0200 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-10-20 02:43:08 +0200 |
| commit | fa9c695256de1c7fe007ba5d6bb9b28b1deb5a5a (patch) | |
| tree | bd418bc860349833d5a19c4af6bb8a61666477ca /tools/check_codes.py | |
| parent | 59255b1a55a81ba2b5de967eefced11910597b48 (diff) | |
test(codes): compare with zxing-cpp reference rows and decode encoder output and screenshots
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'tools/check_codes.py')
| -rw-r--r-- | tools/check_codes.py | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/tools/check_codes.py b/tools/check_codes.py new file mode 100644 index 0000000..22d3033 --- /dev/null +++ b/tools/check_codes.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# Author: cirakg & claude ai +# Summary: Decode the barcodes the watch's encoders produced in a unit-test run with zxing-cpp (README 12.4 check 2). +"""Decode-check the CODEDUMP lines of a Monkey C test log. + +Each line is "CODEDUMP <symbology> <readable text as hex> <modules>". Every +code is rendered with its quiet zone at 1, 2 and 3 pixels per module and +must decode to the expected text at each size. + +Usage: check_codes.py LOG [LOG ...] Exit: 0 all decoded, 1 a failure, 2 no dump found. +""" + +from __future__ import annotations + +import re +import sys +from pathlib import Path + +import barcode_ref as ref + +DUMP = re.compile(r"CODEDUMP (\d+) ([0-9a-f]*) ([01]+)") +SCALES = (1, 2, 3) + + +def check_log(path: Path) -> tuple[int, list[str]]: + """(codes checked, failure messages) for one log.""" + checked = 0 + failures: list[str] = [] + for match in DUMP.finditer(path.read_text(encoding="utf-8", errors="replace")): + symbology = int(match.group(1)) + text = bytes.fromhex(match.group(2)).decode("utf-8") + modules = match.group(3) + expected = ref.expected_reading(symbology, text) + for scale in SCALES: + got = ref.decode(ref.render_linear(modules, scale), symbology) + if expected not in got: + failures.append(f"symbology {symbology} '{text}' at {scale} px/module: read {got}") + checked += 1 + return checked, failures + + +def main(argv: list[str] | None = None) -> int: + paths = [Path(p) for p in (argv if argv is not None else sys.argv[1:])] + total = 0 + failed = False + for path in paths: + checked, failures = check_log(path) + total += checked + for failure in failures[:10]: + print(f"[{path.stem}] {failure}") + failed = failed or bool(failures) + print(f"[{path.stem}] decoded {checked} barcodes at {len(SCALES)} sizes: {'FAILED' if failures else 'ok'}") + if total == 0: + print("no CODEDUMP lines found") + return 2 + return 1 if failed else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) |
