201571030314/201571030316《小学生四则运算练习软件》结对项目

结对编程实现小学生四则运算练习软件

前言:按照结对编程的原则,我和邻宿舍的小伙伴进行了两人结对编程,我们开发的结对项目的是小学生四则运算练习软件,具体就是随机生成n道题,供学生答题并返回正误记录答题结果,进行多轮。具体需求分析以及功能设计与实现如下。

 github代码地址:https://github.com/mqqgd/Experiment2

 一、需求分析

        本次实验采用结对编程方式,设计开发一个小学生四则运算练习软件,使之具有以下功能:

  • 由计算机从题库文件中随机选择20道加减乘除混合算式,用户输入算式答案,程序检查答案是否正确,每道题正确计5分,错误不计分,20道题测试结束后给出测试总分;
  • 题库文件可采用实验二的方式自动生成,也可以手工编辑生成,文本格式如下:

  • 程序为用户提供三种进阶四则运算练习功能选择:百以内整数算式(必做)、带括号算式、真分数算式练习;
  • 程序允许用户进行多轮测试,提供用户多轮测试分数柱状图,示例如下:

 

  • 程序记录用户答题结果,当程序退出再启动的时候,可为用户显示最后一次测试的结果,并询问用户可否进行新一轮的测试;
  • 测试有计时功能,测试时动态显示用户开始答题后的消耗时间。
  • 程序人机交互界面是GUI界面(WEB页面、APP页面都可),界面支持中文简体(必做)/中文繁体/英语,用户可以进行语种选择。

二、功能设计与实现

  • 软件设计类图

  • 核心功能代码展示
import java.util.Random;

public class GetRandomDigit {
    private Random random;
    public GetRandomDigit(){
        random=new Random();
    }
    int oprator(){
        return random.nextInt(4)+1;
    }
    int Time(){
        return random.nextInt(3)+3;
    }
    int randomDigit(){
        return random.nextInt(100);
    }
    int probabilityQuestion(){
        return random.nextInt(200);
    }
    int BracketsIndex(int time){
        return random.nextInt(time-2);
    }
}

随机出题
随机出题
public class LinkSql {
    private static final String url = "jdbc:mysql://127.0.0.1:3306/mqqgd";   
    private  static final String user = "root";  
    private  static final String password = "root";
    private static ResultSet ret = null;
    private  static final String name = "com.mysql.jdbc.Driver";
    public Connection conn = null;  
    public PreparedStatement pst = null; 
    public  LinkSql() {  
        try {  
            Class.forName(name);//指定连接类型  
            conn = DriverManager.getConnection(url, user, password);//获取连接             
            System.out.println("数据库链接成功");
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
    
    public void changeMySqlDate(String sql) {
        try {
            pst=conn.prepareStatement(sql);
            pst.executeUpdate();
            System.out.println("接收到修改数据库命令"+sql);
        } catch (SQLException e) {
            // TODO Auto-generated catch block 
            e.printStackTrace();
        }
    }
    public ResultSet selectSqlDate(String sql) {
        try {
            System.out.println("接收到查询数据库命令"+sql);
            pst=conn.prepareStatement(sql);
            ret = pst.executeQuery();
            return ret;
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        } 
    }
    public void closeMySql() {
        try {  
            this.conn.close();   
        } catch (SQLException e) {  
            e.printStackTrace();  
        }
    }
    @SuppressWarnings("static-access")
    public void closeChart() {  
        try {    
            this.pst.close();
            this.ret.close();
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
    } 
}

链接数据库
链接数据库
import java.util.HashMap;  
import java.util.Stack;    
public class ArithmeticResult {  
    public Double Result(String formula) {  
        Stack<Double> s1 = new Stack<Double>();
        Stack<String> s2 = new Stack<String>();
        HashMap<String, Integer> hashMap = new HashMap<String, Integer>();  
        hashMap.put("(", 0);  
        hashMap.put("+", 1);  
        hashMap.put("-", 1);  
        hashMap.put("×", 2);  
        hashMap.put("÷", 2);  
        for (int i = 0; i < formula.length();) {  
            StringBuffer digit = new StringBuffer();  
            char c = formula.charAt(i);  
            while (Character.isDigit(c) || c == '.') {  
                digit.append(c);  
                i++;  
                c = formula.charAt(i);  
            }  
            if (digit.length() == 0) {  
                switch (c) {  
                case '(': {  
                    s2.push(String.valueOf(c));  
                    break;  
                }  
                case ')': {  
                    String stmp = s2.pop();  
                    while (!s2.isEmpty() && !stmp.equals("(")) {  
                        double a = s1.pop();  
                        double b = s1.pop();  
                        double sresulat = calcDouble(b, a, stmp);  
                        s1.push(sresulat);  
                        stmp = s2.pop();  
                    }  
                    break;  
                }  
                case '=': {  
                    String stmp;  
                    while (!s2.isEmpty()) {  
                        stmp = s2.pop();  
                        double a = s1.pop();  
                        double b = s1.pop();  
                        double sresulat = calcDouble(b, a, stmp);  
                        s1.push(sresulat);  
                    }  
                    break;  
                }  
                default: {  
                    String stmp;  
                    while (!s2.isEmpty()) {  
                        stmp = s2.pop();  
                        if (hashMap.get(stmp) >= hashMap.get(String.valueOf(c))) {  
                            double a = s1.pop();  
                            double b = s1.pop();  
                            double sresulat = calcDouble(b, a, stmp);  
                            s1.push(sresulat);  
  
                        } else {  
                            s2.push(stmp);  
                            break;  
                        }  
  
                    }  
                    s2.push(String.valueOf(c));  
                    break;  
                }  
                }  
            } else {  
                s1.push(Double.valueOf(digit.toString()));  
                continue;  
            }  
            i++;  
        }  
        return s1.peek();  
    }  
  
    public double calcDouble(double a, double b, String stmp) {  
        double res = 0f;  
        char s = stmp.charAt(0);  
        switch (s) {  
          case '+':
            res = a + b;  
            break;  
          case '-':  
            res = a - b;  
            break;  
          case '×':
            res = a * b;  
            break;  
          case '÷':
            res = a / b;  
            break;  
        }  
        return res;
    }    
}  

计算过程
计算过程
//从这里开始  
        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));//设置标题字体  
            
