202103226-1 编程作业
这个作业属于哪个课程 | 《软件工程》 |
---|---|
Github项目地址 | 项目地址 |
这个作业要求在哪里 | 要求 |
这个作业的目标 | 学习基础Git命令,实现基本需求的过程 |
参考文献 | 《构建之法及软件工程》 |
gitee地址
PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 30 |
Estimate | 估计这个任务需要多少时间 | 30 | 20 |
Development | 开发 | 1000 | 1200 |
Analysis | 需求分析 (包括学习新技术) | 60 | 150 |
Design Spec | 生成设计文档 | 90 | 60 |
Design Review | 设计复审 | 40 | 50 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 60 |
Design | 具体设计 | 70 | 60 |
Coding | 具体编码 | 300 | 600 |
Code Review | 代码复审 | 10 | 10 |
Test | 测试(自我测试,修改代码,提交修改) | 50 | 60 |
Reporting | 报告 | 10 | 20 |
Test Repor | 测试报告 | 30 | 50 |
Size Measurement | 计算工作量 | 10 | 10 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 10 | 15 |
合计 | 1760 | 2395 |
需求
实现一个命令行程序,不妨称之为WordCount。
实现基本需求
假设有一个软件每隔一小段时间会记录一次用户的搜索记录,记录为英文。
只需要统计Ascii码,汉字不需考虑
空格,水平制表符,换行符,均算字符
统计文件的单词总数(对应输出第二行),单词:至少以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。
英文字母: A-Z,a-z
字母数字符号:A-Z, a-z,0-9
分割符:空格,非字母数字符号
例:file123是一个单词, 123file不是一个单词。file,File和FILE是同一个单词
统计文件的有效行数(对应输出第三行):任何包含非空白字符的行,都需要统计。
统计文件中各单词的出现次数(对应输出接下来10行),最终只输出频率最高的10个。
频率相同的单词,优先输出字典序靠前的单词。
例如,windows95,windows98和windows2000同时出现时,则先输出windows2000
输出的单词统一为小写格式
然后将统计结果输出到output.txt,输出的格式如下;其中word1和word2 对应具体的单词,number为统计出的个数;换行使用'\n',编码统一使用UTF-8。
- 思路描述
首先是要解决文件输入输出的问题。这方面之前已经学习相关方法,去百度其他方法并发现了语法糖。
读取了文件中的内容,要根据相关要求进行处理统计。
统计字符数,只需要统计ASCII码的数量。在假设会出现中文的情况下,判断每一个是否为ASCII码并进行计数。由于后期知道不会出现中文,改为直接计算字符串的长度。
统计单词数,根据正则表达式,先通过分隔符获取到疑似单词的列表;再通过正则表达式对单词的判定,将符合条件的单词放入字典中,并进行计数。
统计有效行数,通过python自带的函数判断是否为空行。如果返回为非,则进行计数。
统计最多的10个单词及其词频,前面已经将全部的单词放入字典中。通过对字典进行排序并切片,最终剩下前十的单词及其词频。
将得到的数据写入文件中。
单独将相关功能独立成为单独的模块,并对代码进行相应的修改和增加异常处理。
通过参考文献,进行单元测试和性能测试。
设计与实现过程
统计每行字符数,将字符串传入该函数,并返回得到的结果:
`# 统计字符数
def count_character(line):
# character_num = len([i for i in list(line) if ord(i) <= 127])
character_num = len(line)
return character_num`
统计单词数,将字符串以及存放单词的字典传入该函数,修改字典并返回单词数:
`# 统计每行单词数
def count_word(line, count):
words = 0
word = re.split(r'[^a-z0-9]+', line)
pattern = re.compile(r'[a-z]{4}[a-z0-9]*')
for w in word:
if re.match(pattern, w):
words += 1
if w in count:
count[w] += 1
else:
count[w] = 1
return words`
统计最多的10个单词及其词频,将字典传入该函数,并返回前十结果:
`# 统计最多的10个单词及其词频
def count_most(count):
ans = sorted(count.items(), key=lambda x: (-x[1], x[0]))
result = {k: v for k, v in ans[:10]}
return result`
在主程序中通过from Lib import *导入该模块。
在读取输入文件的时候,通过语法糖的迭代器,先将每一行的大写字符都转化为小写,再进行相关的处理:
`with open(input_file, encoding='utf-8', newline='') as f:
for line in f:
line = line.lower()
# 统计每行字符数
characters += count_character(line)
# 统计非空白行数
if not line.isspace():
lines += 1
# 统计每行单词数
words += count_word(line, count)`
最后根据要求的格式将内容写入输出文件:
`with open(output_file, 'w', encoding='utf-8', newline='') as f:
f.write("characters: {0}\n".format(characters))
f.write("words: {0}\n".format(words))
f.write("lines: {0}\n".format(lines))
# 输出最多的10个单词及其词频
result = count_most(count)
for k, v in result.items():
f.write("{0}: {1}\n".format(k, v))
`