# 綜合練習 ## 一行程式碼可以做甚麼 ``` '\n'.join([''.join([('\x4c\x6f\x76\x65\u2665'[(x-y) % len('\x4c\x6f\x76\x65\u2665')] if ((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3 <= 0 else ' ') for x in range(-30, 30)])for y in range(30, -30, -1)]) ``` 讓使用者輸入字串後,變化愛心的內容: ``` import time user_input = input('請輸入想顯ˋ的字串: ') datas = user_input.split() # 以空白字元來切割字串並回傳一個list # print(datas) # datas = ['Hello ', 'world', 'I ', 'am ', 'Aaron ', 'test ', 'momo '] for i in datas: print('\n'.join([''.join([(i[(x-y) % len(i)] if ((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3 <= 0 else ' ') for x in range(-30, 30)])for y in range(30, -30, -1)])) time.sleep(1) ``` # Python GUI使用tkinter模組 ## BMI計算機 > tkinter為Python的一個內建模組 ### 建立一個空白視窗 ``` import tkinter as tk window = tk.Tk() # 建立一個視窗存到window變數 window.title('BMI app') window.geometry('640x480') window.configure(background='purple') # 改變視窗被景色(purple=紫色) window.mainloop() # 啟動視窗迴圈來等待使用者操作,必須放在最後一行 ``` ### 加上一個標籤(Label) ``` header_label = tk.Label(window, text='BMI計算機', font='微軟正黑體 30', bg='purple', fg='yellow') # 建立Label物件並存放到header_label變數, font=設定字型跟文字大小 header_label.pack(pady=10) # 將Label顯示出來,pady=上下的間距 ``` ### 加上輸入體重跟身高的標籤(Label)+輸入框(Entry) ``` # 建立體重輸入欄位跟提示訊息 weight_frame = tk.Frame(window, bg='purple') weight_frame.pack() weight_label = tk.Label(weight_frame, text='體重(kg)', font='微軟正黑體 20', bg='purple') weight_label.pack(side=tk.LEFT) weight_entry = tk.Entry(weight_frame, font='微軟正黑體 20', bg='purple') weight_entry.pack(side=tk.LEFT) # 建立身高輸入欄位跟提示訊息 height_frame = tk.Frame(window, bg='purple') height_frame.pack() height_label = tk.Label(height_frame, text='身高(cm)', font='微軟正黑體 20', bg='purple') height_label.pack(side=tk.LEFT) height_entry = tk.Entry(height_frame, font='微軟正黑體 20', bg='purple') height_entry.pack(side=tk.LEFT, pady=10) ``` > 我們使用Frame來包圍標籤(Label)跟輸入框(Entry) ### 建立顯示結果的Label ``` # 建立顯示結果的Label result_label = tk.Label(window, text='', font='微軟正黑體 20', bg='purple') result_label.pack() ``` ### 建立按鈕 ``` def calculate_bmi(): # tk.messagebox.showinfo('標題', '計算BMI') w = weight_entry.get() h = height_entry.get() result_label.configure(text='您輸入身高為{}公分, 體重為{}公斤'.format(h, w)) # 建立按鈕 calculate_btn = tk.Button(window, text='計算', font='微軟正黑體 20', command=calculate_bmi) calculate_btn.pack() ``` > 透過command參數,使用者在點擊按鈕後會觸發執行command設定的函示。 ### 完整程式碼 ``` # -*- coding: utf-8 -*- import tkinter as tk def calculate_bmi(): if height_entry.get() == '': tk.messagebox.showerror('錯誤', '身高欄位不能為空') return if weight_entry.get() == '': tk.messagebox.showerror('錯誤', '體重欄位不能為空') return w = float(weight_entry.get()) # 取得使用者輸入的體重 h = float(height_entry.get()) / 100 # 取得使用者輸入的身高並轉為公尺 if 0.2 > h or h > 2.5: tk.messagebox.showerror('錯誤', '身高需介於20~250公分之間') return if 5 > w or w > 200: tk.messagebox.showerror('錯誤', '體重需介於5~200公斤之間') return # BMI計算公式: BMI=體重/身高(公尺)的平方 bmi = round(w / (h ** 2), 2) # 或 int(w / (h ** 2) * 100) / 100 des = '' # 建議 if bmi < 18.5: des = '體重過輕' elif 24 <= bmi < 27: des = '有點過重, 該運動了' elif 27 <= bmi < 30: des = '輕度肥胖, 請多運動' elif 30 <= bmi < 35: des = '中度肥胖, 很需要運動' elif bmi >= 35: des = '重度肥胖, 呃~' else: des = '很標準' result_label.configure(text='您的BMI為{}, {}'.format(bmi, des)) window = tk.Tk() # 建立一個視窗存到window變數 window.title('BMI app') window.geometry('640x480') window.configure(background='purple') # 改變視窗被景色(purple=紫色) # t = '\n'.join([''.join([('\x4c\x6f\x76\x65\u2665'[(x-y) % len('\x4c\x6f\x76\x65\u2665')] if ((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3 <= 0 else ' ') for x in range(-30, 30)])for y in range(30, -30, -1)]) header_label = tk.Label(window, text='BMI計算機', font='微軟正黑體 30', bg='purple', fg='yellow') # 建立Label物件並存放到header_label變數, font=設定字型跟文字大小 header_label.pack(pady=10) # 將Label顯示出來,pady=上下的間距 # 建立身高輸入欄位跟提示訊息 height_frame = tk.Frame(window, bg='purple', width=500) height_frame.pack() height_label = tk.Label(height_frame, text='身高: ', font='微軟正黑體 20', bg='purple', fg='white') height_label.pack(side=tk.LEFT) height_entry = tk.Entry(height_frame, font='微軟正黑體 20', bg='purple', width=10) height_entry.pack(side=tk.LEFT, pady=10) height_label2 = tk.Label(height_frame, text='(cm)', font='Courier 20', bg='purple', fg='white') height_label2.pack(side=tk.LEFT) # 建立體重輸入欄位跟提示訊息 weight_frame = tk.Frame(window, bg='purple') weight_frame.pack() weight_label = tk.Label(weight_frame, text='體重: ', font='微軟正黑體 20', bg='purple', fg='white') weight_label.pack(side=tk.LEFT) weight_entry = tk.Entry(weight_frame, font='微軟正黑體 20', bg='purple', width=10) weight_entry.pack(side=tk.LEFT) weight_label2 = tk.Label(weight_frame, text='(kg)', font='Courier 20', bg='purple', fg='white') weight_label2.pack(side=tk.LEFT) # 建立顯示結果的Label result_label = tk.Label(window, text='', font='微軟正黑體 20', bg='purple', fg='pink') result_label.pack(pady=10) # 建立按鈕 calculate_btn = tk.Button(window, text='計算', font='微軟正黑體 20', bg='pink', command=calculate_bmi) calculate_btn.pack(side=tk.BOTTOM, pady=10) window.mainloop() # 啟動視窗迴圈來等待使用者操作,必須放在最後一行 ``` ### 參考資料 - [Tkinter較完整的網路教學](https://www.itread01.com/content/1547705544.html) - [BMI介紹](https://health99.hpa.gov.tw/OnlinkHealth/Onlink_BMI.aspx) ## 猜拳遊戲 ``` import tkinter as tk from PIL import Image, ImageTk import random SCISSORS = 0 ROCK = 1 PAPER = 2 # 玩家出了剪刀 def scissors(): pc = random.randint(0, 2) # 電腦出拳 # 先將電腦出拳顯示在畫面上給玩家看 if pc == SCISSORS: pc_label.configure(text='電腦出了: 剪刀') elif pc == ROCK: pc_label.configure(text='電腦出了: 石頭') else: pc_label.configure(text='電腦出了: 布') # 比輸贏 if pc == SCISSORS: result_label.configure(text='遊戲結果: 平手') elif pc == ROCK: result_label.configure(text='遊戲結果: 你輸了') else: result_label.configure(text='遊戲結果: 你贏了') # 玩家出了石頭 def rock(): pc = random.randint(0, 2) # 電腦出拳 # 先將電腦出拳顯示在畫面上給玩家看 if pc == SCISSORS: pc_label.configure(text='電腦出了: 剪刀') elif pc == ROCK: pc_label.configure(text='電腦出了: 石頭') else: pc_label.configure(text='電腦出了: 布') # 比輸贏 if pc == SCISSORS: result_label.configure(text='遊戲結果: 你贏了') elif pc == ROCK: result_label.configure(text='遊戲結果: 平手') else: result_label.configure(text='遊戲結果: 你輸了') # 玩家出了布 def paper(): pc = random.randint(0, 2) # 電腦出拳 # 先將電腦出拳顯示在畫面上給玩家看 if pc == SCISSORS: pc_label.configure(text='電腦出了: 剪刀') elif pc == ROCK: pc_label.configure(text='電腦出了: 石頭') else: pc_label.configure(text='電腦出了: 布') # 比輸贏 if pc == SCISSORS: result_label.configure(text='遊戲結果: 你輸了') elif pc == ROCK: result_label.configure(text='遊戲結果: 你贏了') else: result_label.configure(text='遊戲結果: 平手') window = tk.Tk() # 建立一個視窗存到window變數 window.title('猜拳遊戲') window.geometry('640x480') window.configure(bg='dark red') # 改變視窗被景色(purple=紫色) title = tk.Label(window, text='猜拳遊戲', font='微軟正黑體 30', fg='white', bg='dark red') title.pack(pady=10) frame = tk.Frame(window, bg='dark red') frame.pack(pady=10) # 載入遊戲圖片 img_scissors = Image.open('剪刀.jpg') # 開啟並載入圖片檔 photo_scissors = ImageTk.PhotoImage(img_scissors) # 解碼jpg檔 img_rock = Image.open('石頭.jpg') # 開啟並載入圖片檔 photo_rock = ImageTk.PhotoImage(img_rock) # 解碼jpg檔 img_paper = Image.open('布.jpg') # 開啟並載入圖片檔 photo_paper = ImageTk.PhotoImage(img_paper) # 解碼jpg檔 scissors_btn = tk.Button(frame, text='剪刀', image=photo_scissors, bg='dark red', command=scissors) scissors_btn.pack(side=tk.LEFT, padx=10) rock_btn = tk.Button(frame, text='石頭', image=photo_rock, bg='dark red', command=rock) rock_btn.pack(side=tk.LEFT, padx=10) paper_btn = tk.Button(frame, text='布', image=photo_paper, bg='dark red', command=paper) paper_btn.pack(side=tk.LEFT, padx=10) # 顯示遊戲提示Label prompt_label = tk.Label(window, font='微軟正黑體 20', text='請點擊按鈕來遊玩', fg='yellow', bg='dark red') prompt_label.pack(pady=15) # 顯示電腦出了甚麼Label pc_label = tk.Label(window, font='微軟正黑體 30', fg='white', bg='dark red') pc_label.pack(pady=15) # 顯示遊戲結果Label result_label = tk.Label(window, font='微軟正黑體 30', fg='white', bg='dark red') result_label.pack(pady=15) window.mainloop() ``` ![](https://i.imgur.com/5Add4FU.jpg) ![](https://i.imgur.com/OOPTAC4.jpg) ![](https://i.imgur.com/64rKUdc.jpg)