天天看點

軟工作業5:詞頻統計--增強功能

一、基本資訊

1、編譯環境、作者等資訊

編譯環境:Pycharm2017、Python3.6

項目名稱:詞頻統計——增強功能

作者:  1613072026:唐順成

      1613072027:吳  濤

2、本次作業的位址:

https://edu.cnblogs.com/campus/ntu/Embedded_Application/homework/2088

二、項目分析

Task 1. 接口封裝 —— 将基本功能封裝成(類或獨立子產品)

1.封裝好的fengz.py

import re
from string import punctuation


class wordCount:
 

    def process_file(dst):  # 讀檔案到緩沖區
        try:   # 打開檔案
            f = open(dst, 'r')   # path為檔案路徑
        except IOError as s:
            print(s)
            return None
        try:  # 讀檔案到緩沖區
            # 如果檔案很大,那麼放到清單裡計算長度的方法将會很慢,是以循環會更好些
            count = 0
            for count, line in enumerate(f):
                count += 1
            f.close()
            f = open(dst, 'r')
            bvffer = f.read()
        except:
            print('Read File Error!')
            return None
        f.close()
        return bvffer, count


    def process_buffer(bvffer):  # 處理緩沖區,傳回存放每個單詞頻率的字典if bvffer:
        # 下面添加處理緩沖區bvffer代碼,統計每個單詞的頻率,存放在字典word_freq
        word_freq = {}
        # 用空格代替标點符号,并且去掉大小寫,之後進行正則比對
        bvffer = bvffer.replace(punctuation, '').lower().split(' ')
        regex_word = "^[a-z]{4}(\w)*"
        words = []
        for word in bvffer:  # 判定是否符合單詞的定義
            if re.match(regex_word, word):
                words.append(word)
        txtWords = open("stopwords.txt", 'r').readlines()  # 讀取停詞表檔案
        stopWords = []  # 存放停詞表的list
        # 讀取文本是readlines是以寫入list要将換行符取代
        for i in range(len(txtWords)):
            txtWords[i] = txtWords[i].replace('\n', '')
            stopWords.append(txtWords[i])
        for word in words:
            if word not in stopWords:  # 當單詞不在停詞表中時,使用正規表達式比對
                if word in word_freq.keys():
                    # 資料字典已經存在該單詞,數量+1
                    word_freq[word] = word_freq[word] + 1
                else:
                    # 不存在,把單詞存入字典,數量置為1
                    word_freq[word] = 1
    return word_freq, len(words)

    def output_result( word_freq):
        if word_freq:
            sorted_word_freq = sorted(word_freq.items(), key=lambda v: v[1], reverse=True)
            for item in sorted_word_freq[:10]:  # 輸出 Top n 的單詞
                print('<' + str(item[0]) + '>:' + str(item[1]))
        return sorted_word_freq

    def save_result(self, lines, words_number, sorted_word_freq):  # 儲存結果到檔案(result.txt)
        try:
            result = open("result.txt", "w")  # 以寫模式打開,并清空檔案内容
        except Exception as e:
            result = open("result.txt", "x")  # 檔案不存在,建立檔案并打開
        # 寫入檔案result.txt
        result.write("lines:" + lines + "\n")
        result.write("words:" + words_number + "\n")
        for item in sorted_word_freq[:self.n]:
            item = '<' + str(item[0]) + '>:' + str(item[1]) + '\n'
            result.write(item)
        print('寫入result.txt檔案已完成!')
        result.close()

    def print_result(dst):
        buffer, lines = wordCount.process_file(dst)
        word_freq, words_number = wordCount.process_buffer(buffer)
        lines = str(lines)
        words_number = str(words_number)
        sorted_word_freq=wordCount.output_result(word_freq)
        wordCount.save_result( lines, words_number, sorted_word_freq)
      

2.測試類test.py

import fengz
import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser()  
    parser.add_argument('--file', '-file', type=str, default='Gone_with_the_wind.txt', help="讀取檔案路徑")
    args = parser.parse_args()  # 将變量以标簽-值的字典形式存入args字典
    dst = args.file
    fengz.wordCount.print_result(dst) #此處為類的調用      

3、測試函數的效果:

(1)測試函數在Pycharm中運作截圖

軟工作業5:詞頻統計--增強功能
軟工作業5:詞頻統計--增強功能

(2)測試函數在CMD中運作截圖

軟工作業5:詞頻統計--增強功能

Task 2. 增加新功能

 1.封裝好的fengz.py

import re
from string import punctuation


