• 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的效果了,在项目进行的初期阶段分工明确,使得我们互相督促,之后因为程序的问题,然后就一起做并解决问题。由于是邻舍,讨论问题也很方便,一人在负责自己分工的同时,另一人则也出谋划策,遇到困难的地方在彼此的帮助下也都迎刃而解了。在这次项目的过程中,我们也通过不断的请教大神,学到了很多东西, 通过这次的结对项目觉得终于完成了一次又有趣又有成就感的项目。

  • 相关阅读:
    mysql主从复制配置
    mysql三种修改密码的方式
    mysqldump数据库备份与恢复
    mysql多实例安装
    线性回归与梯度下降法——原理与实现
    K-Means聚类算法原理
    EFcodeFirst+T4=操纵任意数据库
    涨姿势UWP源码——IsolatedStorage
    记一次Project插件开发
    基于Nodejs生态圈的TypeScript+React开发入门教程
  • 原文地址:https://www.cnblogs.com/mjuan/p/8715700.html
Copyright © 2020-2023  润新知