一、基本信息
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 、其它:
希望下次能接触到其它语言的题目。