class wordCount:
    def __init__(self, dst, m, n, o):  # dst:打開檔案路徑;m:詞組長度;n:輸出的單詞數量;o表示輸出檔案的存儲路徑
        self.dst = dst
        self.m = m
        self.n = n
        self.o = o

    def process_file(self):  # 讀檔案到緩沖區
        try:   # 打開檔案
            f = open(self.dst, 'r')   # path為檔案路徑
        except IOError as s:
            print(s)
            return None
        try:  # 讀檔案到緩沖區
            # 如果檔案很大,那麼放到清單裡計算長度的方法将會很慢,是以循環會更好些
            count = 0
            for count, line in enumerate(f):
                count += 1
            f.close()
            f = open(self.dst, 'r')
            bvffer = f.read()
        except:
            print('Read File Error!')
            return None
        f.close()
        return bvffer, count


    def process_buffer(self, bvffer):  # 處理緩沖區,傳回存放每個單詞頻率的字典word_freq
        if bvffer:
            # 下面添加處理緩沖區bvffer代碼,統計每個單詞的頻率,存放在字典word_freq
            word_freq = {}
            # 用空格代替标點符号,并且去掉大小寫,之後進行正則比對
            count = bvffer.replace(punctuation, '').lower().split(' ')
            regex = ''
            for i in range(self.m):
                regex += '[a-z]+'
                if i < self.m - 1:
                    regex += '\s'
            result = re.findall(regex, bvffer)  # 正則查找詞組
            word_freq = {}
            for word in result:  # 将正則比對的結果進行統計
                word_freq[word] = word_freq.get(word, 0) + 1
            return word_freq, len(count)

    def output_result(self, word_freq):
        if word_freq:
            sorted_word_freq = sorted(word_freq.items(), key=lambda v: v[1], reverse=True)
            for item in sorted_word_freq[:self.n]:  # 輸出 Top n 的單詞
                print('<' + str(item[0]) + '>:' + str(item[1]))
        return sorted_word_freq[:self.n]

    def save_result(self, lines, words_number, sorted_word_freq):  # 儲存結果到檔案(result.txt)
        try:
            result = open(self.o, "w")  # 以寫模式打開,并清空檔案内容
        except Exception as e:
            result = open(self.o, "x")  # 檔案不存在,建立檔案并打開
        # 寫入檔案result.txt
        result.write("lines:" + lines + "\n")
        result.write("words:" + words_number + "\n")
        for item in sorted_word_freq[:self.n]:
            item = '<' + str(item[0]) + '>:' + str(item[1]) + '\n'
            result.write(item)
        print('寫入'+self.o+'檔案已完成!')
        result.close()

    def print_result(self):
        buffer, lines = wordCount.process_file(self)
        word_freq, words_number = wordCount.process_buffer(self, buffer)
        print('統計詞組長度為:' + str(self.m) + '且詞頻前' + str(self.n) + '的單詞')
        lines = str(lines)
        words_number = str(words_number)
        sorted_word_freq=wordCount.output_result(self, word_freq)
        wordCount.save_result(self, lines, words_number, sorted_word_freq)

          

2、測試類

import fengz
import argparse


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="test example")
    parser.add_argument('--i', '-i', type=str, default='Gone_with_the_wind.txt', help="讀取檔案路徑")
    parser.add_argument('--m', '-m', type=int, default=2, help="詞組長度")
    parser.add_argument('--n', '-n', type=int, default=4, help="輸出前n的單詞/詞組")
    parser.add_argument('--o', '-o', type=str, default='result.txt', help="寫入檔案路徑")
    args = parser.parse_args()  # 将變量以标簽-值的字典形式存入args字典
    dst = args.i
    m = args.m
    n = args.n
    o = args.o
    obj = fengz.wordCount(dst, m, n, o)  # 将參數傳給類
    obj.print_result()      

3、運作成果截圖:

 (1)詞組長度為1,輸出前5詞組

軟工作業5:詞頻統計--增強功能

(2)詞組長度為2,輸出前4詞組

軟工作業5:詞頻統計--增強功能

(3)詞組長度為3,輸出前5詞組,且指定輸出路徑為re.txt

軟工作業5:詞頻統計--增強功能
軟工作業5:詞頻統計--增強功能

三、性能分析

(1)使用gprof2dot進行性能分析可視化

軟工作業5:詞頻統計--增強功能

四、PSP 表格

1、結對程式設計時間開銷:

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 30 25
· Estimate · 估計這個任務需要多少時間 120 130
Development 開發 160 150
· Analysis · 需求分析(含學習新技術) 60 50
· Design · 編寫設計文檔
· Design Review · 設計複審 35
· Coding Standard · 代碼規範 10
· 具體設計 55
· Coding · 具體編碼 80 70
· code review · 代碼複審
· test · 測試 20
Reporting 報告
· Test report · 測試報告
· Size measurement · 計算工作量 5
· Postmortem ·事後總結
合計 675 660

五、事後分析與總結 

(1)針對某個問題的讨論決策過程:

 就cmd運作py腳本傳參的問題,我們通過查詢,找到了二種方法,1、

sys.argv;2、

argparse子產品。通過比較我們發現argparse子產品對于傳多個參數而且argparse子產品還包含位置參數,這樣讓處理指令行參數很快捷和友善。

(2)評價對方:

請評價一下你的合作夥伴,又哪些具體的優點和需要改進的地方。 這個部分兩人都要提供自己的看法。

吳濤評價唐順成 :聰明思維靈活,樂于幫助我,促進大家學習進步。程式設計能力強,有發散思維。

唐順成評價吳濤 :樂于學習新知識,但是Python的知識不夠熟練。

(3)評價整個過程:關于結對過程的建議:

  (1)   結對程式設計不僅檢驗了程式設計能力,也極高了我們團結合作能力,我們在程式設計過程中互相鼓勵,互相幫助,因為一旦某個功能實作不了,我們會很着急。兩個人可以互相鼓勵,也同時形成一種良性競争,比如這個方法是其中一個人想出來的,另一個人就會去思考有沒有更快的方法。希望有機會可以再次結對程式設計。

(2)建議: 有合作就有競争,互相之間應該,以合作為主,互相學習。

(4)結對程式設計照片:

軟工作業5:詞頻統計--增強功能

(5)其他:

不斷的結對合作程式設計,我們配合的越開越默契,這是一個好的結果,希望我們的合作成果越來越好。