GitHub地址

https://github.com/jiaxuansun/wordcount

PSP表格

PSP PSP阶段 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 10 5
·Estimate 估计这个任务需要多少时间 10 5
Development 开发 510 500
·Analysis 需求分析 (包括学习新技术) 40 30
·Design Spec 生成设计文档 20 20
·Design Review 设计复审 (和同事审核设计文档) 10 10
·Coding Standard 代码规范 (为目前的开发制定合适的规范) 10 10
·Design 具体设计 30 30
·Coding 具体编码 300 240
·Code Review 代码复审 40 40
·Test 测试(自我测试,修改代码,提交修改) 60 120
Reporting 报告 70 80
·Test Report 测试报告 30 40
·Size Measurement 计算工作量 10 10
·Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 30 30
合计 590 585

解题思路

对整体程序的功能需求进行划分如下:

  • 参数分析功能:判断命令行的参数,保存所做的选项,并根据选项执行相应的命令,然后输出的结果

  • 查找文件功能:查找输入的文件需要支持如"*.c"等简单匹配符,在有-s选项的情况下,需要在当前目录下递归查找文件

  • 基本计数功能:实现课设基本功能要求的计算文件字符数、行数、单词数的功能

  • 代码计数功能:实现课设扩展功能要求的计算文件代码行数、空行数、注释行数的功能

根据功能复杂程度选择Python语言完成作业

程序设计实现

根据分析结果将代码分为如下几个模块:

  • 入口代码:设定所需要支持的参数内容
  • main函数:查找目录下所有的目标文件,对每一个文件调用基本功能函数和扩展功能函数,并将结果返回;若选择-s选项,则递归查找当前目录下的各个目录
  • wordcount函数:实现课设要求的基本功能
  • codecount函数:实现课设要求的扩展功能

代码说明

入口和标准库的参数解析对象初始化:

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="word count")
parser.add_argument("-o", "--output", type=str, default="result.txt")
parser.add_argument("-c", "--bytes", action="store_true")
parser.add_argument("-w", "--words", action="store_true")
parser.add_argument("-l", "--lines", action="store_true")
parser.add_argument("-s", "--recursive", action="store_true")
parser.add_argument("-a", "--code", action="store_true")
parser.add_argument("-e", "--stoplist", type=str)
parser.add_argument("filename", type=str)
args = parser.parse_args()
result = main(args, os.getcwd())
print_result(args, result)

查找目录并根据不同的参数来调用不同的功能函数:

def main(args, rootpath):
result = []
filename = args.filename.replace("*", "\\w*")
if args.recursive:
for name in os.listdir(rootpath):
path = os.path.join(rootpath, name)
if os.path.isdir(path):
result += main(args, path)
elif re.findall(filename, name):
fd = open(path)
wc = wordcount(fd.read())
if args.stoplist:
fd.seek(0)
content = fd.read()
stoplist = open(args.stoplist)
stopchars = stoplist.read().split()
count = 0
for c in stopchars:
count += len(re.findall(c, content))
r["words"] -= count
stoplist.close()
if args.code:
fd.seek(0)
wc.update(codecount(fd))
wc["filename"] = name
result.append(wc)
fd.close()
else:
for name in os.listdir(rootpath):
path = os.path.join(rootpath, name)
if os.path.isdir(path):
pass
elif re.findall(filename, name):
fd = open(path)
wc = wordcount(fd.read())
if args.stoplist:
fd.seek(0)
content = fd.read()
stoplist = open(args.stoplist)
stopchars = stoplist.read().split()
count = 0
for c in stopchars:
count += len(re.findall(c, content))
r["words"] -= count
stoplist.close()
if args.code:
fd.seek(0)
wc.update(codecount(fd))
wc["filename"] = name
result.append(wc)
fd.close() return result

基本功能实现:

def wordcount(content):
print(re.split(r"[\s,]+", content))
result = {
"words": len(re.split(r"[\s,]+", content))-1, # 单词数
"lines": len(content.split('\n'))-1, # 行数
"bytes": len(content)-1 # 字符数
} return result

扩展功能实现

def codecount(fd):
codelines = 0
blanklines = 0
commentlines = 0
isComment = False
isString = False
isCode = False
for line in fd.readlines():
line = line.strip().replace('{', '').replace(
'}', '').replace(';', '') # 去掉{};以便计算空行
if not isComment and not line:
blanklines += 1
continue
if isComment:
commentlines += 1
elif line.replace('/', '').replace('*', ''):
codelines += 1
line = '\n'+line+'\n'
for i in range(1, len(line)):
if line[i] == '"' and line[i-1] != '\\':
isString = not isString
if not isString:
if line[i] == '/' and line[i+1] == '/' and not isComment:
if not line[:i].split():
blanklines += 1
commentlines += 1
break
if line[i] == '/' and line[i+1] == '*' and not isComment:
isComment = True
commentlines += 1
i += 1
if line[i] == '*' and line[i+1] == '/':
isComment = False
i += 1 result = {
"codelines": codelines,
"blanklines": blanklines,
"commentlines": commentlines
} return result

测试设计过程

如何设计测试用例

测试时应重点考虑边界值以及特殊情况,使测试用例最大程度覆盖代码。

思想是使每一个判断语句都执行一遍,实现条件覆盖,尽量让每一个判断语句在是与否的情况下都能执行一遍,实现语句覆盖。

哪些地方会导致程序高风险

当输入文件内容为空或输入大于文件内容的边界时会导致程序高风险

测试代码设计

  • test1.c
File write,name = new File(outputPath);
writename.createNe|wFile();
Buffe,redWriter out = new BufferedWrit,er(new FileWriter(writename));
out.close();

测试字符数统计

  • test2.c
test()
{
File writename = new File(outputPath);
writename.createNewFile();
codeLine */
BufferedWriter out = new BufferedWriter(new FileWriter(writename));
// note line
out write(outputBuffer);
/* noteLine
/* noteLine
*/
/* noteLine */
/* noteLine
// noteLine
*/
out.flush();
out.close();
}
// noteLine
for(){}/* noteLine */

测试代码行数、注释行数、空行数统计

  • test3.c
test()
{
File writename = new File(outputPath);
writename.createNewFile();
codeLine */
BufferedWriter out = new BufferedWriter(new FileWriter(writename));
// note line
out write(outputBuffer);
/* noteLine
/* noteLine
*/
/* noteLine */
/* noteLine
// noteLine
*/
out.flush();
out.close();
} // noteLine
for(){
}/* noteLine */

测试单词数、行数统计

  • end.txt
for
new
out
  • 测试递归查找文件:文件夹test1,其中有一个test3.c文件,选择-s选项测试即可

-测试命令:

wordcount.exe

wordcount.exe -c test1.c

wordcount.exe -w test3.c

wordcount.exe -l test3.c

wordcount.exe -a test2.c -o testout1.txt

wordcount.exe -s -w test3.c

wordcount.exe -w -e end.txt test2.c

wordcount.exe -a -w -e end.txt test1.c

wordcount.exe -l -w -a -c test2.c -o testout2.txt

wordcount.exe -l -w -a -c -s test3.c -o testout2.txt

参考文献

  1. http://www.cnblogs.com/xinz/archive/2011/10/22/2220872.html
  2. http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html
  3. http://www.cnblogs.com/xinz/archive/2011/11/20/2255830.html

