软工网络16结对编程

Posted kyrie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软工网络16结对编程相关的知识,希望对你有一定的参考价值。

1、码云项目地址

结对项目码云地址

结对编程队友

学号 姓名 各自项目地址
201621123013 侯湘宁 https://www.cnblogs.com/kyrie/p/9754498.html
201621123011 陈瑀 https://www.cnblogs.com/eshy/

码云记录

技术分享图片


2、PSP表格

PSP2.1 个人开发流程 预估耗费时间(分钟) 实际耗费时间
Planning 计划 30 35
· Estimate 明确需求和其他相关因素,估计每个阶段的时间成本 40 50
Development 开发 350 430
· Analysis 需求分析 (包括学习新技术) 150 180
· Design Spec 生成设计文档 30 30
· Design Review 设计复审 40 50
· Coding Standard 代码规范 25 30
· Design 具体设计 30 30
· Coding 具体编码 150 180
· Code Review 代码复审 20 20
· Test 测试(自我测试,修改代码,提交修改) 20 30
Reporting 报告 75 90
· 测试报告 30 40
· 计算工作量 50 50
· 并提出过程改进计划 25 25

3、解题思路概述

3.1、编程语言的选择:java、html和css(用于做基于web的GUI页面)

3.2、开发工具以及环境:Eclipse

3.3、解题思路

经过本人和小伙伴的讨论,决定在我之前个人项目的代码上做改进。首先要抓住本次结对编程项目和上一次个人项目的不同,要新增两个功能,能统计文件夹中指定长度的词组的词频能输出用户指定的前n多的单词
在把后台的东西解决好之后,开始考虑与前端(简单的页面)结合,经过思考后,决定采用java Servlet技术,但是由于之前没怎么涉及到这个,还是花了很多的时间去了解,在前端与后台的整合上花的时间是最多的,主要还是不够熟悉java Servlet技术,导致开发过程遇到不少问题。

其实基本思路就是通过jsp文件中的表单将数据传递给后台进行处理,调用java代码实现功能。


4、设计实现过程

4.1、相关类和函数的设计

定义了一个charCount类,在之前定义的三个方法的基础上,sortMap方法(实现单词排序),wordCount方法(实现词频统计),Output方法(实现写文本文件处理),增加了两个方法。本次的结对编程项目增加了两个功能,也就是sortMap1方法(能输出用户指定的前n多的单词),还有lenWordCount方法(能统计文件夹中指定长度的词组的词频)。而且本次的项目中,我们改进了之前不能进行大小写区分的问题,在之后的单元测试会有说明!


5、代码说明(代码片段)

在这边我们就说明一下新功能的代码(之前的代码就不再说明了)

