一、GitHub 地址

项目 GitHub 地址为:https://github.com/bytemo/WordCountTool

二、PSP表格

PSP2.1 Personal Software Process Stages 耗时估计值 1(分钟) 耗时估计值 2(分钟) 耗时估计值 3(分钟) 实际耗时(分钟)
Planning 计划 20 20 20 30
· Estimate · 估计这个任务需要多少时间 20 20 20 30
Development 开发 690 665 715 770
· Analysis · 需求分析 30 30 30 30
· Design Spec · 生成设计文档 60 50 50 50
· Design Review · 设计复审 20 20 20 40
· Coding Standard · 代码规范 20 15 20 20
· Design · 具体设计 70 60 65 60
· Coding · 具体编码 360 360 400 480
· Code Review · 代码复审 30 30 30 30
· Test · 测试(自我测试,修改代码,提交修改) 100 100 100 60
Reporting 报告 130 140 140 135
· Test Report · 测试报告 70 70 70 65
· Size Measurement · 计算工作量 20 20 20 30
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 40 40 40 40
合计 840 825 875 935

三、题目设计思路

这个题目不是很复杂,看了一遍题目之后,心里大概就想得七七八八了,只剩下一些流程和细节的选型需要斟酌和确定。

首先,WordCount 工具实现的功能是统计文件的字符数、单词数、行数等基本统计信息,并且能统计某程序设计语言源文件的字符数、单词数和行数。同时,还要能够支持其他扩展功能以及快速处理多个文件。

看到这里,就已经大致清晰了,这个程序的关键在于文件操作和文本处理。

  1. 开发语言的选用

这是个非常轻量级的需求,所以我决定选用 Python 语言作为开发语言,既比 C/C++ 更加简便易行,也比 Java 等语言更轻盈。开发语言的选用需要考虑到运行场景。

wc 程序只是一个简单的文件统计工具,如果使用 Java 等语言来开发,那么光是 Java 虚拟机的启动时间,都足够用 C/C++ 或者 Python 实现的版本运行完毕十几次了,实在是过于臃肿,杀鸡用牛刀,完全没有必要。

如果采用 C/C++ 开发的话,由于更加底层,在处理高级需求的时候,比如扩展图形界面等,会十分繁琐复杂。而选用 Python 的话,既能利用丰富的 Python 生态,加速开发,还能使产品具备广泛跨平台等特性,且性能不会下降太多。

综合上述考虑,我觉得选用 Python 作为本次个人项目的开发语言。

  1. 模块设计

还是那个原因:这是一个非常简单轻量级的软件,因此我没有采用面向对象的编程思想,传统的面向过程的设计方式就已经足够。在这么一个简单小型的软件上,强行采用面向对象的设计思想,会变得“为了面向对象而面向对象”,导致在实际上并不能实现面向对象的诸多优点,反而会弄巧成拙,使程序模块设计变得更加混乱或者会影响软件的运行效率。

但是为了兼顾扩展性,我又在面向过程的基础上,借助了 Python 语言的特性,做了模块的划分。从而使得能够轻易地加入新的解析器模块,具备非常好的扩展性。

我把程序按照 主程序 + 解析器 的思路做了模块拆分,主程序解析了参数之后,根据文件类型以及控制参数,去执行不同的操作、调用不同的解析模块。并且由于 Python 语言的特性,很容易做到支持解析器模块 “热拔插” 的效果。

  1. 主要流程设计

经过前面的思考后,对程序的大致处理流程的思路也就自然而然浮现出来了。

首先是获取命令行参数,通过对参数的解析,来决定下一步要执行的操作,比如解析到 -x参数后启动图形界面。并且要注意参数解析到顺序,比如应当优先解析-x参数,因为启动了图形界面之后就与命令行的处理流程大不相同了。

解析完参数之后,调用不同的函数过程,去进行处理。

至此,大致的设计思路已经思考完毕,可以开始落实了。

四、设计实现过程

  1. 整体模块设计

按照上文中描述的模块划分,设计出如下的模块架构:

关键函数调用关系流程图:

  1. 参数解析

参数的解析是整个程序的第一个流程,也是入口主模块的主要功能组成。

