Last active
February 8, 2023 10:27
-
-
Save elleryq/4c2e309d3155b8819d3d to your computer and use it in GitHub Desktop.
產生 Bingo 表格的程式,裏面的數字是亂數,預設一頁產生 12 個表格,結果會輸出為 PDF。參數是要產生的頁數,輸出檔案會在當前目錄下的 bingo.pdf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# Dependencies: | |
# * wkhtmltopdf - Convert HTML to PDF | |
# * pdftk - Merge multiple PDFs to single PDF | |
# * jinja2 - Template engine | |
import sys | |
import os | |
from itertools import permutations, izip_longest | |
import random | |
from jinja2 import Template | |
from tempfile import NamedTemporaryFile | |
from subprocess import call | |
template = Template(""" | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<style> | |
table { | |
font-size: 0.8cm; | |
border: 5px #cccccc solid; | |
display: block; | |
float: left; | |
margin: 10px; | |
} | |
td {text-align: right;} | |
#content { | |
width: 100%; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="content"> | |
{% for table in tables %} | |
<table border="1"> | |
{% for row in table %} | |
<tr> | |
{% for col in row %} | |
<td>{{ col }}</td> | |
{% endfor %} | |
</tr> | |
{% endfor %} | |
</table> | |
{% endfor %} | |
</div> | |
</body> | |
</html> | |
""") | |
# The below 3 functions are from | |
# https://docs.python.org/2/library/itertools.html | |
def random_combination(iterable, r): | |
"Random selection from itertools.combinations(iterable, r)" | |
pool = tuple(iterable) | |
n = len(pool) | |
indices = sorted(random.sample(xrange(n), r)) | |
return tuple(pool[i] for i in indices) | |
def random_permutation(iterable, r=None): | |
"Random selection from itertools.permutations(iterable, r)" | |
pool = tuple(iterable) | |
r = len(pool) if r is None else r | |
return tuple(random.sample(pool, r)) | |
def grouper(iterable, n, fillvalue=None): | |
"Collect data into fixed-length chunks or blocks" | |
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx | |
args = [iter(iterable)] * n | |
return izip_longest(fillvalue=fillvalue, *args) | |
def generate_html(): | |
tables = [] | |
twenty_five = range(1, 26) | |
for i in range(12): | |
tables.append(grouper(random_permutation(twenty_five, 25), 5)) | |
fout = NamedTemporaryFile(suffix=".html", delete=False) | |
fout.write(template.render(tables=tables)) | |
return fout.name | |
def generate_pdf(html_file): | |
fout = NamedTemporaryFile(suffix=".pdf", delete=False) | |
name = fout.name | |
fout.close() | |
call(['wkhtmltopdf', html_file, name]) | |
return name | |
def pdfcat(pdfs, output): | |
cmd = ['pdftk'] | |
cmd.extend(pdfs) | |
cmd.extend(["cat", "output"]) | |
cmd.append(output) | |
call(cmd) | |
if __name__ == "__main__": | |
pages = 1 | |
if len(sys.argv): | |
try: | |
pages = int(sys.argv[1]) | |
except: | |
print("Argument should be number.") | |
sys.exit(-1) | |
pdfs = [] | |
for i in range(pages): | |
html_fn = generate_html() | |
print(os.path.exists(html_fn)) | |
pdfs.append(generate_pdf(html_fn)) | |
os.remove(html_fn) | |
pdfcat(pdfs, "bingo.pdf") | |
# clean up | |
for pdf in pdfs: | |
os.remove(pdf) | |
print("Already output to bingo.pdf") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment