Pythonで電卓アプリを作ってみよう

先日、Windows 10標準の電卓アプリがオープンソースで公開されて話題となった。筆者も気になってソースコードを覗いてみた。電卓は実用的なアプリである上に、それほど難しいわけではないので、実際に作ってみると、プログラミング技術のレベルアップに役立つ好例だ。それでは本連載でも電卓を作ってみよう。

(記事) Microsoft、電卓アプリをオープンソースで公開
  • 今回作る電卓アプリ

    今回作る電卓アプリ

電卓の挙動を観察してみよう

電卓を作るにあたって、どんな電卓を作るか考えてみよう。オープンソースになったWindows 10の電卓では、現実の電卓に近い動作をする設計になっている。それに対して、Androidに付属している電卓では「1 + 2 × 3」と入力して「=」ボタンを押すと、かけ算が優先されて計算されるので、7と答えが表示される。Windows 10で同じようにボタンを押してみると、1 + 2 の後、[×]ボタンを押した時点で、1 + 2が計算され、3が表示され、結果として、9が表示される。

  • Windows 10の電卓

    Windows 10の電卓

  • Androidの電卓

    Androidの電卓

これは、電卓の設計思想が違うだけで、どちらも正しいと言える。Androidの電卓では、入力欄に連続して計算式が入力できるようになっており計算式が計算された結果が表示される。それに対して、Windowsの電卓では逐次計算が行われるので、Windows 10の電卓もこれで正しいと言える。

今回は、Androidの電卓のように、計算式が入力できるタイプの電卓を作ってみよう。

eval関数を使えば計算も簡単

それで、自分用のオリジナル電卓を作るのに際して、一番簡単な解決策がある。それは、文字列で書かれたPythonのプログラムを実行できるevalという関数を使うことだ。

evalを使った簡単なプログラムを見てみよう。

res = eval('1 + 2 * 3')
print(res)

プログラムを実行するには、上記のプログラムを「test-eval.py」という名前で保存し、コマンドラインから「python test-eval.py」のように実行する。すると、7が表示される。

Tkinterで電卓の外観を作ろう

あとは、電卓の体裁を作れば電卓は完成する。前回、Tkinterの基本的な使い方を紹介したので、今回はその応用編とも言える。それでは、Tkinterライブラリを使ってボタンを配置した電卓を作ってみよう。

以下は電卓のプログラムだ。

import tkinter as tk
# ボタンの配置を定義 --- (*1)
BUTTONS = [
  ['7', '8', '9', '/'],
  ['4', '5', '6', '*'],
  ['1', '2', '3', '-'],
  ['0', '.', '=', '+']
]

# ボタンイベントの作成関数 --- (*2)
def make_click(ch):
    def click(e):
        print(ch)
        if ch == '=': calc(0); return
        else: disp.insert(tk.END, ch)
    return click

# 計算式を計算 --- (*3)
def calc(e):
    label["text"] = '= ' + str(eval(disp.get()))

# ウィンドウを作成 --- (*4)
win = tk.Tk()
win.title("自作の電卓")
win.geometry("400x400")
# ディスプレイ部分 --- (*5)
disp = tk.Entry(win, font=('', 20), justify="center")
disp.pack(fill='x')
disp.bind('<Return>', calc)
label = tk.Label(win, font=('', 20), anchor="center")
label.pack(fill='x')
# 電卓のボタンを一括作成 --- (*6)
fr = tk.Frame(win)
fr.pack()
for y, cols in enumerate(BUTTONS):
    for x, n in enumerate(cols):
        btn = tk.Button(fr, text=n,
            font=('', 20), width=6, height=3)
        btn.grid(row=y+1, column=x+1)
        btn.bind('<1>', make_click(n))

# ウィンドウを動かす --- (*7)
win.mainloop()

上記のプログラムを「calc.py」という名前で保存しよう。以下のコマンドを実行するとプログラムが実行される。

python calc.py

実行すると、電卓が表示される。計算式を入力して「=」ボタンを押すか、Enterキーを押すと計算結果がテキストボックスに表示される。

  • 電卓プログラムを実行し計算したところ

    電卓プログラムを実行し計算したところ

プログラムを確認してみよう。(*1)の部分では電卓のウィンドウに配置するボタンを定義する。この部分の配置を変更すると、電卓のボタンをカスタマイズできる。

次の(*2)の部分では、ボタンを押した時のイベントを記述する。ここではボタンに応じた処理を実行する関数を生成している。「=」ボタンであれば計算処理を実行するように、その他のボタンであれば、テキストボックスに文字を追加する。そして(*3)では、計算式をeval関数で計算し、結果をラベルに表示する関数calcを定義する。

そして、(*4)からの部分ではテキストボックスやラベルやボタンを作成する。特に(*4)ではウィンドウを、(*5)ではディスプレイ部分を、(*6)では電卓のボタンを一括作成する。for構文を利用して、繰り返しボタンを生成していく。そして、最後、(*7)でメインループを呼び出し、ウィンドウが動作するようにする。

まとめ

以上、Pythonで電卓アプリを作ってみた。Tkinterを使うプログラムは行数が長くなりがちだが、40行未満で電卓ができた。計算式をeval関数で計算するだけだが、それなりに電卓らしいものになった。

ただし、少し使っていると、改良したい点がたくさん見つかるだろう。計算式をクリアする[C]ボタンとか、バックボタンとか、すぐに機能追加したい点がいくつかある。それほど難しくないので、自分で改良してみると良いだろう。

自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2005年IPAスーパークリエイター認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。