zoukankan      html  css  js  c++  java
  • WordCount——文本计数器的GUI实现(python)

    github-> https://github.com/foolishkylin/WordCount

    WordCount


    项目需求

    ​ WordCount是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。WordCount须有清晰直观的GUI界面。
    规则是:
    ​ 空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
    ​ 代码行:本行包括多于一个字符的代码。
    ​ 注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:} //注释
    ​ 在这种情况下,这一行属于注释行。

    对于一个或多个文件,须统计*.c 文件的代码行数、空行数、注释行数。


    PSP

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 5 4
    · Estimate · 估计这个任务需要多少 5 4
    Development 开发 465 432
    · Analysis · 需求分析 (包括学习新技术) 20 16
    · Design Spec · 生成设计文档 20 12
    · Design Review · 设计复审 (和同事审核设计文档) 10 2
    · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 5 2
    · Design · 具体设计 20 30
    · Coding · 具体编码 300 330
    · Code Review · 代码复审 30 10
    · Test · 测试(自我测试,修改代码,提交修改) 60 30
    Reporting 报告 100 56
    · Test Report · 测试报告 20 16
    · Size Measurement · 计算工作量 20 10
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 30
    合计 570 492

    需求分析

    1. 开发技术需求:

      名称 描述
      python 基础开发 完成软件的逻辑部分
      python GUI开发 完成软件的图形化部分
      python 打安装包 将软件打包成安装包
      单元测试 进行软件的单元测试
    2. 项目功能需求:

    名称 描述 备注
    统计单文件特征 统计单个文件的字符数、单词数、行数(代码行、空行、注释行) 应包含统计用时
    统计多个文件 统计统一目录下的所有文件特征 文件格式应有要求

    解题思路

    ​ 拿到项目要求后,首先分析需求。WC的核心逻辑需求是统计文件的各项特征,统计特征不难,可能难的是文件io,需求里以.c文件为例,但后续可以拓展到其他源文件。其次的前端需求是做控制台传参或者GUI操作,笔者选择了后者。

    ​ 对于逻辑需求,需要去学习文件的io操作、统计特征。

    ​ 对于前端需求,需要学习python的GUI开发

    ​ 但完成前两部分还不够,我们需要对项目进行回归测试,笔者预备在项目在初步开发后进行。


    设计思路

    ​ 具体首先将分成两层,逻辑层和GUI层。逻辑层负责实现项目的核心逻辑,GUI层负责实现项目的GUI界面。

    ​ 大致实现思路是先完成逻辑层,再实现GUI层。

    ​ 先按照功能实现逻辑层的两个函数:单文件统计和多文件统计,其中多文件统计类同于单文件统计循环调用。

    ​ 再实现GUI层的基本ui,然后在此基础上通过信号槽来与逻辑层相连。


    代码说明

    下面给出单c/c++源文件的统计函数

    def count_single_file(file_path):
        """
    
        :param file_path:
        :return:
        """
        text = '文件: ' + file_path + '
    '
        start = time.perf_counter() # 开始计时
        fr = open(file_path)
        ltext = fr.readlines() # 读文件
        dcount = {
            'cchar': 0,
            'cword': 0,
            'cline': len(ltext),
            'cempty_line': 0,
            'ccode_line': 0,
            'ccomment_line': 0,
            'cost_time':0.0
        } # 初始化统计字典
        comment_block = False # 设置验证/**/的布尔值
    
        for line in ltext:
            # 开始统计
            dcount['cchar'] += len(line) # 统计字符数
            dcount['cword'] += len(line.split(' ')) # 统计单词数
    
            if len(line.strip('
    ')) <= 1:
                # check empty line
                dcount['cempty_line'] += 1 # 是否为空行
                continue
    
            code_check1 = line.split('//')[0]
            code_check2 = line.split('/*')[0]
            if len(code_check1.strip('
    ')) > 1 or len(code_check2.strip('
    ')) > 1:
                # check code line
                dcount['ccode_line'] += 1 # 是否为代码行
                continue
    
            # check comment line
            if line.find('//') != -1:
                dcount['ccomment_line'] += 1 # 是否为//类注释
                continue
            if line.find('/*') != -1:
                comment_block = True # 是否为/**/类注释
            if comment_block:
                # check "**"
                dcount['ccomment_line'] += 1
            if line.find('*/') != -1:
                comment_block = False # 是否/**/注释结束
    
        dcount['cost_time'] = time.perf_counter() - start # 计时结束
        zh_names = ['字符数', '单词数', '总行数', '空行数', '代码行数', '注释行数', '耗时']
        en_names = ['cchar', 'cword', 'cline', 'cempty_line', 'ccode_line', 'ccomment_line', 'cost_time']
        for it in range(len(zh_names)):
            # 生成结果文本
            text += (zh_names[it] + ': ' + str(dcount[en_names[it]]))
            if it != len(zh_names) - 1:
                text += '
    '
            else:
                text += 's
    
    '
    
        return text, dcount['cost_time']
    

    以上代码在GUI中的输出如下:


    测试运行

    • 回归测试

      在本项目中,笔者构建了对同一目录下的同类文件进行统计的功能,以此我们可以进行批量的回归测试。测试结果如下:

    统计结果:
    文件: E:/depot/WordCount/sample/one_line.c
    字符数: 18
    单词数: 2
    总行数: 1
    空行数: 0
    代码行数: 1
    注释行数: 0
    耗时: 0.00019949999999990808s
    
    文件: E:/depot/WordCount/sample/one_word.c
    字符数: 4
    单词数: 1
    总行数: 1
    空行数: 0
    代码行数: 1
    注释行数: 0
    耗时: 0.00017739999999921707s
    
    文件: E:/depot/WordCount/sample/sample.c
    字符数: 46
    单词数: 10
    总行数: 7
    空行数: 4
    代码行数: 3
    注释行数: 0
    耗时: 0.00016929999999959477s
    
    
    -----------------------------------------
    总耗时: 0.0009594999999995579s
    

    由上述可知,初步的回归测试是成功的。

    • 标准测试集测试

      类似地,笔者使用了多文件统计的功能,对一系列c++文件(来源于笔者之前写过的代码)进行统计。结果如下

      s_result

    统计结果:
    文件: E:/depot/WordCount/sample/basis.cpp
    字符数: 4212
    单词数: 489
    总行数: 237
    空行数: 64
    代码行数: 173
    注释行数: 0
    耗时: 0.3017877999999996s
    
    文件: E:/depot/WordCount/sample/clock.cpp
    字符数: 262
    单词数: 26
    总行数: 14
    空行数: 4
    代码行数: 10
    注释行数: 0
    耗时: 0.00027199999999538704s
    
    文件: E:/depot/WordCount/sample/elevator.cpp
    字符数: 19430
    单词数: 2019
    总行数: 668
    空行数: 62
    代码行数: 606
    注释行数: 0
    耗时: 0.0016401000000030308s
    
    文件: E:/depot/WordCount/sample/list.cpp
    字符数: 2083
    单词数: 247
    总行数: 110
    空行数: 21
    代码行数: 89
    注释行数: 0
    耗时: 0.0005341000000100848s
    
    文件: E:/depot/WordCount/sample/main.cpp
    字符数: 56
    单词数: 10
    总行数: 7
    空行数: 3
    代码行数: 4
    注释行数: 0
    耗时: 0.00036660000000665605s
    
    文件: E:/depot/WordCount/sample/peopel.cpp
    字符数: 4833
    单词数: 511
    总行数: 162
    空行数: 29
    代码行数: 133
    注释行数: 0
    耗时: 0.0006900999999857049s
    
    文件: E:/depot/WordCount/sample/queue.cpp
    字符数: 1501
    单词数: 171
    总行数: 90
    空行数: 22
    代码行数: 68
    注释行数: 0
    耗时: 0.0004983999999979005s
    
    
    -----------------------------------------
    总耗时: 0.30578909999999837s
    
    
    拓展需求

    ​ 在本项目中,笔者设计了多种源代码统计格式(目前有c和c++,后续可以拓展),以此来对不同文件的注释进行统计。


    项目小结

    ​ 综合PSP表来看,大体上都在预期时间内完成,但是仍有一些意外。在实现好各项功能后,笔者在打包程序这里遇到了一些难题,通过github的pr找到了可能的原因:打包环境内部的版本可能不兼容。后来通过新建一个虚拟环境解决。

    ​ 这也给了我一个教训,在实现前,要确认好环境的配置问题,确保不会卡在这里。

    ​ 另:笔者在github项目的dist下上传了可执行文件,有兴趣的读者可以去下载试试。


    程序使用说明

    对于单文件统计,先选择统计格式,在选择文件。选择好后即进行统计。

    对于多文件统计,同样选择统计格式。然后选择文件夹路径,选择好后即开始统计文件。

  • 相关阅读:
    python解压缩rar,zip文件的正确姿势
    tensorflow1.x及tensorflow2.x不同版本实现验证码识别
    qt5.6.3下使用firebird
    Python3.6下的Requests登录及利用Cookies登录
    c++实现全密码生成
    android中利用HttpURLConnection进行Get、Post和Session读取页面。
    Freebsd10.3 Nginx多版本PHP
    Freebsd10.3(FreeBSD11 Beta1)使用手记
    Eclipse导入的User Libarary
    MySQL zip版本安装
  • 原文地址:https://www.cnblogs.com/rosehip/p/12485268.html
Copyright © 2011-2022 走看看