作业 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             for i 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次的结对练习,我们的编程能力都有了些许提升,而且更加懂得了什么是合作!

 

posted @ 2018-11-29 21:15  高昶  阅读(265)  评论(4编辑  收藏  举报