软工作业4:词频统计 ——基本功能

一、基本信息

1、编译环境:Pycharm2018、Python3.8

2、作者:1613072007 周磊

         1613072008 俞林森

3、项目地址:https://gitee.com/ntucs/PairProg.git

二、项目分析

1.1、读文件到缓冲区 process_file(dst,f)

def process_file(dst, f):  # 读文件到缓冲区
    try:  # 打开文件
        doc = open(dst, 'r')
    except IOError as s:
        print(s)
        return None
    try:  # 读文件到缓冲区
        bvffer = doc.read()
    except:
        print("Read File Error!")
        return None
    doc.close()
    return bvffer

1.2、统计行数   process_line(dst, f)

def process_line(dst, f): #统计行数
    count = 0
    for line in open(dst, 'r').readlines():
        if line != '' and line != '\n':
            count += 1
    print('lines:', count, file=f)

1.3、统计单词  process_line(dst, f)

def process_buffer(bvffer, f):
   if bvffer:
        word_freq = {}
        # 下面添加处理缓冲区 bvffer代码,统计每个单词的频率,存放在字典word_freq
        for ch in '“‘!;,.?”':  # 将文本内容都改为小写且除去文本中的中英文标点符号
            bvffer = bvffer.lower().replace(ch, " ")
        bvffer = bvffer.strip().split()  # strip()删除空白符;split()以空格分割字符串
        regex = "^[a-z]{4}(\w)*"
        words = []
        for word in bvffer:  # 判定是否是符合单词设定
            if re.match(regex, word):
                words.append(word)
        print('words:', len(words), file=f)  # 输出单词总数
        for word in words:  # 获取字典
            word_freq[word] = word_freq.get(word, 0) + 1
        for key in list(word_freq):  # 删除一些常用单词
            if key in st1:
                del word_freq[key]
        return word_freq

1.4、统计两个单词的词组   process_higth2(bvffer, f)

def process_higth2(bvffer, f): #统计两个单词词组
    Phrase = []
    Phrase_freq = {}
    words = bvffer.strip().split()#单词分割
    for y in range(len(words) - 1):
        if words[y][-1] in '’“‘!;,.?”' or words[y + 1][0] in '’“‘!;,.?”':  # 判断两个单词之间是否有其他符号
            continue
        elif words[y][0] in '’“‘!;,.?”':  # 判断第一个单词前是否有符号
            words[y] = words[y][1:]
        elif words[y + 1][-1] in '’“‘!;,.?”':  # 判断第二个单词后是否有符号
            words[y + 1] = words[y + 1][:len(words[y + 1]) - 1]
        Phrase.append(words[y] + ' ' + words[y + 1])  # 录入列表Phrase
    for ph in Phrase:
        Phrase_freq[ph] = Phrase_freq.get(ph, 0) + 1  # 生成词组字典
    return Phrase_freq

1.5、统计三个单词的词组   process_higth3(bvffer, f)

def process_higth3(bvffer, f):#统计三个单词词组
    Phrase = []
    Phrase_freq1 = {}
    words = bvffer.strip().split()  # 单词分割
    for y in range(len(words) - 2):
        if words[y][-1] in '’“‘!;,.?”' or words[y + 1][0] in '’“‘!;,.?”':
            continue
        elif words[y + 1][-1] in '’“‘!;,.?”' or words[y + 2][0] in '’“‘!;,.?”':
            continue
        elif words[y][0] in '’“‘!;,.?”':
            words[y] = words[y][1:]
        elif words[y + 1][-1] in '’“‘!;,.?”':
            words[y + 2] = words[y + 2][:len(words[y + 2]) - 1]
        Phrase.append(words[y] + ' ' + words[y + 1] + ' ' + words[y + 2])  # 录入列表Phrase
    for ph in Phrase:
        Phrase_freq1[ph] = Phrase_freq1.get(ph, 0) + 1  # 生成词组字典
    return Phrase_freq1

1.6、输出单词   output_result(word_freq, f)

def output_result(word_freq, f):#输出单词
    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 10 的单词
            print(item[0], ':', item[1], file=f)

1.7、主函数  main()

def main():
    dst = "Gone_with_the_wind.txt"  # A_Tale_of_Two_Cities  Gone_with_the_wind
    f = open('result.txt', 'w')  # 写入结果路径
    process_line(dst, f)
    bvffer = process_file(dst, f)  # 读文件到缓冲区
    word_freq = process_buffer(bvffer, f)  # 生成单词字典
    Phrase_freq2 = process_higth2(bvffer, f)  # 生成词组字典
    Phrase_freq3 = process_higth3(bvffer, f)  # 生成词组字典

    output_result(word_freq, f)  # 输出单词前10
    print('双词组前十词组:', file=f)
    output_result(Phrase_freq2, f)  # 输出双词组前10
    print('三词组前十词组:', file=f)
    output_result(Phrase_freq3, f)  # 输出双词组前10

1.8、性能测试