由于函数过长,因此就不贴出代码了,主要讲述一下实现国产,详细代码青岛 Github 中查看。

对于命令行参数的解析,首先通过 os 模块取得参数,再借助 getopt 模块进行统一处理,得到所有符合格式的控制参数列表,以及文件名列表(在我的设计中,支持一次性处理无限多个文件)。如果出现错误的参数,则会报错:错误的参数!

接下来按照各个参数不同的优先级来处理参数,首先处理的是-x参数,如果存在该参数,则唤起图形界面,同时忽略对其他命令参数的处理。

接着判断是否提供了一个以上的文件名,如果没有,则报错:未提供目标文件名!如果已经提供,则检查-s参数。如果-s参数已提供,则开始递归遍历当前目录及其子目录下符合条件的文件,将其纳入待处理的文件名列表中去。如果没有提供-s参数,则将命令行参数中的文件名列表直接作为待处理的文件名列表。

  1. 文件列表处理

接下来循环遍历待处理的文件名列表。处理过程如下:

首先对文件名进行处理,分割出文件类型(根据后缀名进行判断),接着回去检查解析器模块目录里有没有对应这个文件类型的解析器模块,如果没有,则会报错:暂不支持此文件格式的解析!如果有对应的解析器,则将剩余未处理的控制参数列表和当前文件对象一起移交给对应的解析器模块去处理,并将处理的结果输出到命令行。

  1. 解析器模块的实现

解析器是一个单独的模块,即一个单独的 py 文件,存放在特定的解析器目录中。所有被放入这个目录的 py 文件都被视为解析器,在文件处理时呗热加载到 wc 程序中。因此只需要将一个解析器放入或者移出目录中,即可完成热拔插操作,扩展性极好。

解析器模块会拿到调用方主模块传递过来的文件对象和控制参数。

接下来,解析器会逐个逐个读入字符或者行,解析并统计其中的字符数、单词数、行数以及更高级的代码行数、注释行数和空行数等数据。

有了统计结果,接下来解析器会根据控制参数列表来决定返回哪一些统计结果给调用方。比如控制参数列表是 -c、-w,那么解析器将会返回字符数和单词数给调用方,其他的数据由于控制参数的影响而不会返回。

  1. 图形界面的实现

图形界面采用 Python 原生的 tkinter GUI 图形库实现。

首先会加载一个窗口,窗口包含一个按钮,用户点击这个按钮之后,会弹出一个文件选择框。用户选择了有效的文件之后,会调用对应的解析器模块进行处理,并将处理的结果显示在图形窗口中。

五、测试

为了便于测试,我便写了一个单独的测试模块,能够对所有功能进行半自动化的测试(只允许测试,而不比对结果,所以称为半自动化)。

测试结果如下:

  • 基本功能

  • 扩展功能

  • 高级功能

六、总结

通过这次个人项目,我从中体会到了软件工程的一些思想。比如需求分析,比如代码复审等。这是我第一次用软件工程的方式和思想来完成一个项目,中间不能说不艰辛。从最初的 PSP 表格的填写,到其中的开发,再到博客的撰写,大部分所花费的时间与 PSP 表格中的估计相差不小。这说明了我对自身能力的了解还相当不足,暴露了自身较多的问题。

同时,项目中还有不少可以改进的地方,比如可以通过建立测试样本和标准结果库,从而实现完全的自动化测试,并且通过编辑器的配置,实现编译的时候自动调用测试脚本,免去手动调用测试脚本的麻烦,让测试更加自动化。

希望以后再接再厉!

