step05 課題レポート1:電卓を作ろう

ここまでの講座で、

など、自分でGUIプログラミングをやるための基礎知識は身についた(はずだ)。
このstepでは、【応用編】の折り返し点として、ボタンとエントリーを用いた、簡単な電卓プログラムを作る。電卓を題材に選んだのは典型的なイベント駆動のアルゴリズムだからである。電卓の動作は、 という、とても明快な構造を持っている。
とはいえ、本格的電卓を一挙にプログラムするのは敷居が高いだろうから、いくつかのレベルに分けて、徐々に実装してゆく。どのレベルまで到達できるかは、皆さんの現状での理解度と今後の努力しだいである。

電卓の動作を知る

まず、各自、持って来た電卓をいじって、動作を観察しよう。PCやスマホの電卓でも悪くはないけれど、できればここは、安物でもいいから本物の電卓でありたい。テキストファイルか紙に、メモを取りながら観察すると、理解がはやいだろう。
普段見慣れた(気になっている)電卓だが、それぞれのキーを押したどきの動作、つまり各キーの役割を正確に把握していた人は、意外に少ないのではないだろうか? たとえば、「+キーは何をするキーですか?」と聞くと、たいていの人は「足し算をします」と答えるのだが、それは間違っている。+キーは足し算をしない。より正確にいえば、+キーが押された時には、電卓はまだ足し算をやれるだけのデータを持っていないのである。では、+キーは何をするのか? 足し算をするのは誰か? 電卓をじっくり観察しているうちに、正解は自ずと分かるだろう。
観察のポイント:

1 本物の電卓では、これらのデータはLSIチップ中のレジスタという記憶装置に格納されるが、プログラムではもちろん変数に格納する。

モックアップ電卓(Level0)

図5-1に起動時の画面を示す。

図5-1: モックアップ電卓(Level0)

モックアップの名前通り、いかにもちゃんと動きそうだが、まだ何もできない。ケータイ屋に並んでいるスマホのモックアップと同じ。「1」のキーを押しても「1」の表示がでない。それも当然で、tkinterのエントリーとボタンを、grid方式でそれらしく配置しただけなのである。すべての動作は、これから実装するボタンのイベントハンドラにかかっている。
この段階であまり手間取っても学習時間のムダだから、このレベルのプログラムは、リスト5-1に公開する。より高いレベルの電卓をプログラムする際のテンプレート(ひな形)に使ってほしい。


リスト5-1: モックアップ電卓(Level0) dentaku0.pyw

前stepで、ボタンやエントリーを含むウィジェットの使用法はみっちりと学んだので、読むのに苦労はいらないだろうが、初出の部分を含めて簡単に解説する。
電卓ウィンドウ(アプリ)のための電卓クラスを設けた。作成(初期化)メソッドでは、以下の手順で電卓の見た目を作っている。

  1. トップレベルのフレームを作り、余白を設定する。
  2. 電卓のボタン(キー)の定義を、リストButtonDefとしてまとめておく。各要素は、(ボタンを置くcolumn, row, キートップのラベル, イベントハンドラ関数)という4つ組のタプルだ。
  3. ButtonDefをなぞりながら、(トップレベルフレームの)gridのマス目に、ボタンを配置してゆく。各マス目にボタンが上下左右一杯になるよう指定している(sticky = tk.N +tk.E + tk.S + tk.W)。
  4. gridの0行目に左右4列ぶち抜きで、数字が表示されるエントリーを配置する。
  5. ボタンとエントリーのフォント設定の文法については、リファレンスマニュアルの107ページ 27.3.Resource specification linesを参照のこと。

整数電卓(Level1)

図5-2に起動時の画面を示す。図5-1のモックアップ電卓と、見た目は何も変わらないが、この電卓は整数に限ればどんな計算でもできる。

図5-2: 整数電卓(Level1)

整数の四則演算だけができる電卓を作る。実装するボタン(キー)は以下の通り。各キーの役割(ふるまい)を、よく考えよう。

計算機能を各ボタンのイベントハンドラとして実装するには、どうしたらよいか。イベントハンドラは、ボタン毎にすべて別々に書かなくてもよい。動作の似たものは共通化できる。ただしその際、どのボタンから呼ばれたかをハンドラ側で知る手段がなくてはならない。

小数計算付き電卓(Level2)

いわゆる普通の電卓である。図5-3に起動時の画面を示す。図5-2に示した整数電卓と、見た目上の違いは「.(小数点)」キーが増えただけだ。

図5-3: 小数計算付き電卓(Level2)

つまり、小数点キーの役割を考え、イベントハンドラとしてプログラムすればいいだけなのだが、これが中々難しい。実物の電卓を観察すると、小数点ボタンを押す前と押した後では電卓の動作が違うことがわかる。つまり、動作に2種類のモードがあるのだ。ここでは仮に、

と呼ぼう。それぞれのモードでの動作を、さらに細かく観察すると、以下のようである。
整数モード
入力した数字は常に「1」の位に入力される。それ以前に入力されていた数は、1桁繰り上がる。
小数モード
入力した数字は、それ以前に入力されていた数の1桁右(つまり1/10)の位に入る。以後順々に、入力される位が右に移動する。
小数点キーの役割は、このモードの切り替えにあるらしい。
また、小数モードから整数モードに戻ることも、計算結果によっては起こりうる。参考に示したモックアップ電卓のプログラムで、計算結果を表すエントリーに、あえてコントロール変数を割り当てていないのも、この辺の事情と関係するのだ。

多機能電卓(Level3)

図5-4に起動時の画面を示す。さまざまなキーが追加され、実物の電卓と同等かそれ以上の機能を備えている。

図5-4: 多機能電卓(Level3)

Level1、Level2の電卓が完成した人は、さらにさまざまなボタンを追加して、その機能をプログラムしてみよう。追加するキーの種類は、各自の自由とするが、たとえば、

などである。

2 これらのキーの役割は、講師にとって長年の謎だったが、この講座で電卓を作って、ようやく理解できた。なにこれ便利!


各自、できるレベルまででよいから(もちろんLevel0では不可)、完成したプログラムを提出すること。
以上、100~200行のpythonプログラムを書くだけで、電卓の機能が実現できることがわかった。将来的には、自分の仕事専用電卓を自分で作って使うこともできるだろう。たとえば、 などなど、発想は無限にできる。自分で簡単なプログラミングができるメリットは、ここにこそあるのだ。