if __name__ == "__main__":
    cProfile.run("main()",filename="result")
    p=pstats.Stats("result")
    p.strip_dirs().sort_stats("calls").print_stats(10)
    p.strip_dirs().sort_stats("cumulative", "name").print_stats(10)

2.1、时间复杂度和空间复杂度

时间复杂度和空间复杂度的计算以下面这段代码为例

def process_higth2(bvffer, f): #统计两个单词词组
    Phrase = []
    Phrase_freq = {}
    words = bvffer.strip().split()#单词分割
    for y in range(len(words) - 1):
        if words[y][-1] in '’“‘!;,.?”' or words[y + 1][0] in '’“‘!;,.?”':  # 判断两个单词之间是否有其他符号
            continue
        elif words[y][0] in '’“‘!;,.?”':  # 判断第一个单词前是否有符号
            words[y] = words[y][1:]
        elif words[y + 1][-1] in '’“‘!;,.?”':  # 判断第二个单词后是否有符号
            words[y + 1] = words[y + 1][:len(words[y + 1]) - 1]
        Phrase.append(words[y] + ' ' + words[y + 1])  # 录入列表Phrase
    for ph in Phrase:
        Phrase_freq[ph] = Phrase_freq.get(ph, 0) + 1  # 生成词组字典
    return Phrase_freq

因为两个for循环不是嵌套的,因此时间复杂度为O(n)。时间复杂度为O(1)。

3.1、程序运行案例截图

 

 停词表:

三、性能分析

    我们大概花了一个多小时在提高程序性能上,原本运行时间是10秒second,经过代码改进后运行时间提升至3.341second。

   主要修改代码如下:

def process_buffer(bvffer, f):
    if bvffer:
        word_freq = {}
        # 下面添加处理缓冲区 bvffer代码,统计每个单词的频率,存放在字典word_freq
        for ch in '“‘!;,.?”':  # 将文本内容都改为小写且除去文本中的中英文标点符号
            bvffer = bvffer.lower().replace(ch, " ")
            words = bvffer.strip().split()  # strip()删除空白符;split()以空格分割字符串
        for word in words:  # 判定是否是符合单词设定
            y = 1
            s = True
            for x in word:
                if y > 4:
                    break
                if (x < 'a' or x > 'z') and x not in '':
                    s = False
                    break
                y = y + 1
            if s == False:
                words.remove(word)
        print('words:', len(words), file=f)  # 输出单词总数
        for word in words:  # 获取字典
            word_freq[word] = word_freq.get(word, 0) + 1
        for key in list(word_freq):  # 删除一些常用单词
            if key in stop_wred:
                del word_freq[key]
        return word_freq

改为:

 
 
st = open("stop_word.txt", 'r')
st1 = st.read()

def
process_buffer(bvffer, f): if bvffer: word_freq = {} # 下面添加处理缓冲区 bvffer代码,统计每个单词的频率,存放在字典word_freq for ch in '“‘!;,.?”': # 将文本内容都改为小写且除去文本中的中英文标点符号 bvffer = bvffer.lower().replace(ch, " ") bvffer = bvffer.strip().split() # strip()删除空白符;split()以空格分割字符串 regex = "^[a-z]{4}(\w)*" words = [] for word in bvffer: # 判定是否是符合单词设定 if re.match(regex, word): words.append(word) print('words:', len(words), file=f) # 输出单词总数 for word in words: # 获取字典 word_freq[word] = word_freq.get(word, 0) + 1 for key in list(word_freq): # 删除一些常用单词 if key in st1: del word_freq[key] return word_freq

 (1)按执行次数

 

(2)按执行时间

四、其他

1、结对编程时间开销(单位:小时)

    这次结对编程大概用了8个多小时,因为不精通python,很多内容没接触过,所以做的时候就基本是边学边写的。

 2、结对编程照片

五、事后分析与总结

1、 简述结对编程时,针对某个问题的讨论决策过程

     一开始使用的停词表是直接写在py文件中的,但是考虑到效率问题,最终采用txt来读取停词表,来实现删除不想要的单词。

 2、评价

(1)周磊对俞林森的评价:个人能力强,不遗余力参与到合作编程中,与他讨论的时候能够给我很大的启发,并且会提出代码中不足的地方,希望能与他再次合作!

(2)俞林森对周磊的评价:周磊同学对python有过接触,而我基本就是个小白,此次他编写了大部分内容,我做到尽量不拖后腿。

 

3、关于结对过程的建议

      结对编程的过程收获颇多,我觉得结对编程有好有坏,但是好处远远大于的不好的地方。两个人难免会遇到意见不同的时候,关键是看此时如何协调、如何沟通、如何采纳。如果团队内部不能很好地处理这些分歧,那么非但不能提高效率,反而会拖慢工作的进程。如果团队协调得很好,那么两个人的力量是绝对大过一个人的。一个人的想法始终有限,两个人或者一群人合作,说不定还能擦出思想的火花。

 

4 、其它:

   希望下次能接触到其它语言的题目。

 

猜你喜欢

转载自www.cnblogs.com/YLSyls/p/9819748.html
今日推荐