だぶるばいせっぷす 新館

ホワイトカラーではないブルーカラーからの視点

【プログラミング】 python奮闘記 その18 ~重複部分をまとめる

広告

無駄な部分を手直し

前回で、ようやく、思っていたとおりのツールが出来上がりました。
kimniy8.hatenablog.com
ただ、前回のコードを見直すと、結構、無駄な部分があったりするんですよね。。
という事で今回は、もう少しだけ短くなるように書き直そうと思います。

素人目に見ても『無駄だなぁ』と思う部分は、この部分でしょうか。

        # 身のボール紙の価格
        if cardboard_a:
            c_p = cp[0]
            if radio1 == 0:
               p_p = pp[0][0]
            elif radio1 == 1:
               p_p = pp[0][1]
            elif radio1 == 2:               
               p_p = pp[0][2]
            elif radio1 == 3:
               p_p = pp[0][3]

        elif cardboard_b:
            c_p = cp[1]
            if radio1 == 0:
                p_p = pp[1][0]

if文の中にif文を入れて、条件を細かく絞っているわけですが、この部分、よく見ると、無駄なんですよね。
というのも、cp[0]の場合は、ppリストの最初に指定する1つ目のリストも[0]となり、ラジオボタンの選択によって得られる値と、ppリストの2つ目の数字が合致している。
それなら、わざわざif文の中にif文を書かなくても、2つの変数を利用するだけで、紙の価格であるppリストは呼び出せそうですし、もし呼び出せるのなら、ifの中のifは完全に無駄ということになります。

重複部分をまとめる

では、具体的にどんな感じにすれば、cpのリスト番号とラジオボタンの戻り値であるradio1を利用できるんでしょうか。
ここで生きてくるのが、代入の知識です。
変数というのは基本的に、何らかの値が代入された値なので、どんな名前がついていようと、その中身は『値』なんですよ。
ということは、ラジオボタンのアクションによる戻り値が格納されている『radio1』は、ラジオボタンのアクションによって数値が変わる変数である為、わざわざ、『radio1』の値が0と同じ時は、ppリストの2番目の数字は『0』なんて記述はしてくても言い。
直接pp[0][radio1]と、リスト番号を指定する際に、変数である『radio1』を打ち込んでやれば良いわけです。

このように、『リスト呼び出しに変数を利用』すれば、先程のコードはこんな感じで短縮できます。

        # 身のボール紙の価格
        if cardboard_a:
            c_p = cp[0]
            p_p = pp[0][radio1]
        elif cardboard_b:
            c_p = cp[1]
            p_p = pp[1][radio1]

ifの中のifが無くなったことで、かなりのダイエットが出来て随分と短くなりましたが、まだ、無駄な部分がありそうです。
というのも、cpの数字とppの1つ目のリストの呼出番号が同じなので、同じ数字を共有できるようにするだけで、p_p…の部分も削除できそうです。
ではどうすれば良いのかというと、先程の応用で、cpとppの1つ目のリスト呼出番号を変数に代入し、その変数を使い回せばよいだけです。
早速書いてみましょう。

        # 身のボール紙の価格
        if cardboard_a:
            c_p_v = 0
        elif cardboard_b:
            c_p_v = 1
        elif cardboard_c:
            c_p_v = 2
        elif cardboard_d:
            c_p_v = 3
           
        # 蓋のボール紙の価格
        if cardboard_a_f:
            c_p_f_v = 0
        elif cardboard_b_f:
            c_p_f_v = 1
        elif cardboard_c_f:
            c_p_f_v = 2
        elif cardboard_d_f:
            c_p_f_v = 3
        
        c_p = cp[c_p_v]
        c_p_f = cp[c_p_f_v]
        p_p = pp[c_p_v][radio1]
        p_p_f = pp_f[c_p_f_v][radio2]

新たにc_p_vといった変数を作り、それぞれの変数を使って価格リストから値を呼び出せるようにしてみました。
2つのコードの最終行を見てみると、書き直す前が244行だったのに対して、書き直した後は179行と、かなりのダイエットに成功しました。
全く同じ動作をするツールでも、変数をうまく使う事で、かなり効率的に書ける事がわかりますよね。

では、これで完璧なプログラムなのかというと…
実は全くそんなことは無かったりします。
というのも、今回の書き方は、その都度その都度で必要な変数を新たに作って対処していった為、最終的にはかなり適当な感じの変数の名付け方になっていました。

