elleryq
10/31/2014 - 7:34 AM

產生 Bingo 表格的程式,裏面的數字是亂數,預設一頁產生 12 個表格,結果會輸出為 PDF。參數是要產生的頁數,輸出檔案會在當前目錄下的 bingo.pdf

產生 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")