forked from vycdev/thermal-printer-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmultiplication_print.py
More file actions
77 lines (62 loc) · 2.69 KB
/
Copy pathmultiplication_print.py
File metadata and controls
77 lines (62 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env python3
"""Print a multiplication table on the S01 thermal printer.
A classic N x N times-table grid with highlighted headers -- handy for the wall
or the school bag.
Examples:
python multiplication_print.py # 12 x 12
python multiplication_print.py --size 10
python multiplication_print.py --no-print
"""
from __future__ import annotations
import argparse
from pathlib import Path
from PIL import Image, ImageDraw
from print_common import ROOT, Card, font
def draw_table(n: int, w: int) -> Image.Image:
cells = n + 1
cell = w // cells
grid = cell * cells
img = Image.new("L", (grid + 1, grid + 1), 255)
d = ImageDraw.Draw(img)
hf = font(True, round(cell * 0.45))
nf = font(False, round(cell * 0.42))
for r in range(cells):
for c in range(cells):
x0, y0 = c * cell, r * cell
header = r == 0 or c == 0
if header:
d.rectangle((x0, y0, x0 + cell, y0 + cell), fill=0)
if r == 0 and c == 0:
txt, fill, fnt = "x", 255, hf
elif r == 0:
txt, fill, fnt = str(c), 255, hf
elif c == 0:
txt, fill, fnt = str(r), 255, hf
else:
txt, fill, fnt = str(r * c), 0, nf
d.text((x0 + cell / 2, y0 + cell / 2), txt, fill=fill, font=fnt, anchor="mm")
for i in range(cells + 1):
wdt = 2 if i in (0, 1, cells) else 1
d.line((i * cell, 0, i * cell, grid), fill=0, width=wdt)
d.line((0, i * cell, grid, i * cell), fill=0, width=wdt)
return img
def main() -> int:
parser = argparse.ArgumentParser(description="Print a multiplication table on the S01 thermal printer.")
parser.add_argument("--size", type=int, default=12, help="Table size N x N (default: 12).")
parser.add_argument("--out", type=Path, default=None)
parser.add_argument("--darkness", type=int, choices=range(1, 6), default=3)
parser.add_argument("--bottom-feed", type=int, default=24)
parser.add_argument("--no-print", action="store_true")
args = parser.parse_args()
if not 5 <= args.size <= 12:
parser.error("--size must be 5-12")
print(f"Generating {args.size}x{args.size} multiplication table ...")
card = Card()
card.title("TIMES TABLE")
card.line(f"{args.size} x {args.size}", size=12, bold=False, center=True)
card.gap(4).image(draw_table(args.size, card.inner_w), border=False)
card.footer("multiplication", f"to {args.size}x{args.size}")
out = args.out or ROOT / f"timestable_{args.size}.png"
return card.finish(out, args.bottom_feed, args.darkness, do_print=not args.no_print)
if __name__ == "__main__":
raise SystemExit(main())