wordcount程序实现与测试的更多相关文章

  1. Hadoop集群测试wordcount程序

    一.集群环境搭好了,我们来测试一下吧 1.在java下创建一个wordcount文件夹:mkdir wordcount 2.在此文件夹下创建两个文件,比如file1.txt和file2.txt 在fi ...

  2. spark学习11(Wordcount程序-本地测试)

    wordcount程序 文件wordcount.txt hello wujiadong hello spark hello hadoop hello python 程序示例 package wujia ...

  3. 软件工程:Wordcount程序作业

    由于时间的关系,急着交作业,加上这一次也不是那么很认真的去做,草草写了“Wordcount程序”几个功能,即是 .txt文件的读取,能计算出文件内容的单词数,文件内容的字符数,及行数. 这次选用C来做 ...

  4. Hadoop环境搭建及wordcount程序

    目的: 前期学习了一些机器学习基本算法,实际企业应用中算法是核心,运行的环境和数据处理的平台是基础. 手段: 搭建简易hadoop集群(由于机器限制在自己的笔记本上通过虚拟机搭建) 一.基础环境介绍 ...

  5. hadoop学习笔记——用python写wordcount程序

    尝试着用3台虚拟机搭建了伪分布式系统,完整的搭建步骤等熟悉了整个分布式框架之后再写,今天写一下用python写wordcount程序(MapReduce任务)的具体步骤. MapReduce任务以来H ...

  6. hadoop2.7.x运行wordcount程序卡住在INFO mapreduce.Job: Running job:job _1469603958907_0002

    一.抛出问题 Hadoop集群(全分布式)配置好后,运行wordcount程序测试,发现每次运行都会卡住在Running job处,然后程序就呈现出卡死的状态. wordcount运行命令:[hado ...

  7. 021_在Eclipse Indigo中安装插件hadoop-eclipse-plugin-1.2.1.jar,直接运行wordcount程序

    1.工具介绍 Eclipse Idigo.JDK1.7-32bit.hadoop1.2.1.hadoop-eclipse-plugin-1.2.1.jar(自己网上下载) 2.插件安装步骤 1)将ha ...

  8. 50、Spark Streaming实时wordcount程序开发

    一.java版本 package cn.spark.study.streaming; import java.util.Arrays; import org.apache.spark.SparkCon ...

  9. 大数据之路week07--day03(Hadoop深入理解,JAVA代码编写WordCount程序,以及扩展升级)

    什么是MapReduce 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃. MapReduce方法则是: 1.给在座的所有玩家中分配这摞牌 2.让每个玩家数自己手中的牌有几 ...

随机推荐

  1. C8051F340 USB0 寄存器访问

    /*************************************************************************** * C8051F340 USB0 寄存器访问 ...

  2. 康托展开与逆康托展开模板(O(n^2)/O(nlogn))

    O(n2)方法: namespace Cantor { ; int fac[N]; void init() { fac[]=; ; i<N; ++i)fac[i]=fac[i-]*i; } in ...

  3. 高并发下Redis如何保持数据一致性(避免读后写)

    通常意义上我们说读后写是指针对同一个数据的先读后写,且写入的值依赖于读取的值. 关于这个定义要拆成两部分来看,一:同一个数据:二:写依赖于读.(记住这个拆分,后续会用到,记为定义一.定义二)只有当这两 ...

  4. NAT打洞

    NAT(Network Address Translation)是一种广域网的接入技术,将私有地址转换为合法的公共IP地址,可以完美的解决IP地址不足问题,而且还能有效避免来自外部网络的攻击,隐藏并保 ...

  5. 在系统学习javaEE开发的颠覆者Springboot时遇到的localhost无法访问的问题

    就是新建了一个Springboot项目,但是无法正常访问. 关闭防火墙试了,mvn方式启动试了,换端口试了.然后用Tomcat的start.bat测试发现localhost是可以访问的. 上网找到各种 ...

  6. Js基础之函数

    定义函数:我们使用function标签来定义函数 使用函数:JavaScript函数定义完毕是不能自动执行的,需要我们调用或者事件触发,比如点击事件,鼠标事件,键盘事件等. 下面我们以点击事件为例,调 ...

  7. uptime命令查看系统启动时间和运行时间、查看linux系统负载

    1.uptime命令输出:16:11:40 up 59 days, 4:21, 2 users, load average: 0.00, 0.01, 0.00 2.查看/proc/uptime文件计算 ...

  8. 分析诊断工具之五:Procedure Analyse优化表结构

    一.Procedure Analyse PROCEDURE ANALYSE() ,在优化表结构时可以辅助参考分析语句.通过分析select查询结果对现有的表的每一列给出优化的建议. 利用此语句,MyS ...

  9. 【转】link_to中delete无效的问题解决

    问题一 1.问题描述:点击[删除]链接之后,跳到了show页面,完全没有弹出框提示 <%= link_to "删除", product_path(product.id), : ...

  10. 2015.5.11 string与byte[]相互转换

    string类型转成byte[]: byte[] byteArray = System.Text.Encoding.Default.GetBytes ( str ); 反过来,byte[]转成stri ...