tkinterで電卓いじってみた

#まず初めに
僕がpythonでプログラミングを学んでいった上で、1番好きだったのが**tkinterを用いたボタン処理**だった。そのボタン処理をたくさんできるのは何かと考えた時に1番に出てきたのが電卓だった。
___

#要点

##Window表示
```ruby:final_python.py
from tkinter import *

#Window作成
root = Tk()
#Windowサイズ指定
root.geometry("500x500")
#Windowタイトル作成
root.title("四則演算機")
#決まり文句
root.mainloop()
```

もしWindowのサイズが小さければ、かなり見にくい電卓となってしまう,,,
ついでに電卓そのものの大きさをいじってより見やすくした

```ruby:final_python.py
 b = Button(root, text=label, command=func, width=10, height=5)
```

widthとheightをいじってやることで簡単に変えることができる！

___
##CとACの機能
```ruby:final_python.py
#Cの機能
def clear():
    textVal = expression.get()
    
    if len(textVal) > 1:
        expression.set(textVal[:-1])
    
    else:
        expression.set("")

#ACの機能
def all_clear():
    expression.set("")
```

- CとACの役割

| C | 一文字ずつ消去|
|:-:|:-:|
|  AC |全文字消去   |

___
##ボタン配置

###めんどくさいボタン配置例

```ruby:final_python.py
#１列目
btn_p = Button(root, text="%", command=lambda: func("%"), width=5, height=2)
btn_p.grid(row=1, column=2)
btn_add = Button(root, text="+", command=lambda: func("+"), width=5, height=2)
btn_add.grid(row=1, column=3)

#２列目
btn_7 = Button(root, text="7", command=lambda: func("7"), width=5, height=2)
btn_7.grid(row=2, column=0)
btn_8 = Button(root, text="8", command=lambda: func("8"), width=5, height=2)
btn_8.grid(row=2, column=1)
btn_9 = Button(root, text="9", command=lambda: func("9"), width=5, height=2)
btn_9.grid(row=2, column=2)
btn_div = Button(root, text="/", command=lambda: func("/"), width=5, height=2)
btn_div.grid(row=2, column=3)

#３列目
btn_4 = Button(root, text="4", command=lambda: func("4"), width=5, height=2)
btn_4.grid(row=3, column=0)
btn_5 = Button(root, text="5", command=lambda: func("5"), width=5, height=2)
btn_5.grid(row=3, column=1)
btn_6 = Button(root, text="6", command=lambda: func("6"), width=5, height=2)
btn_6.grid(row=3, column=2)
btn_mul = Button(root, text="*", command=lambda: func("*"), width=5, height=2)
btn_mul.grid(row=3, column=3)

#４列目
btn_1 = Button(root, text="1", command=lambda: func("1"), width=5, height=2)
btn_1.grid(row=4, column=0)
btn_2 = Button(root, text="2", command=lambda: func("2"), width=5, height=2)
btn_2.grid(row=4, column=1)
btn_3 = Button(root, text="3", command=lambda: func("3"), width=5, height=2)
btn_3.grid(row=4, column=2)
btn_sub = Button(root, text="-", command=lambda: func("-"), width=5, height=2)
btn_sub.grid(row=4, column=3)

#５列目
btn_0 = Button(root, text="0", command=lambda: func("0"), width=5, height=2)
btn_0.grid(row=5, column=0)
btn_pt = Button(root, text=".", command=lambda: func("."), width=5, height=2)
btn_pt.grid(row=5, column=2)
```

1,2列くらいだとまだ大丈夫だが、5列となるとかなりキツい,,,

###かなりラクなボタン配置例
```ruby:final_python.py

buttons = (
    (("C", clear   ), ("AC", all_clear), ("%", op("%") ), ("+", op("+"))),
    (("7", digit(7)), ("8",  digit(8) ), ("9", digit(9)), ("/", op("/"))),
    (("4", digit(4)), ("5",  digit(5) ), ("6", digit(6)), ("*", op("*"))),
    (("1", digit(1)), ("2",  digit(2) ), ("3", digit(3)), ("-", op("-"))),
    (("0", digit(1)), (None, None     ), ('.', op('.') ), ("=", calculate)),
)
```
※一列一列ボタンを並べるよりも**配列**にしたほうがだいぶラクらしい
___
#完成形
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638188/fc87425f-e797-e06b-7125-dfdbf9ed248b.gif)


___

#お詫び
今回最終課題の発表ということで、全部の機能を説明したかったが、一人の持ち時間が2分と限られているので、2分以内に収められるよう要点を絞った。
最後にソースコードが貼ってあるので、それを見ておいて欲しいです、、、

#ソースコード
```ruby:final_python.py
# coding:utf-8
from tkinter import *

#Window表示
root = Tk()
#Windowサイズ指定
root.geometry("500x500")
#Windowタイトル作成
root.title("四則演算機")

expression = StringVar()

#Cの機能
def clear():
    textVal = expression.get()
    
    if len(textVal) > 1:
        expression.set(textVal[:-1])
    
    else:
        expression.set("")

#ACの機能
def all_clear():
    expression.set("")

#数字ボタン
def digit(number):
    def func():
        expression.set(expression.get() + str(number))
    return func

#演算ボタン
def op(label):
    def func():
        expression.set(expression.get() + label)
    return func

#=の機能
def calculate():
    try:
        expression.set(eval(expression.get()))
    except SyntaxError:
        expression.set("SyntaxError")
    except ZeroDivisionError:
        expression.set("ZeroDivisionError")
    except NameError:
        expression.set("NameError")

buttons = (
    (("C", clear   ), ("AC", all_clear), ("%", op("%") ), ("+", op("+"))),
    (("7", digit(7)), ("8",  digit(8) ), ("9", digit(9)), ("/", op("/"))),
    (("4", digit(4)), ("5",  digit(5) ), ("6", digit(6)), ("*", op("*"))),
    (("1", digit(1)), ("2",  digit(2) ), ("3", digit(3)), ("-", op("-"))),
    (("0", digit(1)), (None, None     ), ('.', op('.') ), ("=", calculate)),
)

#表示画面
e = Label(root, textvariable=expression, fg="#ffffff", bg="#000000", anchor=E, height=2)
e.grid(row=0, column=0, columnspan=4, sticky="EW")

for row, btns in enumerate(buttons, 1):
    for col, (label, func) in enumerate(btns):
        if label:
            b = Button(root, text=label, command=func, width=10, height=5)
            b.grid(row=row, column=col)

#決まり文句
root.mainloop()
```
___
#感想
ほぼほぼソースコードは[Tkinterで作る電卓](https://qiita.com/FangJoker7714/items/59bd7c9c1dea016683b2)を参考にさせてもらったが、Windowの幅だったり、電卓そのものの大きさ、Cの機能など改善すべき部分はあったので、そこは自分の力で出来たので良かった。
また、それぞれの命令の意味も理解することができて良かった。
夏休みはプログラミングに力を入れていきたい。

#参考文献

- いちばんやさしいpython入門教室　大澤文孝[著]

- [Tkinterで作る電卓](https://qiita.com/FangJoker7714/items/59bd7c9c1dea016683b2)