5.1、首页表单(其他页面表单类似)

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
    
  
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<style>
    
    td.inset {border-style:inset; 
        border-color:#98bf21;}

    
    
    h1
{
    position:fixed;
    top:200px;
    right:555px;
}
    
table.begin
{
    position:fixed;
    top:300px;
    right:550px;
}


    h1{text-shadow: 5px 5px 5px #FF0000;}
    

</style>
<body>
<center>
<form action="/hou13/charCount" method="post">
<h1 class="text1">欢迎您使用宁&瑀的小程序!</h1>

    <table class="begin">
    <tr>
        <td class="inset" colspan="2">请输入想要统计的文本文件(绝对路径):<input type="text" autofocus name="txt"></td>
    </tr>
    
    <tr>
        <td align="right"><input type="submit" value="确认" ></td>
        <td><input type="reset" value="重填"></td>
    </tr>
    </table>
    </form>
</center>
</body>
</html>

这就是一个简单的表单作为首页,将在这里输入的数据传递到servlet文件进行后台处理。

5.2、doPost方法


protected void doPost(HttpServletRequest req, HttpServletResponse resp)
               throws ServletException, IOException {
           
            resp.setContentType("text/html;charset=UTF-8");
            PrintWriter out = resp.getWriter();
            //读入TXT文件
            Scanner input = new Scanner(System.in);
            String pathname = req.getParameter("txt");
            
            int charCount=0;
            int lineCount=0;
            InputStreamReader r = new InputStreamReader(new FileInputStream(pathname)); // 建立一个输入流对象reader
            BufferedReader br = new BufferedReader(r); // 建立一个对象,它把文件内容转成计算机能读懂的语言
            
            List<String> list = new ArrayList<String>();  //存储单词
            String readLine = null;
            while((readLine = br.readLine()) != null){
                charCount += readLine.length();//字符个数就是字符长度,不考虑汉字
                if(readLine.isEmpty()) {
                    //此行为空,为无效行
                }
                else {
                    lineCount++;}//一行一行读,每读一行行数加1
                String[] wordsArrays = readLine.split("\\s*[^0-9a-zA-Z]+");
                //以空格和非字母数字符号分割,至少4个英文字母开头,跟上字母数字符号
                for (String word : wordsArrays) {
                    if(word.matches("[a-zA-Z]{4,}[a-zA-Z0-9]*")){
                        list.add(word.toLowerCase());
                    }
                }
            }
            
            r.close();//关闭文件
            
            Map<String, Integer> wordsCount = new TreeMap<String,Integer>();  //存储单词计数信息,key值为单词,value为单词数
           
            
            out.println("<html>");
            out.println("<head>");
            out.println("<title>输出</title>");
            out.println("</head>");
            out.println("<style>");
            out.println("h1{text-shadow: 5px 5px 5px #FF0000;}");
            out.println("</style>");
            out.println("<body>");
            out.println("<center>");
            out.println("<h1>欢迎您使用宁&瑀的小程序!</h1>");
            out.println("<h3>字符统计结果</h3>");
            out.println("字符数:"+charCount);
            out.println("<br>");
            out.println("有效行数:"+lineCount);
            out.println("<br>");
      
            wordCount(wordsCount,list,req,resp);
            out.println("<br>");
            sortMap(wordsCount,req,resp);    //按值进行排序
            
            out.println("<input type="button" value="查看前k个单词" onclick="window.location.href=‘other.jsp‘"> ");
            out.println("<input type="button" value="查看指定长度单词" onclick="window.location.href=‘.jsp‘"> ");
            out.println("<input type="button" value="返回" onclick="window.location.href=‘index.jsp‘"> ");
            
            out.println("</center>");
            out.println("</body>");
            out.println("</html>");

             }

在前端提交数据之后,由于前面提交的方式是post,所以在servlet中就重写doPost()方法,进而跳转到另外一个页面(即显示字符统计结果)

5.3、sortMap1方法

//前k多的单词
    public static void sortMap1(Map<String,Integer> oldmap,int k,HttpServletRequest req, HttpServletResponse resp) throws IOException{
        ArrayList<Map.Entry<String,Integer>> list = new ArrayList<Map.Entry<String,Integer>>(oldmap.entrySet());
        Collections.sort(list,new Comparator<Map.Entry<String,Integer>>(){
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                if (o1.getValue() == o2.getValue()) {
                    return o1.getKey().compareTo(o2.getKey());//词频相同时,按字典排列
                }
                return o2.getValue() - o1.getValue();  //降序排列
            }
        });
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        if(list.size()>=k){//单词数大于或等于k的时候,输出频数前k个
            for(int i = 0; i<k; i++){
                out.println(list.get(i).getKey()+ ": " +list.get(i).getValue());
            }
        }else {
            for(int i = 0; i<list.size(); i++){//单词数小于k的时候,输出全部
                out.println(list.get(i).getKey()+ ": " +list.get(i).getValue());//键值对一一对应
            }
        }

    }

这个方法就是将前k个单词输出,这个功能的实现相对来说简单一点,因为基于之前的sortMap的函数上做一点修改就可以用,但是如果认真观察的话,会发现为啥sortMap1
函数的参数会多了两个HttpServletRequest req, HttpServletResponse resp,需要用到PrintWriter out = resp.getWriter();它其实就是用来给out功能,将数据输出到页面上(其实也是无奈之举,因为doPost里面的resp不是全局变量,导致在sortMap1里面的数据只能输出到控制台上)
其他的方法同理。


6、单元测试

测试用例(部分)

6.1、改进能够实现大小写

技术分享图片

6.2、查看前3个单词

技术分享图片

技术分享图片

6.3、查看前10个单词(超过单词总数)

技术分享图片

技术分享图片

6.4、查看指定长度的单词

技术分享图片

技术分享图片

代码覆盖率测试

技术分享图片

7、结对编程感受

结对编程照片(纪实)

技术分享图片

个人感受:

首先,虽然说,可能这个结对编程项目完成得不是很好,但我想说这应该是我经历过比较成功的一次合作编程,整个过程下来,我们很聊得来,相处那肯定是很愉快了。一开始我们都互相研究了对方的上周个人项目的代码,经过讨论,一致决定采用本人的代码。整个项目下来,一些问题的探讨和解决,个人感觉是1+1>2,两个人的思维和想法在一个频道上面,这种感觉是相当地棒了。我们一致决定GUI用基于web的网页设计,用servlet技术来完成这个项目,我们分工明确,前端和后台结合得还是很不错的。其实整个结对项目过程我觉得队友给予我最重要的是一种启发的作用,我们在处理问题的时候往往会陷入一些困境,这个时候你的队友就可能会给你帮助!而在这次的合作中感受很深。最后我个人觉得,如果你的队友与你是在一个频道上,交流得很融洽,互相促进对方,这个我觉得1+1>2就能很明显体现出来了。




以上是关于软工网络16结对编程的主要内容,如果未能解决你的问题,请参考以下文章

软工网络15结对编程练习

软工网络15结对编程练习

软工网络15结对编程练习 201521123056 吴剑通

软工网络15个人阅读作业2

软工网络15结对编程练习(201521123007谭燕)

软工结对编程代码审查