また、オブジェクト指向というのは、一つのオブジェクトに対して様々なデータを付加していく事で、より複雑なプログラムも簡単にかけるようになる言語だと思うのですが、今回、その強みを全く活かせていません。
次回は、この反省を活かした形で、同じソフトをもう一度作り直してみようと思います。


最終的なコード

import tkinter

# ウィンドウ作成
root = tkinter.Tk()
root.title("見積もり")

# テキスト表示
frame1 = tkinter.Frame(root)
heading = tkinter.Label(frame1, text="お見積り")
heading.pack()

# テキストボックス表示
frame2 = tkinter.Frame(root)
box_width = tkinter.Entry(frame2, width=10, bd=4)
box_width.grid(column=0,row=0, padx=5)

box_length = tkinter.Entry(frame2, width=10, bd=4)
box_length.grid(column=1,row=0, padx=5)

box_height = tkinter.Entry(frame2, width=10, bd=4)
box_height.grid(column=2,row=0, padx=5)

box_height_f = tkinter.Entry(frame2, width=10, bd=4)
box_height_f.grid(column=2,row=1, padx=5)
# ボタン表示
askbutton = tkinter.Button(frame2, text="見積開始")
askbutton.grid(column=3,row=0, padx=5)

# ラジオボタン 紙の選択
frame5 = tkinter.Frame(root)

radio1_val = tkinter.IntVar()
radio1_val.set(0)
paper_a = tkinter.Radiobutton(frame5, text = "紙【a】", variable = radio1_val, value = 0)
paper_a.pack(side = tkinter.LEFT)
paper_b = tkinter.Radiobutton(frame5, text = "紙【b】", variable = radio1_val, value = 1)
paper_b.pack(side = tkinter.LEFT)
paper_c = tkinter.Radiobutton(frame5, text = "紙【c】", variable = radio1_val, value = 2)
paper_c.pack(side = tkinter.LEFT)
paper_d = tkinter.Radiobutton(frame5, text = "紙【d】", variable = radio1_val, value = 3)
paper_d.pack(side = tkinter.LEFT)

frame6 = tkinter.Frame(root)
radio2_val = tkinter.IntVar()
radio2_val.set(0)
paper_a_f = tkinter.Radiobutton(frame6, text = "紙【a】", variable = radio2_val, value = 0)
paper_a_f.pack(side = tkinter.LEFT)
paper_b_f = tkinter.Radiobutton(frame6, text = "紙【b】", variable = radio2_val, value = 1)
paper_b_f.pack(side = tkinter.LEFT)
paper_c_f = tkinter.Radiobutton(frame6, text = "紙【c】", variable = radio2_val, value = 2)
paper_c_f.pack(side = tkinter.LEFT)
paper_d_f = tkinter.Radiobutton(frame6, text = "紙【d】", variable = radio2_val, value = 3)
paper_d_f.pack(side = tkinter.LEFT)


# 答え表示
frame3 = tkinter.Frame(root)
ans_titl = tkinter.Label(frame3, text="一箱あたりの価格(税抜き)")
ans_titl.pack(side = tkinter.LEFT)
answer = tkinter.Label(frame3, text="円")
answer.pack(side = tkinter.LEFT)

# 内訳表示
frame4 = tkinter.Frame(root)
b_areax = tkinter.Label(frame4, text="ボール紙の身の横幅")
b_areax.grid(column=0,row=0, padx=5)
b_areay = tkinter.Label(frame4, text="ボール紙の身の縦幅")
b_areay.grid(column=1,row=0, padx=5)

b_areax_f = tkinter.Label(frame4, text="ボール紙の蓋の横幅")
b_areax_f.grid(column=0,row=1, padx=5)
b_areay_f = tkinter.Label(frame4, text="ボール紙の蓋の縦幅")
b_areay_f.grid(column=1,row=1, padx=5)

cardboard = tkinter.Label(frame4, text="【身】ボール紙の価格")
cardboard.grid(column=0,row=2, padx=5)
cardboard_price = tkinter.Label(frame4)
cardboard_price.grid(column=1,row=2, padx=5)

cardboard_f = tkinter.Label(frame4, text="【蓋】ボール紙の価格")
cardboard_f.grid(column=0,row=3, padx=5)
cardboard_price_f = tkinter.Label(frame4)
cardboard_price_f.grid(column=1,row=3, padx=5)

paper = tkinter.Label(frame4, text="【身】の紙の価格")
paper.grid(column=0,row=4, padx=5)
paperprice = tkinter.Label(frame4)
paperprice.grid(column=1,row=4, padx=5)

