はじめに
小学校低学年向けの自習用プリントを作るために、計算ドリル生成プログラムを作りました。pythonでランダムに数式を作って、A4用紙サイズでpdf化します。作成したファイルを自宅かコンビニなどで印刷して、子供が自習してくれれば目的達成です。
環境
- Ubuntu 18.04[Windows10上でWSL(Windows Subsystem for Linux)使用]
- python3.6
ReportLabのインストール
生成した計算式を印刷するために、pdf化用のライブラリ・ReportLabを使用します。
$ sudo pip3 install ReportLab
ReportLabに関する詳細なドキュメントは下記です。
https://www.reportlab.com/docs/reportlab-userguide.pdf
出力イメージ
pdf出力用関数 drawStringとlineの使い方
今回のプリント作成は主にdrawString()とline()の2つの関数を使って実現します。プログラム本体に入る前に、基本的な使い方だけまとめておきます。
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.pagesizes import A4
# Canvasを作成。ファイル名とサイズを指定
c = canvas.Canvas("calc_train.pdf",pagesize=A4)
# 出力座標を設定
x=0
y=0
# "hoge"という文字列を座標(0,0)に書き出し
c.drawString(x,y,"hoge")
# 直線を描画
c.line(x,y,x+10,y)
# pdf1ページを生成
c.showPage()
# ファイルを保存
c.save()
ReportLabの座標はページの"左下"が原点になっています。
計算ドリル自動生成プログラム
下記が、今回の目的であるReportLabを使った計算ドリル自動生成プログラムです。
import os, sys
import random
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.pagesizes import A4
# 5x5の計算式の基本座標
x_list = [20, 130, 240, 350, 460]
y_list = [730, 580, 430, 280, 130]
# フォントを指定することも可能です
fontname = "Helvetica"
# 日本語を出力させる場合、下記のように設定します。
# パスはご自身の環境を参照ください。
#pdfmetrics.registerFont(TTFont(fontname,"/mnt/c/Windows/Fonts/msgothic.ttc"))
# 計算式1個を指定した座標に出力する関数
# 想定している計算は各要素が2桁以下です。
def Set_calc(c,x,y,ope,d1,d2):
# c: canvas
# x, y : 座標
# ope : 数学記号の文字列
offset = 30
_d1 = str(d1)
_d2 = str(d2)
# 文字幅の調整
if(d1<10):
_d1 = " " + _d1
if(d2<10):
_d2 = " " + _d2
c.drawString(x+offset, y, _d1)
c.drawString(x, y-offset, ope)
c.drawString(x+offset, y-offset, _d2)
c.line(x,y-offset-5,x+offset*2.5,y-offset-5)
# 1ページ分の計算式を生成する関数
def Make_page(c,ope,d1_max,d2_max):
# c: canvas
# ope : 数学記号の文字列
# d1_max, d2_max : 計算する値の最大値設定
c.setFont(fontname,20)
# ヘッダー部分の文字列出力
c.drawString(5,800, " Name: Day: / ")
c.setFont(fontname,30)
# Set Value
for row in y_list:
for col in x_list:
# 設定された最大値の中でランダムに要素を生成
d1 = random.randint(1, d1_max)
d2 = random.randint(1, d2_max)
# 加算の場合
if(ope=="+"):
Set_calc(c,col,row,"+ ",d1,d2)
# 減算の場合
elif(ope=="-"):
# 負の値は扱わない
if(d1<d2):
tmp=d1
d1=d2
d2=tmp
Set_calc(c,col,row,"- ",d1,d2)
# 乗算の場合
elif(ope=="x"):
Set_calc(c,col,row,"× ",d1,d2)
else:
print("[Error] Not support operation:",ope)
c.showPage()
# 以下メイン関数
print(" >>> Start")
c = canvas.Canvas("calc_train.pdf",pagesize=A4)
# 足し算 (各要素の最大値:99)
Make_page(c,"+",99,99)
# 引き算 (要素の最大値:99と9)
Make_page(c,"-",99,9)
# 引き算 2 (各要素の最大値:99)
Make_page(c,"-",99,99)
# 掛け算 (要素の最大値:99と9)
Make_page(c,"x",99,9)
c.save()
print(" >>> Finish")
上記サンプルを実行すると、A4サイズ用紙に5x5個の計算式が出力されます。お子さんの学年に応じて計算範囲を修正、1枚当たりの計算式数を調整して使ってみてください。
以上です。お疲れ様でした。