Python实现wc.exe

github项目传送门:https://github.com/fengoxiao/wc/blob/master/wc.py

项目要求

wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。

实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。

  • 基本功能列表
  1.   -c    [文件名]  返回文件的字符数
  2.   -w   [文件名]  返回文件词的数目
  3.   -l     [文件名]  返回文件的行数
  • 扩展功能列表
  1.   -s   递归处理目录下符合条件的文件。
  2.   -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

测试目录

测试结果:

 

 

代码覆盖率

进行代码覆盖率测试

![](https://img2018.cnblogs.com/blog/1484680/201809/1484680-20180913201320713-1957070996.png)

 

总结

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

 

posted @ 2018-09-13 14:58  风o萧  阅读(166)  评论(0)    收藏  举报