python 实现wc,exe

GitHub地址:https://github.com/LliXxiaoYyang/pyworkspace

项目要求:

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

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

wc.exe [parameter] [file_name]

 

 

基本功能列表:

wc.exe -c file.c     //返回文件 file.c 的字符数            (实现)

wc.exe -w file.c    //返回文件 file.c 的词的数目         (实现)

wc.exe -l file.c      //返回文件 file.c 的行数                (实现)

 


扩展功能:
    -s   递归处理目录下符合条件的文件。                  (实现)
    -a   返回更复杂的数据(代码行 / 空行 / 注释行)。(实现)

空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。

代码行:本行包括多于一个字符的代码。

注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:

    } //注释
在这种情况下,这一行属于注释行。

[file_name]: 文件或目录名,可以处理一般通配符。

高级功能:

 -x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。

需求举例:
  wc.exe -s -a *.c                                                 (未实现)


返回当前目录及子目录中所有*.c 文件的代码行数、空行数、注释行数。

解题思路:

完成wc的思路如下:

    1、先获取命令,读取输入的文件路径及文件名;

    2、打开文件,获取文件内容,并对其做处理:

         a、获取字符数;

         b、获取行数;

         c、获取单词数;

    3、进一步获取输入命令,例如-c 123,.txt,,前面是对应命令,后面是文件路径文件名,用空格隔开;

    4、添加扩展内容,遍历文件夹;代码数,注释,空白行数。

设计流程:

 

 代码说明:

对读入的文件进行字符,单词,行的计数。字符的计数是直接计算文本内容的长度;单词数是利用正则表达式将非字母,数字,下划线的字符都替换成空格,再将下划线也替换成空格,最后用split划分空格,从而得出单词数;行数则是通过数 ‘\n’ 换行符加一得出。

 1  def getCharsCount(data):
 2         chars: int = len(data)
 3         print ('字符数:',chars)
 4 
 5  def getWordsCount(data):
 6          data0 = re.sub("\W"," ",data,count=0)
 7          data1 = re.sub ("_"," ",data0,count=0)
 8          words = len(data1.split())
 9          print ('单词数:',words)
10 
11  def getLinesCount(data):
12         lines = data.count('\n')+1
13         print( '行数:',lines)

递归遍历文件夹,先是用os.path.isdir()判断是否文件夹,是的话遍历文件夹,若里面还有文件夹,则递归遍历,读取文件内容,并打印出其字符数,单词数和行数;若不是文件夹,则输出错误信息。

 1     def recursiveDir(filePath):
 2         if  os.path.isdir(filePath):
 3           fileList = os.listdir(filePath)
 4           for file in fileList:
 5             newpath = filePath + '/' + file
 6             if os.path.isdir(newpath):
 7                 Count.recursiveDir(newpath)  # 递归
 8             if os.path.isfile(newpath):
 9                 try:
10                     data = open(newpath, 'r')
11                     data1 = data.read()
12                     data.close()
13                     print(newpath)
14                     Count.getCharsCount(data1)
15                     Count.getLinesCount(data1)
16                     Count.getWordsCount(data1)
17                 except:
18                     print('this file can not be opened')
19         else :
20             print('please input the path of folder!')

输出特殊行数:用每一行若为空字符则是空行,若以 ‘#’、‘//’开始的函数则是注释行,其余为代码行。

 1     def special_linenum(file):
 2         with open(file) as fp:
 3             content_list = fp.readlines()
 4             code_num = 0
 5             blank_num = 0
 6             annotate_num = 0
 7             for content in content_list:
 8                 content = content.strip()
 9                 # 统计空行
10                 if content == '':
11                     blank_num += 1
12                 # 统计注释行
13                 elif content.startswith('#') or content.startswith('//'):
14                     annotate_num += 1
15                 # 统计代码行
16                 else:
17                     code_num += 1
18         print('空白行:',blank_num)
19         print('注释行:',annotate_num)
20         print('代码行:',code_num)

主函数:从控制台获取输入信息,用空格分出命令和文件名两部分,存入列表,分别进行处理。其中,open()函数是Python打开文件的函数,若是可读文件,则顺利打开,若是不可读文件,则输出错误信息。

 1 def main():
 2     while True :
 3        str = sys.stdin.readline()
 4        list = str.split()
 5        filePath = list[1][0:len(str) - 1]
 6        if list[0]=='-s':
 7           Count.recursiveDir(filePath)
 8        elif list[0]=='-a':
 9           Count.special_linenum(filePath)
10        else :
11           if os.path.exists(filePath):
12               file = open(filePath, 'r')
13               data = file.read()
14               file.close()
15               if list[0] == '-c':
16                   Count.getCharsCount(data)
17               if list[0] == '-l':
18                   Count.getLinesCount(data)
19               if list[0] == '-w':
20                   Count.getWordsCount(data)
21 
22           else:
23               print('This is not a valid path or file ')

测试:

 1、一个空白文件:

2、一个字符的文件:

3、一行的文件:

4、带注释行的文件:

5、递归遍历文件夹:

 

 

 PSP2.1表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 20  60

· Estimate

· 估计这个任务需要多少时间

 240  480

Development

开发

 150 200 

· Analysis

· 需求分析 (包括学习新技术)

 15  25

· Design Spec

· 生成设计文档

 15  25

· Design Review

· 设计复审 (和同事审核设计文档)

 15  10

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

 10  20

· Design

· 具体设计

 20  30

· Coding

· 具体编码

 120  240

· Code Review

· 代码复审

 20  15

· Test

· 测试(自我测试,修改代码,提交修改)

 20  30

Reporting

报告

 20 40 

· Test Report

· 测试报告

 10  15

· Size Measurement

· 计算工作量

 15  20

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

 10  20

合计

   700  1230

 

个人总结:

刚学习了Python不久就布置了这个项目,便想试试看能不能用Python实现,想试试自己的能力。但是由于对Python还不熟悉,算是困难重重,基本每个函数都得去百度查找其用法。一开始想到命令行参数可以用Python的opt模块实现,但是发现打包成exe应用程序是不能用,只能直接用命令窗口运行py文件,再在里面运行,所以就放弃了这个方便好用的模块,就想着自己写吧。虽然说最后把任务完成了,但是还有很多不足。接下来还需要更加认真的学习Python。

posted on 2018-09-14 14:47  LliXxiaoYyang  阅读(57)  评论(0)    收藏  举报

导航