        //到这里结束,虽然代码有点多,但只为一个目的,解决汉字乱码问题  
        //这里也可以用chartFrame,可以直接生成一个独立的Frame
        frame1=new ChartPanel(chart,true);          
           
    }  
    
    private CategoryDataset getDataSet() {  
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();   
        System.out.println(times);
        for(int i=0;i<times;i++){
            System.out.println("lalal");
            dataset.addValue(result[i],"第"+(i+1)+"轮","第"+(i+1)+"轮");
        }
        return dataset;   
    }
    
    public ChartPanel getChartPanel(){  
        return frame1;  
    }  
}  

绘制柱状图
绘制柱状图
import javax.swing.JFrame;

@SuppressWarnings("serial")
public class Tongji extends JFrame{
    PieChart pic;
    int time;
    int [] result;
    public Tongji(int[] result,int time){
        this.time=time;
        this.result=result;
        setFrame();
    }
    
    //登陆界面
    private void setFrame(){
        System.out.println(time);
        pic=new PieChart(result,time);
        this.setTitle("您最终的得分统计");
        this.setSize(600,400);
        this.setLocationRelativeTo(null);
        this.setResizable(false);
        this.setVisible(true);
        this.add(pic.getChartPanel());
        
    }
}

统计分数
统计分数
  • 测试运行

1.登录界面

2.数据库

3.做题界面

4.答题结束时,自动显示柱状图

三、结对过程

我的小伙伴:马兰

她的学号:201571030316

她的博客地址:http://www.cnblogs.com/mqqgd/p/8708953.html 

以下就是我们讨论时的照片啦~

 

四、PSP

PSP2.1

任务内容

计划共完成需要的时间(min)

实际完成需要的时间(min)

Planning

计划

20

16

·       Estimate

·  估计这个任务需要多少时间,并规划大致工作步骤

20

16

Development

开发

1838

1736

··       Analysis

  需求分析 (包括学习新技术)

20

20

·       Design Spec

·  生成设计文档

25

25

·       Design Review

·  设计复审 (和同事审核设计文档)

10

10

·       Coding Standard

  代码规范 (为目前的开发制定合适的规范)

3

3

·       Design

  具体设计

300

240

·       Coding

  具体编码

1440

1400

·       Code Review

·  代码复审

10

8

·       Test

·  测试(自我测试,修改代码,提交修改)

30

30

Reporting

报告

33

30

··       Test Report

·  测试报告

3

2

·       Size Measurement

  计算工作量

10

8

·       Postmortem & Process Improvement Plan

·  事后总结 ,并提出过程改进计划

20

20

五、用汉堡评价法给小伙伴的点评

       我的小伙伴是一个学习能力很强的人,在整个合作过程中合作非常愉快,她的优点是想到什么了就会去做去学,很细心。刚开始拿到这个题目,两个人都比较苦恼,不知道如何去实现,后来小伙伴给的建议是分工合作,突然有了紧迫感,我们查阅了相关的资料,感觉时间越来越近的时候就会督促她。当正式着手去做的时候并没有按之前分工好的去做,因为两人的编程能力都不是很强(她比我好很多),而是把彼此的想法都提出来进行了汇总,最后一起一步一步进行了实现。她是一个很有趣的人,在合作的过程中也不会感到乏味。在写这篇博客的时候,有遗漏的地方她也会提醒我加上。

六、结对编程真的能够带来1+1>2的效果吗?通过这次结对编程,请谈谈你的感受和体会

        这次与另外同学的结对编程,发现自己某些方面的不足,某些考虑不全面,结对小伙伴都可以一针见血的指出,同时两个人同时编程感觉更高效考虑的更全面,如果是很多人同时开发,几个人之间的沟通就成很大问题,不一定就有结对编程的效率高。真正体会到1+1>=2的效果了,在项目进行的初期阶段分工明确,使得我们互相督促,之后因为程序的问题,然后就一起做并解决问题。由于是邻舍,讨论问题也很方便,一人在负责自己分工的同时,另一人则也出谋划策,遇到困难的地方在彼此的帮助下也都迎刃而解了。在这次项目的过程中,我们也通过不断的请教大神,学到了很多东西, 通过这次的结对项目觉得终于完成了一次又有趣又有成就感的项目。

原文地址:https://www.cnblogs.com/mjuan/p/8715700.html