Document
WordCount (Python)
Github Pages:
一、题目描述
- 实现一个简单而完整的软件工具(源程序特征统计程序)。
- 进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具。
- 进行个人软件过程(PSP)的实践,逐步记录自己在每个软件工程环节花费的时间。
二、WC 项目要求
- wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
- 实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
- 具体功能要求:程序处理用户需求的模式为:wc.exe [parameter] [file_name]
三、代码分析
- 模块
# Argparse 从控制台获取输入参数
from argparse import ArgumentParser
# re 正则匹配 from re import findall, M, compile, match
# os 获取文件信息 from os import path, listdir
- 关键函数
if self.args.c: # 输入参数 'C', 输出字符数 char_num = len(f_read.replace(" ", "").replace("\n", "")) self.info.append(base_name + " --Char: " + str(char_num)) if self.args.w: # 输入参数 'W', 输出单词数
word_num = len(findall(r'[a-zA-Z]+', f_read, M)) self.info.append(base_name + " --Word: " + str(word_num))
# 输入参数 'l' 输出行数 if self.args.l: line_num = len(f_readline) self.info.append(base_name + " --lines: " + str(line_num)) for line in f_readline: # 统计注释行 空行 代码行 if "/*" in line: note_count = note_count + 1 flag = True if "*/" in line: flag = False elif flag: note_count = note_count + 1 if "*/" in line: flag = False elif "//" in line: note_count = note_count + 1 elif len(line.strip()) > 1: code_count = code_count + 1 else: space_count = space_count + 1
# 递归查询文件 支持简单正则 if '*' in file_name: if '.' in file_name: match_format = compile('{}{}'.format(file_name.replace('.', '\.').replace('*', '\w+'), '$')) for file in listdir(dir_path): if match(match_format, file): self.file_list.append(path.join(dir_path, file)) elif '?' in file_name: if '.' in file_name: match_format = compile('{}{}'.format(file_name.replace('.', '\.').replace('*', '\w'), '$')) for file in listdir(dir_path): if match(match_format, file): self.file_list.append(path.join(dir_path, file)) if len(self.file_list) == 0: if path.exists(self.args.directory): self.file_list.append(self.args.directory)
# 默认比较参数调用 args = parse_test() if args.x: # Set default args.c = True args.w = True args.l = True args.a = True args.directory = "" gui.GUI(args) else: wc = WC(args) wc.main()
- GUI Code
# 选择文件 self.files, files_type = QFileDialog.getOpenFileNames() if len(self.files) > 0: # When select single file if len(self.files) == 1: self.wc_exe.args.directory = self.files[0] # When select dual file else: self.wc_exe.flag = False self.wc_exe.args.directory = self.files[0] for file in self.files: self.wc_exe.file_list.append(file) info = self.wc_exe.main() # Clear previous chosen file to avoid twice-detection self.wc_exe.file_list.clear() self.textbox.setText("\n".join(info)) else: self.textbox.setText("File not selected")
四、项目测试
五、PSP
PSP2.1 | Estimated time consuming(minutes) | Actual time consuming(minutes) |
Planning | 60 | 90 |
-- Estimate | 60 | 90 |
Development | 255 | 440 |
-- Analysis | 50 | 90 |
-- Design Spec | 15 | 20 |
-- Design Review | 5 | 5 |
-- Coding Standard | 5 | 5 |
-- Design | 30 | 60 |
-- Coding | 120 | 200 |
-- Code Review | 30 | 60 |
Test | 75 | 135 |
- Reporting | 20 | 25 |
- Test Report | 10 | 30 |
- Size Measurement | 15 | 20 |
- Postmortem & Process Improvement Plan | 30 | 60 |
Total | 390 | 665 |
六、总结
- 尚未形成psp流程的操作习惯,发现的确有助于提高开发效率.意识到接下来每次写项目都应该有相关的操作习惯
- 具体项目exe可以用pyinstaller执行 pyinstaller wc.py -p gui.py执行,值得注意的是多个文件不可以用Pyinstaller打包成单个exe文件.
- 遇到pip下载过慢的问题可以尝试切换pip源 或者 更改pip config走的流量通道为代理解决