【软件工程第二次作业】个人项目:WordCountPy的更多相关文章

  1. 第二次作业——个人项目实战(sudoku)

    第二次作业--个人项目实战(sudoku) 一.作业要求地址 第二次作业--个人项目实战 二.Github项目地址 softengineering1--sudoku 三.PSP表格估计耗时 PSP2. ...

  2. 集大1513 & 1514班 软件工程第二次作业评分与点评

    谢谢按时完成作业的同学. 请大家在今后的作业中多思考,认真完成并注意作业的原创性. 学号 作业标题 作业地址 提交日期 分数 201521121087 微信APP简要分析 http://www.cnb ...

  3. 软件工程 - 第二十次作业 Alpha 事后诸葛亮(团队)

    Alpha 事后诸葛亮(团队) 组长本次作业链接:https://www.cnblogs.com/dawnduck/p/10056026.html 现代软件工程 项目Postmortem 设想和目标 ...

  4. 软件工程第二次作业——git的使用

    1. 参照 http://www.cnblogs.com/xinz/p/3803109.html 的第一题,每人建立一个GitHub账号,组长建立一个Project,将本组成员纳入此Porject中的 ...

  5. 17秋 软件工程 第二次作业 sudoku

    2017年秋季 软件工程 作业2:个人项目 sudoku Github Project Github Project at Wasdns/sudoku. PSP Table PSP2.1 Person ...

  6. 第二次作业——个人项目实战(Sudoku)

    Github:Sudoku 项目相关要求 利用程序随机构造出N个已解答的数独棋盘 . 输入 数独棋盘题目个数N 输出 随机生成N个 不重复 的 已解答完毕的 数独棋盘,并输出到sudoku.txt中, ...

  7. 软件工程第二次作业——Java学习路线

    我的第二次软工作业 过去我对自己所学和想学都很迷茫,以至于学得总是一知半解,但现在我想主攻Java方向,并坚定不移地走下去(之后拓展其他方面就是以后的事情了).之所以想主攻Java方向是因为Java本 ...

  8. 软件工程第二次作业-VSTS单元测试

    一.选择开发工具 开发工具选择 Visual studio 2017 社区版,开发语言为C 由于之前已经安装完毕,所以不上传安装过程,主界面如下: 二.练习自动单元测试 使用的测试工具是VSTS,具体 ...

  9. 2019软件工程第二次作业(VS2017中对C++的单元测试)

    建立工程,分别编写cpp和头文件 cpp文件中的代码如下: #include<iostream> #include"test.h" using namespace st ...

随机推荐

  1. day44_9_3前端(1)

    一.http协议. 1.在软件开发架构中 有两种模式:1.b/s.2.c/s. 其中b/s就是以浏览器作为客户端,所以,需要服务器同一遵循同一规则,向浏览器发送数据,这个规则就是http协议,存在以应 ...

  2. 【视频技术】ffmpeg截取图片(Mac)

    1. 输出单张图片:ffmpeg -i NLP-CNN.mp4 -f image2 -ss 2000 -vframes 1 -s 220*220 NLP-CNN-003.jpg 2. 输出所有图片: ...

  3. Java 高级面试题收集

    Java概念题 拆箱装箱的原理 自动装箱时编译器调用valueOf将原始类型值转换成对象,同时自动拆箱时,编译器通过调用类似intValue(),doubleValue()这类的方法将对象转换成原始类 ...

  4. 7 Exciting Uses of Machine Learning in FinTech

    https://rubygarage.org/blog/machine-learning-in-fintech Machine learning (ML) has moved from the per ...

  5. CF306C White, Black and White Again

    CF306C White, Black and White Again 洛谷评测传送门 题目描述 Polycarpus is sure that his life fits the descripti ...

  6. .NET三种异步模式(APM、EAP、TAP)

    APM模式: .net 1.0时期就提出的一种异步模式,并且基于IAsyncResult接口实现BeginXXX和EndXXX类似的方法. .net中有很多类实现了该模式(比如HttpWebReque ...

  7. ajax与重定向

    网上有不少说法ajax的请求url浏览器不会重定向的说法是片面的,正常是这样的: 当服务器将302响应发给浏览器时,浏览器并不是直接进行ajax回调处理,而是先执行302重定向——从Response ...

  8. KMP 串的模式匹配 (25分)

    给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出.如果找不到,则输出“Not ...

  9. oracle--10GRAC集群搭建问题OUI-25031

    一,问题描述 安装RAC的过程中在结束 的阶段出现的错误 02,解决方式 这个可能在root.sh 执行的时候报错 由于版本问题: 修改vim /etc/redhat-release 把6.9改为4. ...

  10. 基于Redis实现分布式定时任务调度

    项目开发过程中,难免会有许多定时任务的需求进来.如果项目中还没有引入quarzt框架的情况下,我们通常会使用Spring的@Schedule(cron="* * * * *")注解 ...