計算カードをPythonで自作|子供のズル対策アプリ(Tkinter)

/ 更新

スポンサーリンク

うちの小学1年生の子の宿題に「計算カード」があります。学校からは「時間を計ってやりなさい」と言われているようです。

ところが、もちろん計算なんかせず、どれだけ早くめくれるかが目的になってしまっていました。まあ、そうなりますよね。妻が我慢できないようだったので、PythonのTkinterで計算カードのアプリを作ってみました。

結論から言うと、ボタンで答えを選ばないと次に進めないようにしたら、めくるだけのズルはできなくなりました。

要点

  • くり下がりのない1けたの引き算(答えがマイナスにならない55通り)をランダムに出します
  • 0〜9のボタンで答えを選び、正解か不正解かを表示します
  • 最後に、かかった時間、点数(正解率)、間違えた問題を表示します
  • 続編で、あまりのある割り算のアプリも作り、ダブルクリックで動くexeにしました

引き算の計算カードアプリ

作ったもの

  • くり下がりのない1けたの引き算
  • 答えがマイナスにならない組み合わせだけ(55通り)
  • ランダムに出題
  • 最後に、かかった時間、点数(正解率)、間違えた問題を表示

コード

import tkinter as tk
from tkinter import messagebox
from functools import partial
import numpy as np
import time

root = tk.Tk()
root.attributes("-topmost", True)
messagebox.showinfo('', 'はじめ!')
root.destroy()

q1=[0,1,2,3,4,5,6,7,8,9]
q2=[0,1,2,3,4,5,6,7,8,9]
q1=np.array(q1)
q2=np.array(q2)
ran=[]
for i in q1:
    for ii in q2:
        if i-ii>=0:
            ran.append([i,ii])
ran=np.array(ran)
p=np.random.permutation(int(len(ran)))#シャッフル
ran=ran[p]

seikai=0
hazure=[]

def ans(a,i,ii):
    b=i-ii
    if a==b:
        messagebox.showinfo('', 'せいかい!')
        global seikai
        seikai+=1
        win.destroy()
    else:
        messagebox.showinfo('', 'ざんねん せいかいは{}です'.format(b))
        global hazure
        hazure.append(['{0}-{1}'.format(i,ii)])
        win.destroy()

def but(i,ii):
    global win
    win=tk.Tk()
    win.attributes("-topmost", True)#常に画面の最前に表示
    win.title('ひきざんチャレンジ!')
    win.geometry('500x350+100+200')
    label=tk.Label(text='{0}-{1} ='.format(i,ii),font=("",30))
    label.pack()
    for n in range(10):
        button=tk.Button(win,text='{}'.format(n),command=partial(ans,n,i,ii),width=10)
        button.pack(fill = 'none', padx=10,side = 'top')
    win.mainloop()

start = time.time()
for i in ran:
    but(i[0],i[1])
stop =time.time()
result = stop -start
x=int(result)//60
y=int(result)%60

rp= tk.Tk()
rp.attributes("-topmost", True)
rp.geometry('300x600+100+50')
label0=tk.Label(text='{}ふん{}びょう'.format(x,y),font=("",30))
label0.pack()
label00=tk.Label(text='てんすう{}てん'.format(int(100*seikai/(seikai+len(hazure)))),font=("",30))
label00.pack()
if len(hazure)==0:
    label1=tk.Label(text='ぜんもんせいかい!',font=("",30))
    label1.pack()
else:
    label2=tk.Label(text='にがてなものは',font=("",30))
    label2.pack()
    for h in hazure:
        label3=tk.Label(text=h,font=("",20))
        label3.pack()
    label4=tk.Label(text='です、がんばりましょう!',font=("",20))
    label4.pack()
messagebox.showinfo('', 'おわり')
rp.destroy()

変数がかぶっていたりする汚いコードですが、とりあえず動きます。元のコードでは0〜9のボタンを1つずつ10回書いていましたが、ここでは for でまとめて短くしました。

動かしてみる

計算カードアプリのスタート画面

まず、OKボタンでスタートします。同時に、時間の計測も始まります。

計算カードアプリで正解のボタンを押したときの「せいかい!」の表示

正解のボタンを押すと「せいかい!」と出ます。OKボタンを押して次の問題に進みます。

計算カードアプリで間違えたときの「ざんねん」の表示

間違ったボタンを押すと、「ざんねん せいかいは〇です」と表示されます。

計算カードアプリの結果画面。かかった時間と点数と間違えた問題

最後まで解くと、かかった時間と正解率、間違えた問題が表示されます。「おわり」のボタンでおしまいです。

続編:あまりのある割り算アプリも作った

その後、小学3年生の娘に「あまりのある割り算の問題を出してほしい」と頼まれたので、同じTkinterで割り算のアプリも作りました。