paper_f = tkinter.Label(frame4, text="【蓋】の紙の価格")
paper_f.grid(column=0,row=5, padx=5)
paperprice_f = tkinter.Label(frame4)
paperprice_f.grid(column=1,row=5, padx=5)

# Frame配置
frame1.pack()
frame3.pack()
frame2.pack()
frame5.pack()
frame6.pack()
frame4.pack()
# ボール紙の大きさ
def ask_click():
    b_hi = int(box_height.get()) # 箱の高さ
    b_hi_f = int(box_height_f.get()) # 箱の高さ
    b_wid = int(box_width.get()) # 箱の幅
    b_long = int(box_length.get()) # 箱の長さ
    b_tate = b_long + b_hi*2 # ボール紙の長さ
    b_yoko = b_wid + b_hi*2 # ボール紙の幅
    b_tate_f = b_long + 5 + b_hi_f*2 # ボール紙の蓋の縦
    b_yoko_f = b_wid + 5 + b_hi_f*2 # ボール紙の蓋の横
    
    # ラジオボタンの値取得
    radio1 = radio1_val.get()
    radio2 = radio2_val.get()

    # 紙の価格 paper plice
    pp=[[50, 65, 60, 70],[70, 100, 90, 110],[100, 135, 120, 160],[160, 235, 220, 280]]
    pp_f=[[50, 65, 75, 90],[70, 100, 115, 140],[100, 135, 160, 200],[160, 235, 285, 360]]
    
    # ボール紙の価格 cardboard plice
    cp=[40, 50, 70, 100]

    # 身のボール紙の種類
    cardboard_a = max(b_tate, b_yoko) <= 232 and min(b_tate, b_yoko) <= 222
    cardboard_b = max(b_tate, b_yoko) <= 354 and min(b_tate, b_yoko) <= 323
    cardboard_c = max(b_tate, b_yoko) <= 505 and min(b_tate, b_yoko) <= 354
    cardboard_d = max(b_tate, b_yoko) <= 748 and min(b_tate, b_yoko) <= 505

    # 蓋のボール紙の種類
    cardboard_a_f = max(b_tate_f, b_yoko_f) <= 232 and min(b_tate_f, b_yoko_f) <= 222
    cardboard_b_f = max(b_tate_f, b_yoko_f) <= 354 and min(b_tate_f, b_yoko_f) <= 323
    cardboard_c_f = max(b_tate_f, b_yoko_f) <= 505 and min(b_tate_f, b_yoko_f) <= 354
    cardboard_d_f = max(b_tate_f, b_yoko_f) <= 748 and min(b_tate_f, b_yoko_f) <= 505
    
    # NG要項
    if b_hi > 100 or b_hi < 20 or b_wid < 70 or b_long < 70 \
       or not(max(b_tate, b_yoko) <= 600 or min(b_tate, b_yoko) <= 450):
        answer["text"] = "申し訳ございませんが、弊社の設備では製造できません"
        
    else:                
        b_areay["text"] = "身のボール紙の身の縦" + str(b_tate) + "mm"
        b_areax["text"] = "身のボール紙の身の横" + str(b_yoko) + "mm"
        b_areax_f["text"] = "身のボール紙の蓋の縦" + str(b_tate_f) + "mm"
        b_areay_f["text"] = "身のボール紙の蓋の横" + str(b_yoko_f) + "mm"

        # 身のボール紙の価格
        if cardboard_a:
            c_p_v = 0
        elif cardboard_b:
            c_p_v = 1
        elif cardboard_c:
            c_p_v = 2
        elif cardboard_d:
            c_p_v = 3
           
        # 蓋のボール紙の価格
        if cardboard_a_f:
            c_p_f_v = 0
        elif cardboard_b_f:
            c_p_f_v = 1
        elif cardboard_c_f:
            c_p_f_v = 2
        elif cardboard_d_f:
            c_p_f_v = 3
        
        c_p = cp[c_p_v]
        c_p_f = cp[c_p_f_v]
        p_p = pp[c_p_v][radio1]
        p_p_f = pp_f[c_p_f_v][radio2]

        cardboard_price["text"] = str(c_p) + "円"
        cardboard_price_f["text"] = str(c_p_f) + "円"
        paperprice["text"] = str(p_p) + "円"
        paperprice_f["text"] = str(p_p_f) + "円"
        answer["text"] =str(c_p + c_p_f + p_p + p_p_f) + "円"
askbutton["command"] = ask_click            
# メインループ
root.mainloop()