项目 | 内容 |
---|---|
这个作业属于哪个课程 | |
这个作业的要求在哪里 | |
课程学习目标 | 熟悉软件开发整体流程,提升自身能力 |
本次作业在哪个具体方面帮助我们实现目标 | 第一次体验一个完整的工程 |
任务一:
- 点评作业的博客:https://www.cnblogs.com/jsj-hxl/p/10561076.html
- github链接地址: https://github.com/Queey/WordCount
- 点评内容: 本篇博文结构清晰,分别从需求分析、功能设计、设计实现和测试运行做了详细分析,内容比较完整,但是也有一定的缺点,比如在需求分析中指出指定单词词频统计功能可显示对应单词在文本中出现的次数和柱状图,但是博文里面没有实现柱状图。博文结构与PSP中“任务内容”列存在对应关系,PSP中的数据可以明确显示这个项目计划、开发和完成报告的时间分配情况,PSP中“计划共完成需要的时间”与“实际完成需要的时间”有些任务可以在计划完成的时间内完成,而有些任务超出了计划完成任务的时间,其主要原因与项目本身密切相关,一方面项目有一定的难度,另一方面由于自身经验不足,完成项目的时候缺乏经验,导致实际完成项目的时间超出了预期完成项目的时间。
点评心得:
通过运行博主的代码,对方代码在书写方面符合代码书写规范,命名格式完全符合代码规范要求,代码格式整洁,注释部分也很详细。对比自己的博文和代码,我还是有很多不足之处,因此,在接下来的实验中我会慢慢改善自己的不足,尽量写出结构清晰、内容完整的博文。任务二:
(一)需求分析
按照《构建之法》第2章中2.3所述PSP流程,使用JAVA编程语言,结对完成英文文本词频统计的软件开发。软件基本功能要求如下:
(1)实验2要求的功能; (2)单词频数利用可视化柱状图;
(3)统计该文本行数及字符数;
(4)各种统计功能均提供计时功能,显示程序统计所消耗时间(单位:ms); (5)可处理任意用户导入的任意英文文本; (6)人机交互界面要求GUI界面(WEB页面、APP页面都可); (7)附加分功能:统计文本中除冠词、代词、介词之外的高频词;(二)软件设计:
类图
(三)核心功能代码展示:
(1)单词频数利用可视化柱状图实现
public JFreeChart ShowCountHistogram(BufferedReader bufferedReader) throws IOException { CategoryDataset dataset = getDataSet(bufferedReader); JFreeChart chart = ChartFactory.createBarChart3D( "英文文本词频统计图", // 图表标题 "单词名称", // 目录轴的显示标签 "次数", // 数值轴的显示标签 dataset, // 数据集 PlotOrientation.VERTICAL, // 图表方向:水平、垂直 true, // 是否显示图例(对于简单的柱状图必须是false) false, // 是否生成工具 false // 是否生成URL链接 ); CategoryPlot plot=chart.getCategoryPlot(); //获取图表区域对象 CategoryAxis domainAxis=plot.getDomainAxis(); //水平底部列表 domainAxis.setLabelFont(new Font("黑体",Font.BOLD,14)); //水平底部标题 domainAxis.setTickLabelFont(new Font("宋体",Font.BOLD,12)); //垂直标题 ValueAxis rangeAxis=plot.getRangeAxis();//获取柱状 rangeAxis.setLabelFont(new Font("黑体",Font.BOLD,15)); chart.getLegend().setItemFont(new Font("黑体", Font.BOLD, 15)); chart.getTitle().setFont(new Font("宋体",Font.BOLD,20)); //设置标题字体 return chart;}
(2)统计文本中除冠词、代词、介词之外的高频词的实现
public MapselectExceptFunctionWord(BufferedReader bufferedReader) throws IOException { Map map = this.selectWordCountByDOrder(bufferedReader); Map exceptFunction = new LinkedHashMap (); for (Map.Entry w :map.entrySet()) { if(!w.getKey().equals("the")&&!w.getKey().equals("is")&&!w.getKey().equals("you")&&!w.getKey().equals("yourself")&&!w.getKey().equals("your")&&!w.getKey().equals("them")&&!w.getKey().equals("their")&&!w.getKey().equals("to")&&!w.getKey().equals("by")&&!w.getKey().equals("is")&&!w.getKey().equals("a")&&!w.getKey().equals("and")&&!w.getKey().equals("was")&&!w.getKey().equals("has")&&!w.getKey().equals("had")&&!w.getKey().equals("I")&&!w.getKey().equals("for")&&!w.getKey().equals("my")&&!w.getKey().equals("me")&&!w.getKey().equals("with")&&!w.getKey().equals("of")&&!w.getKey().equals("in")&&!w.getKey().equals("on")&&!w.getKey().equals("that")&&!w.getKey().equals("it")&&!w.getKey().equals("The")&&!w.getKey().equals("at")&&!w.getKey().equals("which")&&!w.getKey().equals("he")&&!w.getKey().equals("as") &&!w.getKey().equals("but")&&!w.getKey().equals("his")&&!w.getKey().equals("from")&&!w.getKey().equals("some")&&!w.getKey().equals("be")&&!w.getKey().equals("were")&&!w.getKey().equals("not") &&!w.getKey().equals("they")&&!w.getKey().equals("this")&&!w.getKey().equals("an")&&!w.getKey().equals("no")&&!w.getKey().equals("into")&&!w.getKey().equals("It")&&!w.getKey().equals("there")&&!w.getKey().equals("But")&&!w.getKey().equals("him")&&!w.getKey().equals("could")&&!w.getKey().equals("been")&&!w.getKey().equals("would")&&!w.getKey().equals("she")&&!w.getKey().equals("then")&&!w.getKey().equals("Then")&&!w.getKey().equals("have")) { exceptFunction.put(w.getKey(), w.getValue()); }} return exceptFunction;}
(3)读取文本获取降序词频
public MapselectWordCountByDOrder(BufferedReader bufferedReader) throws IOException { Map map = this.AllWordCount(bufferedReader); List > nlist = new LinkedList >(map.entrySet()); Collections.sort(nlist, new Comparator >() { @Override public int compare(Map.Entry o1, Map.Entry o2) { int compare = (o1.getValue()).compareTo(o2.getValue()); return -compare; } }); Map result = new LinkedHashMap (); for (Map.Entry entry : nlist) { result.put(entry.getKey(), entry.getValue()); } return result; }
(四)程序运行:
(1)实验2要求的功能
主界面统计该文本行数及字符数
读取文本获取词频,按照字典排序
(2)单词频数利用可视化柱状图
(3)读取文本获取指定单词出现的次数
(4)读取文本获取指定前K个高频词(5)读取文本获取降序词频
(6)统计文本中除冠词、代词、介词之外的高频词
(五)描述结对的过程,提供两人在讨论、细化和编程时的结对照片(非摆拍)
(六)PSP
PSP2.1 | 任务内容 | 计划共完成需要的时间(h) | 实际完成需要的时间(h) |
---|---|---|---|
Planning | 计划 | 0.4 | 0.4 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 15 | 20 |
Development | 开发 | 2 | 3 |
Analysis | 需求分析 (包括学习新技术) | 5 | 6 |
Design Spec | 生成设计文档 | 2 | 1.5 |
Design Review | 设计复审 (和同事审核设计文档) | 1 | 1 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 0.5 | 0.5 |
Design | 具体设计 | 5 | 5 |
Coding | 具体编码 | 15 | 18 |
Code Review | 代码复审 | 0.5 | 0.5 |
Test | 测试(自我测试,修改代码,提交修改) | 0.5 | 0.5 |
Reporting | 报告 | 1 | 2 |
Test Report | 测试报告 | 0.5 | 0.5 |
Size Measurement | 计算工作量 | 0 | 0 |
Postmortem & Process Improvement Plan | 事后总结 ,并提出过程改进计划 | 0.5 | 0.5 |
(七)总结
通过这次结对项目,我深刻的理解了1+1>2的含义。在编写这次项目的过程中由于我们两个的编程水平都不太好,需要学习的东西太多,所以在学习心得技术和具体实现的时候花费了很多的时间,但是两个人在学习和讨论的效率明显大于一个人的,我们可以互相讲解自己看懂的或者学懂得技术,这样节约了大量的时间。但是在结对项目的过程中也存在很多的缺点,比如沟通不好两个人就会重复做事情,这样反而降低了项目的进度,所以在两个人的合作中良好的沟通显得格外重要。最后,在这次的结对项目中我学会了很多的知识,我们也从彼此的身上学到了各自的优点,很开心和她合作。