一、基本信息
1.1 本次作业地址:https://edu.cnblogs.com/campus/ntu/Embedded_Application/homework/2088
1.2 项目的Git地址:https://gitee.com/ntucs/PairProg
1.3合作:1613072005 蒋晓明 1613072006 陈扬
二、项目分析
程序运行模块(方法、函数)介绍
Task1:接口封装 —— 将基本功能封装成(类或独立模块)
将统计文本总词数,统计文本最多的十个单词及其词频这两个方法封装在类workCount中
import re
class workCount:
def process_file(dst): # 读文件到缓冲区
try: # 打开文件
f = open(dst, 'r')
except IOError as s:
print(s)
return None
try: # 读文件到缓冲区
bvffer = f.read()
except:
print("Read File Error!")
return None
f.close()
return bvffer
def process_buffer(bvffer):
if bvffer:
word_freq = {}
# 下面添加处理缓冲区 bvffer代码,统计每个单词的频率,存放在字典word_freq
bvffer = bvffer.lower() # 大小写转换,将大写字母转化为小写字母
for s in '“”!?,.;:$':
bvffer = bvffer.replace(s, ' ') # 将找出的特殊符替换为空格
list = re.findall(r'[a-z]{4}\w*', bvffer) # 利用re模块的查找功能与正则表达式相结合,找出符合单词定义的单词,存入list
for str in list:
word_freq[str] = word_freq.get(str, 0) + 1 # 计数
return word_freq
def process_count(bvffer): # 统计总词数数
count = bvffer.count(" ") + 1
return count
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 10 的单词
print(item)
return sorted_word_freq[:10]
def print_result(dst):
bvffer = workCount.process_file(dst)
word_freq = workCount.process_buffer(bvffer)
count = workCount.process_count(bvffer)
print('单词数:' + str(count))
print('最多的10个单词及其词频')
workCount.output_result(word_freq)
编写TEST.py测试类,通过import argparse模块,可以在cmd命令行中调用
import cla
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="your script description") # description参数可以用于插入描述脚本用途的信息,可以为空
parser.add_argument('--file', '-file', type=str, default='E:\作业\软件工程1\SE16_WordCount\Gone_with_the_wind.txt',help="读取文件路径") # default属性是默认值,当参数输入错误时使用默认参数 type后表示参数的类型
args = parser.parse_args() # 将变量以标签-值的字典形式存入args字典
dst = args.file
cla.workCount.print_result(dst)
在pycharm环境下运行截图
在命令行传参截图
Task 2. 增加新功能
- 词组统计:能统计文件夹中指定长度的词组的词频
- 自定义输出:能输出用户指定的前n多的单词与其数量
类cla的代码:
import re
class workCount:
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')
except IOError as s:
print(s)
return None
try: # 读文件到缓冲区
bvffer = f.read()
except:
print("Read File Error!")
return None
f.close()
return bvffer
def process_lines(self): # 读取行数
countline = 0
for index, line in enumerate(open(self.dst, 'r')):
countline += 1
return countline
def process_buffer(self,bvffer):
if bvffer:
word_freq = {}
# 下面添加处理缓冲区 bvffer代码,统计每个单词的频率,存放在字典word_freq
bvffer = bvffer.lower() # 大小写转换,将大写字母转化为小写字母
for s in '“”!?,.;:$':
bvffer = bvffer.replace(s, ' ') # 将找出的特殊符替换为空格
match = '[a-z]+'
for i in range((self.m) - 1):
match += '\s[a-z]+' # m长度词组的正则表达式
list = re.findall(match, bvffer) # 利用re模块的查找功能与正则表达式相结合,找出符合单词定义的单词,存入list
for str in list:
word_freq[str] = word_freq.get(str, 0) + 1 # 计数
return word_freq
def process_count(bvffer): # 统计总词数数
count = bvffer.count(" ") + 1
return 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]: # 输出单词
print(item)
return sorted_word_freq[:self.n]
def print_result(self):
print('查询路径为:' + str(self.dst) + '的文本')
print('统计词组长度为:' + str(self.m) + '且词频前' + str(self.n) + '的单词')
bvffer = workCount.process_file(self)
word_freq = workCount.process_buffer(self,bvffer)
count = workCount.process_count(bvffer)
countline = workCount.process_lines(self)
lines = 'lines:' + str(countline)
words = 'words:' + str(count)
print(words)
print(lines)
items = workCount.output_result(self, word_freq)
w = open(self.o, 'w+')
w.write(lines + '\n')
w.write(words + '\n')
for item in items: # 格式化
item = '<' + str(item[0]) + '>:' + str(item[1]) + '\n'
w.write(item)
print('写入' + self.o + '文件已完成!')
w.close()
TEST测试类代码:
import cla
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="your script description") # description参数可以用于插入描述脚本用途的信息,可以为空
# parser.add_argument('--file', '-file', type=str, default='E:\作业\软件工程1\SE16_WordCount\Gone_with_the_wind.txt',help="读取文件路径") # default属性是默认值,当参数输入错误时使用默认参数 type后表示参数的类型
parser.add_argument('--i', '-i', type=str, default='E:\作业\软件工程1\SE16_WordCount\Gone_with_the_wind.txt', help="读取文件路径")
parser.add_argument('--m', '-m', type=int, default=3, help="输出的单词数量")
parser.add_argument('--n', '-n', type=int, default=3, help="输出的单词个数")
parser.add_argument('--o', '-o', type=str, default='E:/作业/软件工程1/SE16_WordCount/result.txt', help="写入文件路径")
args = parser.parse_args() # 将变量以标签-值的字典形式存入args字典
dst = args.i
m = args.m
n = args.n
o = args.o
obj = cla.workCount(dst, m, n, o) # 将参数传给类
obj.print_result() # 调用类里面的自定义的输出函数,将数据呈现出来
在pycharm中的截图:
在命令行传参截图
三、性能分析
本次实验在作业4基础上进行,性能相差不大。
1.调用次数
2.运行时间
3.性能图表
四、PSP 表格
五、事后分析与总结
- 简述结对编程时,针对某个问题的讨论决策过程。(1分)
- 主要通过上网查找资料,一起商讨解决。
- 评价对方:请评价一下你的合作伙伴,又哪些具体的优点和需要改进的地方。 这个部分两人都要提供自己的看法。(1分)
-
陈扬同学对蒋晓明同学的评价:
在整个结对编程的过程中,蒋晓明同学都很认真负责。对于新鲜的东西上手很快,遇到一些问题,我们也能很好地沟通解决,在整个编程过程中该同学付出了很大的努力!期待着和蒋晓明同学的下次合作。 - 蒋晓明对陈扬的评价:
- 陈扬同学积极主动,十分好学,在我们学习python的时候理解的很快也理解的很好,马上就可以学以致用,和他合作感到很舒服。
- 评价整个过程:关于结对过程的建议(1分)
-
通过这两次的结对编程,我觉得对我们的合作能力有了很大的提升,同时也考验了相互协作能力,结对编程就是一次小型的合作项目,只有有效地分工合作,才能很好地完成本次编程,一次一次地沟通,一次一次地改正。结对编程也能很好地解决一个问题,有时候一个人想一个问题总是想不到解决的方法,但是两个人一起想总是可以互补,快速地解决问题,期待着以后还可以结对编程,由两个人慢慢变成三个人。逐渐向工作的环境靠拢,模拟以后工作的项目分工。
- 结对编程照片(0.5分)
-
- 其它 (0.5分)
- 经过两次合作,我们默契更高,工作更加顺利。