aboutsummaryrefslogtreecommitdiff
path: root/tools/check_codes.py
diff options
context:
space:
mode:
authorcirakg <cirakg@cirakg.xyz>2026-10-20 02:43:08 +0200
committercirakg <cirakg@cirakg.xyz>2026-10-20 02:43:08 +0200
commitfa9c695256de1c7fe007ba5d6bb9b28b1deb5a5a (patch)
treebd418bc860349833d5a19c4af6bb8a61666477ca /tools/check_codes.py
parent59255b1a55a81ba2b5de967eefced11910597b48 (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.py60
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())