Skip to content

Instantly share code, notes, and snippets.

@elleryq
Last active February 8, 2023 10:27
Show Gist options
  • Save elleryq/4c2e309d3155b8819d3d to your computer and use it in GitHub Desktop.
Save elleryq/4c2e309d3155b8819d3d to your computer and use it in GitHub Desktop.
產生 Bingo 表格的程式,裏面的數字是亂數,預設一頁產生 12 個表格,結果會輸出為 PDF。參數是要產生的頁數,輸出檔案會在當前目錄下的 bingo.pdf
#!/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