Pythonで計算ドリルをpdfで生成する

やりたいこと

今週は小学生くらいの児童向けの計算ドリルを、Pythonで自動生成するプログラムを書いてみます。
実現したいことは次の2つです。
①足し算の式 (ex 1+1=)を20個ほど作成する
②計算式をpdfに書き出し、印刷できる状態とする。

プログラムの説明

モジュール類

最終的に作るのはpdfファイルです。まずはpdfを扱うためのモジュールをインポートします。

#乱数を発生させる
import random

#pdfをいじる
from reportlab.pdfgen import canvas
from reportlab.pdfbase.pdfmetrics import registerFont
from reportlab.pdfbase.ttfonts import TTFont

pdfの設定

次に、pdfに書き出すフォントを用意します。適当なttfファイルを用意し、
同じ階層に置いてください
源真ゴシック (げんしんゴシック) | 自家製フォント工房

registerFont(TTFont('GenShinGothic', 
                    './fonts/GenShinGothic-Monospace-Light.ttf'))

次にファイル名等の設定をしていきます。

#ファイル名の設定
title = '計算テスト'
#pdfの下地を準備する
pdf = canvas.Canvas(title + '.pdf')
pdf.saveState()
# フォントを設定
pdf.setFont('GenShinGothic', 25)
#タイトルを設定
pdf.drawString(230,780,title)

計算式の作成

ここで1+1=のような文字列を作成する関数を作ります。適当な乱数と問番号(1)等を引数として受け取り (1)1+1= のような文字列を返します

#計算式を作る関数の定義
def generate_problem(a,b,n):
    s = "({})".format(n) + str(a) + " + " + str(b) + " = "
    return s

pdf出力

最後に、実際にpdfに書き出していきます。
問番号を保持する変数numを用意し、20問を2問ずつ2列で配置するために、2重forループを回します。

num = 1
#計算式を並べていく
for i in range(10):
    for j in range(2):
        seed1 = int(random.uniform(1, 20))
        seed2 = int(random.uniform(1, 20))
        prob = generate_problem(seed1,seed2,num)
        pdf.drawString(210*(j+1)-100,700-i*80,prob)
        num += 1
#図の保存
pdf.showPage()
pdf.save()

プログラム全体

import random
from reportlab.pdfgen import canvas
from reportlab.pdfbase.pdfmetrics import registerFont
from reportlab.pdfbase.ttfonts import TTFont
# フォントを登録
registerFont(TTFont('GenShinGothic',
                    './fonts/GenShinGothic-Monospace-Light.ttf'))
#ファイル名の設定
title = '計算テスト'
#pdfの下地を準備する
pdf = canvas.Canvas(title + '.pdf')
pdf.saveState()
# フォントを設定
pdf.setFont('GenShinGothic', 25)
#タイトルを設定
pdf.drawString(230,780,title)
#計算式を作る関数の定義
def generate_problem(a,b,n):
    s = "({})".format(n) + str(a) + " + " + str(b) + " = "
    return s
num = 1
#計算式を並べていく
for i in range(10):
    for j in range(2):
        seed1 = int(random.uniform(1, 20))
        seed2 = int(random.uniform(1, 20))
        prob = generate_problem(seed1,seed2,num)
        pdf.drawString(210*(j+1)-100,700-i*80,prob)
        num += 1
#図の保存
pdf.showPage()
pdf.save()

以上を実行すると、こんな感じのpdfファイルを作ることができます。

f:id:HirotoTakeda:20210204163544p:plain
計算ドリル
宣伝

ココナラでフリーのライターをやっています。
これまでに280件以上の受注実績があります。
大学入試の小論文、学生・社会人の方のレポートの作成・添削のご相談はこちらまで!
coconala.com