作業 5:詞頻統計——增強功能
一、基本資訊
1.1、編譯環境、作者、專案名稱
1 # 編譯環境:Pycharm2017、Python3.7 2 # 專案名稱:詞頻統計——增強功能 3 # 作者:1613072038:夏文傑 4 # 1613072040:高昶
1.2、其他
二、專案分析
-
程式執行模組(方法、函式)介紹
Task 1. 介面封裝 —— 將基本功能封裝成(類或獨立模組)
本任務程式碼和作業4一樣,只是將分散的函式整合到一個類中,然後我們再在測試中呼叫我們寫好的類。這裡我們的檔名為:lei.py
1 import re 2 3 class workCount: 4 5 def process_file(dst): # 讀取檔案 6 lines = len(open(dst, 'r').readlines()) # 藉助readlines可以獲得文字的行數 7 with open(dst) as f: 8 bvffer = f.read() 9 f.close() 10 return bvffer 11 12 def process_buffer(bvffer):13 if bvffer: 14 for ch in ':,.-_': 15 bvffer = bvffer.lower().replace(ch, " ") 16 bvffer = bvffer.strip().split() 17 word_re = "^[a-z]{4}(\w)*" 18 # 正則匹配至少以4個英文字母開頭,跟上字母數字符號,單詞以分隔符分割,不區分大小寫 19 words = [] 20 fori in range(len(bvffer)): 21 word = re.match(word_re, bvffer[i]) # 匹配list中的元素 22 if word: # 匹配成功,加入words 23 words.append(word.group()) 24 word_freq = {} 25 for word in words: # 對words進行統計 26 word_freq[word] = word_freq.get(word, 0) + 1 27 return word_freq, len(words) 28 29 def output_result(word_freq): 30 if word_freq: 31 sorted_word_freq = sorted(word_freq.items(), key=lambda v: v[1], reverse=True) 32 for item in sorted_word_freq[:10]: # 輸出 Top 10 的單詞 33 print('<' + str(item[0]) + '>:' + str(item[1])) 34 return sorted_word_freq[:10] 35 36 def print_result(dst): 37 buffer = workCount.process_file(dst) 38 word_freq, counts_words = workCount.process_buffer(buffer) 39 print('統計單詞數:' + str(counts_words)) 40 print('統計最多的10個單詞及其詞頻') 41 workCount.output_result(word_freq)
接下來我們測試中呼叫我們寫好的類。import我們寫好的:lei.py
1 import lei 2 import argparse 3 if __name__ == '__main__': 4 parser = argparse.ArgumentParser(description="your script description") # description引數可以用於插入描述指令碼用途的資訊,可以為空 5 parser.add_argument('--file', '-file', type=str, default='src/test.txt', help="讀取檔案路徑") 6 args = parser.parse_args() # 將變數以標籤-值的字典形式存入args字典 7 dst = args.file 8 lei.workCount.print_result(dst) #此處為類的呼叫
然後我們直接來看一下效果:如圖2.1、2.2
先看一下src/test.txt裡面寫的啥:
接著看一下測試函式的效果:
2.1 測試函式在IDE中執行截圖
2.2 測試函式在CMD中執行截圖
Task 2. 增加新功能
本任務就是在任務一的基礎上增加了新的功能,我們增加引數的數量,便可以實現。
看一下workCount類裡面的程式碼。
1 import re 2 3 class workCount: 4 def __init__(self, dst, m, n, o): # dst:開啟檔案路徑;m:片語長度;n:輸出的單詞數量;o表示輸出檔案的儲存路徑 5 self.dst = dst 6 self.m = m 7 self.n = n 8 self.o = o 9 10 def process_file(self): # 讀取檔案 11 lines = len(open(self.dst, 'r+').readlines()) # 藉助readlines可以獲得文字的行數 12 with open(self.dst) as f: 13 bvffer = f.read() 14 f.close() 15 return bvffer, lines 16 17 def process_buffer(self, bvffer): 18 if bvffer: 19 for ch in ':,.-_': 20 bvffer = bvffer.lower().replace(ch, " ") 21 counts = bvffer.strip().split() 22 regex = '' 23 for i in range(self.m): 24 regex += '[a-z]+' 25 if i < self.m - 1: 26 regex += '\s' 27 result = re.findall(regex, bvffer) # 正則查詢片語 28 word_freq = {} 29 for word in result: # 將正則匹配的結果進行統計 30 word_freq[word] = word_freq.get(word, 0) + 1 31 return word_freq, len(counts) 32 33 def output_result(self, word_freq): 34 if word_freq: 35 sorted_word_freq = sorted(word_freq.items(), key=lambda v: v[1], reverse=True) 36 for item in sorted_word_freq[:self.n]: # 輸出 Top 10 的單詞 37 print('<' + str(item[0]) + '>:' + str(item[1])) 38 return sorted_word_freq[:self.n] 39 40 def print_result(self): # 輸出結果 41 print('查詢路徑為:' + str(self.dst) + '的文字') 42 print('統計片語長度為:' + str(self.m) + '且詞頻前' + str(self.n) + '的單詞') 43 buffer, lines = workCount.process_file(self) 44 word_freq, counts_words = workCount.process_buffer(self, buffer) 45 lines = 'lines:' + str(lines) 46 words = 'words:' + str(counts_words) 47 print(words) 48 print(lines) 49 items = workCount.output_result(self, word_freq) 50 with open(self.o, 'w+') as w: 51 w.write(lines+'\n') 52 w.write(words+'\n') 53 for item in items: # 格式化 54 item = '<' + str(item[0]) + '>:' + str(item[1]) + '\n' 55 w.write(item) 56 print('寫入'+self.o+'檔案已完成!') 57 w.close()
接下來我們看一下測試的程式碼。
1 import lei 2 import argparse 3 4 if __name__ == '__main__': 5 parser = argparse.ArgumentParser(description="your script description") # description引數可以用於插入描述指令碼用途的資訊,可以為空 6 parser.add_argument('--i', '-i', type=str, default='src/test.txt', help="讀取檔案路徑") 7 parser.add_argument('--m', '-m', type=int, default=2, help="輸出的單詞數量") 8 parser.add_argument('--n', '-n', type=int, default=5, help="輸出的單詞個數") 9 parser.add_argument('--o', '-o', type=str, default='src/result.txt', help="寫入檔案路徑") 10 args = parser.parse_args() # 將變數以標籤-值的字典形式存入args字典 11 dst = args.i 12 m = args.m 13 n = args.n 14 o = args.o 15 obj = lei.workCount(dst, m, n, o) # 將引數傳給類 16 obj.print_result() # 呼叫類裡面的自定義的輸出函式,將資料呈現出來
來看一下成果圖吧!(就不一項項功能截圖了,直接附上成果圖
三、效能分析
因為本次程式碼基本都是用的作業四的,而且作業四程式碼效能都是之前調整到‘’我們覺得最佳‘’的,所以本次就沒進行效能優化。因為文字的內容也很少所以程式執行還是很快的。
效能圖表如下:
四、PSP 表格
僅根據實際估算,不一定很準確。
五、事後分析與總結
-
簡述結對程式設計時,針對某個問題的討論決策過程。
就cmd執行py指令碼傳參的問題,我們通過查詢,找到了二種方法,1、sys.argv;2、
argparse模組。通過比較我們發現argparse模組對於傳多個引數而且argparse模組還包含位置引數,這樣讓處理命令列引數很快捷和方便。
-
評價對方:請評價一下你的合作伙伴,又哪些具體的優點和需要改進的地方。 這個部分兩人都要提供自己的看法。
高昶評價夏文傑:夏文傑本次相較於上次對python有了跟多的瞭解,就封裝和傳參提供了很不錯的點子,所以我們這次作業花費的時間也比上次少了很多。需要改進的地方:還是和上次一樣,多閱讀、瞭解計算機相關的知識。
夏文傑評價高昶:高昶可以很快的將想法變成程式碼。需要改進的地方:基礎需要鞏固加強,且能夠多變通。
-
評價整個過程:關於結對過程的建議
結對程式設計是一個相互學習、相互磨合的漸進過程,因為二人平時關係就很不錯,二人都很認真的完成本次任務,所以本次的結對程式設計是很愉快的。通過本次結對程式設計我們也充分的認識到了合作的重要性,一個人程式設計不免要犯這樣那樣的錯誤,結對程式設計就很好的避免了這樣的問題,而且二人會碰撞出更多的想法和靈感,二人相互學習,相互補充。而且結對程式設計能提供更好的設計質量和程式碼質量,兩人合作能有更強的解決問題的能力。還有就是,結對程式設計讓有些許枯燥的程式設計,變得有趣。
建議:結對程式設計是一件很不錯的事情,但是結對程式設計的過程中難免發生爭執,所以妥善處理好爭議才能更好的將結對程式設計做好。
-
其它
經過2次的結對練習,我們的程式設計能力都有了些許提升,而且更加懂得了什麼是合作!