作るときに決めた条件

  • 2けた÷1けたで、答え(商)は1けた、あまりは0以外
  • 子供が使えるように、ダブルクリックで動くexeにする
  • キーボードは使わず、マウスだけで答える

コード

元のコードには from functools import partial の1行が抜けていて、そのままだとエラーになります。下のコードでは足してあります。

import tkinter as tk
from tkinter import messagebox
from functools import partial
import time
import random

root = tk.Tk()
root.attributes("-topmost", True)
messagebox.showinfo('', 'はじめ!')
root.destroy()

q1,n,hazure,q2=[],[],[],[2,3,4,5,6,7,8,9]
ran,seikai,c=10,0,0
for i in range(10,100):
    q1.append(i)
for ii in q1:
    for iii in q2:
        if ii%iii!=0:
            if ii//iii<10:
                n.append([ii,iii])
random.shuffle(n)

def sub(nn,a,b):
    global c
    if c==0:
        global k
        k=nn
        c+=1
        global win
        win.destroy()
        but(a,b,st,nn)
    else:
        c=0
        kaito(a,b,k,nn)

def kaito(a,b,k,nn):
    if a//b==k:
        if a%b==nn:
            messagebox.showinfo('', 'せいかい!')
            global seikai
            seikai+=1
            global win
            win.destroy()
        else:
            msg(a,b)
    else:
        msg(a,b)

def msg(a,b):
    messagebox.showinfo('', 'ざんねん せいかいは{}あまり{}です'.format(a//b,a%b))
    global hazure
    hazure.append(['{0}÷{1}'.format(a,b)])
    global win
    win.destroy()

def but(a,b,f,sq):
    global win
    win=tk.Tk()
    win.attributes("-topmost", True)#常に画面の最前に表示
    win.title('あまりのあるわりざんチャレンジ!')
    win.geometry('800x350+100+200')
    label=tk.Label(text='{0}÷{1} ={3}あまり☆ \n※{2}にはいる数字のボタンを押そう'.format(a,b,f,sq),font=("",30))
    label.pack()
    for i in range(1,10):
        button=tk.Button(win,text='{}'.format(i),command=partial(sub,i,a,b),width=10)
        button.pack(fill = 'none', padx=10,side = 'top')
    win.mainloop()

sq,st='□','次に☆'
start = time.time()
for i in range(ran):
    but(n[i][0],n[i][1],sq,sq)
stop =time.time()
result = stop -start
x=int(result)//60
y=int(result)%60

rp= tk.Tk()
rp.attributes("-topmost", True)
rp.geometry('400x600+100+50')
label0=tk.Label(text='{}ふん{}びょう'.format(x,y),font=("",30))
label0.pack()
label00=tk.Label(text='てんすう{}てん'.format(int(100*seikai/(seikai+len(hazure)))),font=("",30))
label00.pack()
if len(hazure)==0:
    label1=tk.Label(text='ぜんもんせいかい!',font=("",30))
    label1.pack()
else:
    label2=tk.Label(text='にがてなものは',font=("",30))
    label2.pack()
    for h in hazure:
        label3=tk.Label(text=h,font=("",20))
        label3.pack()
    label4=tk.Label(text='です、がんばりましょう!',font=("",20))
    label4.pack()
messagebox.showinfo('', 'おわり')
rp.destroy()

動かしてみる

あまりのある割り算アプリの問題画面

あまりのある割り算アプリの結果画面

OKを押すと時間の計測が始まり、問題が出ます。まず□に入る数字(商)を選び、次にあまりの数を選ぶと、正解か不正解かが表示されます。10問終わると、かかった時間と間違えた問題が出ます。

exeにしてダブルクリックで動かす

子供がダブルクリックだけで使えるように、実行ファイル(exe)にしました。コマンドプロンプトで「pyinstaller ファイル名」を実行するだけで変換できます。

できあがった「dist」フォルダの中にexeがあるので、それをダブルクリックすれば動きます。場所を移すときは、「dist」フォルダごと動かしてください。exeだけを移すと動かなくなります。

うまくいかなかったこと

娘には「使いにくい」と言われました。一度選んだ答えを取り消せないなど、直したいところはたくさんあります。それでも、宿題の自主勉強には使ってくれているので良しとしています。すぐに使わなくなりそうなので、これ以上は時間をかけていません。

まとめ

  • 計算カードをめくるだけのズルは、ボタンで答えないと進めないアプリにしたらできなくなりました
  • 引き算は55通りをランダムに出し、時間と点数と間違えた問題を表示します
  • あまりのある割り算アプリも作り、pyinstallerでexeにしました
  • 子供からは「使いにくい」とも言われたので、答えを取り消せるようにするのが次の課題です

Tkinterの基本は、Python Tkinter入門の記事にまとめています。

スポンサーリンク

関連記事