Python实现wc.exe
github项目传送门:https://github.com/fengoxiao/wc/blob/master/wc.py
项目要求
wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
- 基本功能列表
- -c [文件名] 返回文件的字符数
- -w [文件名] 返回文件词的数目
- -l [文件名] 返回文件的行数
- 扩展功能列表
- -s 递归处理目录下符合条件的文件。
- -a 返回更复杂的数据(代码行 / 空行 / 注释行)。
PSP开发耗时
PSP2.1
|
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
|
Planning |
计划 |
30 | 50 |
|
· Estimate |
· 估计这个任务需要多少时间 |
30 | 50 |
|
Development |
开发 |
600 | 700 |
|
· Analysis |
· 需求分析 (包括学习新技术) |
100 | 180 |
|
· Design Spec |
· 生成设计文档 |
60 | 100 |
|
· Design Review |
· 设计复审 (和同事审核设计文档) |
30 | 30 |
|
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
30 | 30 |
|
· Design |
· 具体设计 |
120 | 60 |
|
· Coding |
· 具体编码 |
210 | 250 |
|
· Code Review |
· 代码复审 |
40 | 30 |
|
· Test |
· 测试(自我测试,修改代码,提交修改) |
100 | 60 |
|
Reporting |
报告 |
80 | 80 |
|
· Test Report |
· 测试报告 |
30 | 40 |
|
· Size Measurement |
· 计算工作量 |
20 | 10 |
|
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
30 | 20 |
|
合计 |
800 | 870 |
设计
主函数思路:通过输入的命令来判断执行各个功能函数,将输入的命令分割为两部分,第一部分是指令,第二部分是文件路径,把两者同时传到command(str,name)函数,用指令来判断需要执行的方法,文件路径作为参数。
词数统计函数:把readLine读取的数据记录下来,用正则表达式把每行的非数字,字母,汉字替换成空格,根据空格切割。
字符统计函数:把readLine读的每行进行长度统计;
行数统计函数:根据python的readLine功能记录,具体的行种类用一段条件判断来实现;
递归处理目录:使用eachFile(path)函数进行递归操作,对每个文件读取全部数据(新增一个-q参数来实现)。

用户使用说明
需求举例:
-q [文件名] 返回该文件的代码行数、字符数、词数、代码数、空行数、注释行数。
-c [文件名] 返回该文件的字符数。
-w [文件名] 返回该文件的代码词数。
-l [文件名] 返回该文件的代码行数。
-s [文件夹] 返回目录下符合条件的全部文件的 -q。
-a [文件名] 返回文件的代码行 / 空行 / 注释行。
代码
项目目录:

功能函数: ``` def parsing_file(f): read= f.readlines() word = [] # 存储单词,得到文章的单词并且存入列表中: chars=0 lines=0 space_lines=0#空行 code_lines=0#代码行 comment_lines=0#注释行 is_comment = False start_comment_line = 0 # 记录以'''或"""开头的注释位置 for line in read: chars+=len(line) lines+=1 line = line.strip() if not is_comment: if line.startswith("'''") or line.startswith('"""'): is_comment = True start_comment_line = lines # 单行注释 elif line.startswith('#'): comment_lines += 1 # 空白行 elif len(line)<=1: space_lines += 1 # 代码行 else: code_lines += 1 # 多行注释已经开始 else: if line.endswith("'''") or line.endswith('"""'): is_comment = False comment_lines += lines - start_comment_line + 1 else: pass line = re.sub(r'[^0-9a-zA-Z\u4E00-\u9FFF]+',' ',line) # 用空格代替一串非数字和字母 line = line.strip() # 除去左右的空格,不能删除中间的。 wo = line.split(' ')# 空格分割单词 word.extend(wo) # 该方法没有返回值,但会在已存在的列表中添加新的列表内容。 return len(word),chars,lines,space_lines,code_lines,comment_lines ```
主函数: ``` def command(str,name): f = open(name,"r") word,chars,lines,space_lines,code_lines,comment_lines= parsing_file(f) if str=='-c': print('字符数',chars) elif str=='-w': print('单词数',word) elif str=='-l': print('行数',lines) elif str=='-s': eachFile(name) elif str=='-a': print('空格行',space_lines) print('代码行',code_lines) print('注释行',comment_lines) elif str=='-q':#读取全部信息 print('字符数', chars) print('单词数', word) print('行数', lines) print('空格行', space_lines) print('代码行', code_lines) print('注释行', comment_lines) ```
扩展功能的-s功能函数: ``` def eachFile(path): pathDir = os.listdir(path) # 获取当前路径下的文件名,返回List for s in pathDir: newDir = os.path.join(path, s) # 将文件命加入到当前文件路径后面 if os.path.isfile(newDir): # 如果是文件 command('-q', newDir) # 读文件 else: eachFile(newDir) # 如果不是文件,递归这个文件夹的路径 ```
测试运行
基础功能总合:
测试文件

为了方便展示功能,我这里直接选择-q,显示全部信息。

拓展功能-s
测试目录

测试结果:

代码覆盖率
进行代码覆盖率测试

总结
因为暑假学习了一段时间python,自己对Java也不是特别熟练,所以决定这次用python进行实践。在实现-s功能的时候,遇到了很多问题,文件路径的传递出现了bug。通过请教同学才成功解决了。通过这次作业,加深了对正则表达式的认知,同时也学会了代码覆盖率这个新知识点,以及开始使用博客进行写作等等,总体来说,这次经历受益匪浅,让我了解到了自己的不足的同时,也学会怎么从零开始一个程序的设计,对时间的安排,对功能的评估等等工程知识,我相信这次的项目作业对我以后的项目开发会有蛮大的帮助的。这次的实践也让我对于python有了更多的热情,通过后续的作业,可以慢慢提高对python的理解。
浙公网安备 33010602011771号