動動手
0. 先練練手,把我們的剛開始的那個猜數字小游戲加上界面吧?
1 import random 2 import easygui as g 3 4 g.msgbox("嗨,歡迎進入第一個界面小游戲^_^") 5 secret = random.randint(1,10) 6 7 msg = "不妨猜一下小甲魚現在心里想的是哪個數字(1~10):" 8 title = "數字小游戲" 9 guess = g.integerbox(msg, title, lowerbound=1, upperbound=10) 10 11 while True: 12 if guess == secret: 13 g.msgbox("我草,你是小甲魚心里的蛔蟲嗎?!") 14 g.msgbox("哼,猜中了也沒有獎勵!") 15 break 16 else: 17 if guess > secret: 18 g.msgbox("哥,大了大了~~~") 19 else: 20 g.msgbox("嘿,小了,小了~~~") 21 guess = g.integerbox(msg, title, lowerbound=1, upperbound=10) 22 23 g.msgbox("游戲結束,不玩啦^_^")
1. 實現一個用於登記用戶賬號信息的界面(如果是帶 * 號的必填項,要求一定要有輸入並且不能是空格)。
代碼:
1 # 實現一個用於登記用戶賬號信息的界面(如果是帶 * 號的必填項,要求一定要有輸入並且不能是空格) 2 import easygui as g 3 4 msg = "請填寫以下聯系方式" 5 title = "賬號中心" 6 #這邊創建的填入信息標題是空格開頭的 7 fieldNames = [" *用戶名", " *真實姓名", " 固定電話", " *手機號碼", " QQ", " *E-mail"] 8 fieldValues = [] 9 fieldValues = g.multenterbox(msg, title, fieldNames) 10 11 # 如果用戶輸入的值比選項少的話,則返回列表中的值用空字符串填充用戶為輸入的選項。 所以將box返回的值收集在一個列表里 12 13 # 如果用戶取消操作,則返回域中的列表的值或者 None 值 14 15 #效果圖上的提示是填入不符后才顯示出來的 16 print(fieldValues) 17 while 1: 18 if fieldValues == None: 19 break 20 #fieldValues初始是空列表,你啥都沒填,按下OK后,fieldValues也是有值的,返回的是6個'' 21 # 所以這個條件是判斷在輸入框中最后你單擊的是確定還是取消 22 errmsg = "" 23 for i in range(len(fieldNames)): 24 option = fieldNames[i].strip() 25 if fieldValues[i].strip() == "" and option[0] == "*": 26 errmsg += ('【%s】為必填項。\n\n' % fieldNames[i]) 27 if errmsg == "": 28 break 29 fieldValues = g.multenterbox(errmsg, title, fieldNames, fieldValues) 30 31 print("用戶資料如下:%s" % str(fieldValues))
2. 提供一個文件夾瀏覽框,讓用戶選擇需要打開的文本文件,打開並顯示文件內容
# 2. 提供一個文件夾瀏覽框,讓用戶選擇需要打開的文本文件,打開並顯示文件內容。 import easygui as g # 我們這里想到textbox()函數默認會以比例字體(參數 codebox=True 設置為等寬字體)來顯示文本內容(自動換行),這個函數適合用於顯示一般的書面文字。 # textbox(msg='', title=' ', text='', codebox=False, callback=None, run=True) import os file_path = g.fileopenbox(default='*.txt') # fileopenbox(msg=None, title=None, default='*', filetypes=None, multiple=False) # fileopenbox() 函數用於提供一個對話框,返回用戶選擇的文件名(帶完整路徑哦),如果用戶選擇 “Cancel” 則返回 None。 # 關於 default 參數的設置方法: # default 參數指定一個默認路徑,通常包含一個或多個通配符。 # 如果設置了 default 參數,fileopenbox() 顯示默認的文件路徑和格式。 # default 默認的參數是 '*',即匹配所有格式的文件。 with open(file_path) as f: title = os.path.basename(file_path) #os.path.basename(path) 返回文件名 msg = '文件【%s】的內容如下:' % title text = f.read() g.textbox(msg, title, text)
3. 在上一題的基礎上增強功能:當用戶點擊“OK”按鈕的時候,比較當前文件是否修改過,如果修改過,則提示“覆蓋保存”、”放棄保存”或“另存為…”並實現相應的功能。
(提示:解決這道題可能需要點耐心,因為你有可能會被一個小問題卡住,但請堅持,自己想辦法找到這個小問題所在並解決它!)
點擊OK按鈕后會有什么結果呢?
怎么比較當前文件是否被修改過了呢?
1 # 3. 在上一題的基礎上增強功能:當用戶點擊“OK”按鈕的時候,比較當前文件是否修改過,如果修改過,則提示“覆蓋保存”、”放棄保存”或“另存為…”並實現相應的功能。 2 import easygui as g 3 import os 4 5 file_path = g.fileopenbox(default="*.txt") 6 7 with open(file_path) as old_file: 8 title = os.path.basename(file_path) 9 msg = "文件【%s】的內容如下:" % title 10 text = old_file.read() 11 text_after = g.textbox(msg, title, text) # textbox()顯示文本時是可以修改的,但是對原文件是沒有改動,只是顯示的時候 12 print(text_after) 13 14 if text != text_after[:-1]: 15 # textbox 的返回值會追加一個換行符 16 choice = g.buttonbox("檢測到文件內容發生改變,請選擇以下操作:", "警告", ("覆蓋保存", "放棄保存", "另存為...")) 17 # buttonbox(msg='', title=' ', choices=('Button[1]', 'Button[2]', 'Button[3]'), image=None, images=None, default_choice=None, cancel_choice=None, callback=None, run=True) 18 19 # 可以使用buttonbox()定義自己的一組按鈕,buttonbox()會顯示一組由你自定義的按鈕。 20 # 當用戶點擊任意一個按鈕的時候,buttonbox()返回按鈕的文本內容。 21 # 如果用戶點擊取消或者關閉窗口,那么會返回默認選項(第一個選項)。 22 23 if choice == "覆蓋保存": 24 with open(file_path, "w") as old_file: # 直接以‘w 寫入,由於是已經存在文件,寫入就是覆蓋 25 old_file.write(text_after[:-1]) 26 if choice == "放棄保存": 27 pass 28 if choice == "另存為...": 29 another_path = g.filesavebox(default=".txt") 30 if os.path.splitext(another_path)[1] != '.txt': # os.path.splitext(path) 分割路徑中的文件名與拓展名 31 another_path += '.txt' 32 with open(another_path, "w") as new_file: 33 new_file.write(text_after[:-1]) 34 35 # filesavebox(msg=None, title=None, default='', filetypes=None) 36 # filesavebox() 函數提供一個對話框,讓用於選擇文件需要保存的路徑(帶完整路徑哦),如果用戶選擇 “Cancel” 則返回 None。 37 # default 參數應該包含一個文件名(例如當前需要保存的文件名),當然也可以設置為空的,或者包含一個文件格式掩碼的通配符。 38 # filetypes 參數的設置方法請參考 fileopenbox() 函數。
4. 寫一個程序統計你當前代碼量的總和,並顯示離十萬行代碼量還有多遠?
- 要求一:遞歸搜索各個文件夾
- 要求二:顯示各個類型的源文件和源代碼數量
- 要求三:顯示總行數與百分比
1 # 寫一個程序統計你當前代碼量的總和,並顯示離十萬行代碼量還有多遠? 2 # 要求一:遞歸搜索各個文件夾 3 # 要求二:顯示各個類型的源文件和源代碼數量 4 # 要求三:顯示總行數與百分比 5 6 7 import easygui as g 8 import os 9 10 def show_result(start_dir): 11 lines = 0 12 total = 0 13 text = '' 14 15 for i in source_list: 16 lines = source_list[i] 17 total += lines 18 text += "【%s】源文件 %d 個,源代碼 %d 行\n" % (i, file_list[i], lines) 19 20 title = '統計結果' 21 msg = '您目前共累計敲了 %d 行代碼,完成進度: %2.f %%\n離10萬行代碼還差 %d 行,請繼續努力!' % (total, total/1000, 100000 - total) 22 g.textbox(msg, title, text) 23 24 25 def calc_code(file_name): 26 lines = 0 27 with open(file_name) as f: 28 print('正在分析文件:%s...' % file_name) 29 try: 30 for each_line in f: 31 lines += 1 32 33 except UnicodeDecodeError: 34 pass # 不可避免會遇到格式不兼容的文件,這里忽略掉...... 35 36 return lines 37 38 def search_file(start_dir): 39 os.chdir(start_dir) 40 41 for each_file in os.listdir(os.curdir): 42 ext = os.path.splitext(each_file)[1] 43 if ext in target: 44 lines = calc_code(each_file) # 統計行數 45 # 還記得異常的用法嗎?如果字典中不存,拋出KeyError,則添加字典鍵 46 # 統計文件數 47 try: 48 file_list[ext] += 1 49 except KeyError: 50 file_list[ext] = 1 51 52 #統計源代碼行數 53 54 try: 55 source_list[ext] += lines 56 57 except KeyError: 58 source_list[ext] = lines 59 60 if os.path.isdir(each_file): 61 search_file(each_file) # 遞歸調用 62 os.chdir(os.pardir) # 遞歸調用完切記返回上一層目錄 63 64 target = ['.c', '.cpp', '.py', '.cc', '.java', '.pas', '.asm'] 65 file_list = {} 66 source_list = {} 67 68 g.msgbox('請打開您存放所以代碼的文件夾......', '統計代碼量') 69 path = g.diropenbox('請選擇您的代碼庫:') 70 71 search_file(path) 72 show_result(path)