201571030124/201571030130《小学生四则运算练习软件》结对项目报

Github的仓库主页链接地址:https://github.com/Opalus-wangs/Pair-Programming

一、需求分析

任务1:

在《实验二 软件工程个人项目》中,同学们实现了一个命令行四则运算出题小程序,本次实验采用结对编程方式,设计开发一个小学生四则运算练习软件,使之具有以下功能:

 (1)由计算机从题库文件中随机选择20道加减乘除混合算式,用户输入算式答案,程序检查答案是否正确,每道题正确计5分,错误不计分,20道题测试结束后给出测试总分;

 (2)题库文件可采用实验二的方式自动生成,也可以手工编辑生成,文本格式如下:

 

 (3)程序为用户提供三种进阶四则运算练习功能选择:百以内整数算式(必做)、带括号算式、真分数算式练习;

 (4)程序允许用户进行多轮测试,提供用户多轮测试分数柱状图,示例如下:

 

 (5)程序记录用户答题结果,当程序退出再启动的时候,可为用户显示最后一次测试的结果,并询问用户可否进行新一轮的测试;

 (6)测试有计时功能,测试时动态显示用户开始答题后的消耗时间。

 (7)程序人机交互界面是GUI界面(WEB页面、APP页面都可),界面支持中文简体(必做)/中文繁体/英语,用户可以进行语种选择。

二、软件设计

  1.流程图

  2.类图

三、核心代码

 计时部分:

import java.util.Timer;
import java.util.TimerTask;

public  class time {
	public Timer timer=new Timer();
	public boolean is_pause=false;
	public timetask mytimetask=new timetask();
	public int hh,mm,ss;
	String a;	
	public time()
	{
		timer.scheduleAtFixedRate(mytimetask, 0, 1000);	
	}
	public class timetask extends TimerTask{
	public int count_time=0;
	public String date;
	@Override
	public void run() 
	{
		if(!is_pause)
		{
			count_time++;
			hh=count_time/3600;
			mm=(count_time%3600)/60;
			ss=count_time%60;
			date=hh+":"+mm+":"+ss;	
			a=date;	
		}
	}
}
	
	
}

结果计算:

//表达式计算
import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Calculate {

	
	public static int arithmetic(String exp)
    { 
        String result = parseExp(exp).replaceAll("[\[\]]", ""); 
        return (int)Double.parseDouble(result); 
    } 


    public static String parseExp(String expression)
    { 
        expression=expression.replaceAll("\s+", "").replaceAll("^\((.+)\)$", "$1"); 
        String checkExp="\d"; 
        String minExp="^((\d+(\.\d+)?)|(\[\-\d+(\.\d+)?\]))[\+\-\*\/]((\d+(\.\d+)?)|(\[\-\d+(\.\d+)?\]))$"; 
        //最小表达式计算 
        if(expression.matches(minExp))
        { 
            String result=calculate(expression); 
             
            return Double.parseDouble(result)>=0?result:"["+result+"]"; 
        } 
        //计算不带括号的四则运算 
        String noParentheses="^[^\(\)]+$"; 
        String priorOperatorExp="(((\d+(\.\d+)?)|(\[\-\d+(\.\d+)?\]))[\*\/]((\d+(\.\d+)?)|(\[\-\d+(\.\d+)?\])))"; 
        String operatorExp="(((\d+(\.\d+)?)|(\[\-\d+(\.\d+)?\]))[\+\-]((\d+(\.\d+)?)|(\[\-\d+(\.\d+)?\])))"; 
        if(expression.matches(noParentheses))
        { 
            Pattern patt=Pattern.compile(priorOperatorExp); 
            Matcher mat=patt.matcher(expression); 
            if(mat.find())
            { 
                String tempMinExp=mat.group(); 
                expression=expression.replaceFirst(priorOperatorExp, parseExp(tempMinExp)); 
            }
            else
            { 
                patt=Pattern.compile(operatorExp); 
                mat=patt.matcher(expression); 
                 
                if(mat.find())
                { 
                    String tempMinExp=mat.group(); 
                    expression=expression.replaceFirst(operatorExp, parseExp(tempMinExp)); 
                } 
            } 
            return parseExp(expression); 
       
        } 
        //计算带括号的四则运算 
        String minParentheses="\([^\(\)]+\)"; 
        Pattern patt=Pattern.compile(minParentheses); 
        Matcher mat=patt.matcher(expression); 
        if(mat.find())
        { 
            String tempMinExp=mat.group(); 
            expression=expression.replaceFirst(minParentheses, parseExp(tempMinExp)); 
        }        
        return parseExp(expression); 
    } 
    
     public static String calculate(String exp)
     { 
        exp=exp.replaceAll("[\[\]]", ""); 
        String number[]=exp.replaceFirst("(\d)[\+\-\*\/]", "$1,").split(","); 
        BigDecimal number1=new BigDecimal(number[0]); 
        BigDecimal number2=new BigDecimal(number[1]); 
        BigDecimal result=null; 
          
        String operator=exp.replaceFirst("^.*\d([\+\-\*\/]).+$", "$1"); 
        if("+".equals(operator))
        { 
            result=number1.add(number2);     
        }
        else if("-".equals(operator))
        { 
            result=number1.subtract(number2); 
        }
        else if("*".equals(operator))
        { 
            result=number1.multiply(number2); 
        }
        else if("/".equals(operator))
        { 
            result=number1.divide(number2,2, BigDecimal.ROUND_HALF_EVEN); 
        } 
       return result!=null?result.toString():null;        
    } 
	
}

柱状图:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JTextArea;
//绘制柱状图
public class Picture extends JFormattedTextField
{
		int [] a=new int[20];
		int j=0;
		int i=0;
		int x=0;
		int aa=0;
		//绘制柱形统计图
		private Random ran;
		public Picture(ArrayList<Student> students)
		{	
			super();
			for(Student e: students )
			 {
					a[j]=(e.getw());
					j++;	
			 }
			ran = new Random();
			setName("绘制柱形图");
			setBounds(100,85,270,210);
		}
		@Override
		public void paint(Graphics g){
			int Width = getWidth();
			int Height = getHeight();
			int leftMargin = 2;//柱形图左边界
			int topMargin = 5;//柱形图上边界
			Graphics2D g2 = (Graphics2D) g;
			int ruler = Height-topMargin-5;
			int rulerStep = ruler/10;//将当前的高度评分为10个单位
			g2.setColor(Color.WHITE);//绘制白色背景
			g2.fillRect(0, 0, Width, Height);//绘制矩形图
			g2.setColor(Color.LIGHT_GRAY);
			for(int i=0;i<=10;i++){//绘制灰色横线和百分比
				g2.drawString((100-10*i)+"%", 5, topMargin+rulerStep*i);//写下百分比
				g2.drawLine(5, topMargin+rulerStep*i, Width, topMargin+rulerStep*i);//绘制灰色横线
			}
			g2.setColor(Color.RED);

			for(i=0;i<j;i++){//绘制柱形图
				int value =(20-a[i])*10+5;
				int step = (i+1)*20;//设置每隔柱形图的水平间隔为40
				//绘制矩形
			
				g2.fillRoundRect(leftMargin+step*2, Height-value, 20, value, 20, 20);
				
				g2.drawString("C"+(i+1)+"-"+(20-a[i])*5+"%", leftMargin+step*2, Height-value-5);
			
			}
		}		
}
	

四、程序运行

  1.首先是主界面:

  2.点击简单后,出现用户登录的界面,用户登录完成后,点击确定:

  3.出现做题界面:

  4.点击开始计时时,并开始做题:

  5.如果我们没有答完题,提交的时候才能提示信息:

  6.做完点击提交,出现成绩和错误题号,并且画出柱状图:

   7.点击继续,选择复杂计算:

  8.显示结果:

  9.点击查看:

 五、结对编程过程

 六、PSP

PSP2.1任务内容计划完成的时间(min)实际完成需要的时间(min)
PLanning 计划 60 80
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 60 80
Developmet 开发 450 520
Analysis 需求分析(包括学习新技术) 30 40
Design Spec 生成设计文档 10 20
Design Revie 设计复审(和同事审核设计文档) 30 30
Coding Standard 代码规范 30 30
Design 具体设计 60 60
Coding 具体编码 240 290
Code Review 代码复审 30 30
Test 测试(自我测试,修改代码,提交修改) 20 20
Reporting 报告 40 40
Test Report 测试报告 20 20
Size Measurement 计算工作量 5 5
Postmortem & Process Improvement Plan 事后总结,并提出过程改机计划 15 15

 七、对小伙伴的评价

   对于我的partner,我想说一声谢谢。在本次结对编程中,我们并不是一帆风顺,遇到了很多的困难,但我们都没有选择放弃,而是在互相鼓励中,成功完成了实验。我的partner她是一个动手能力很强,且有自己独特想法的同学,在实验过程中,以其熟练的编程能力,删掉了我冗余代码,使得程序的结构更加清楚明了,代码也更加的规范,这一点值得我去学习,还有一点就是对待事情认真的态度,例如在每添加一个控件的时候,都极力的使其对称整体,可以说是一丝不苟。总的来说,这次的结对编程很快乐,在不知不觉中就完成了实验,没有往日做实验的枯燥,相反,更愿意讨论彼此对问题的想法。这也增加我们解决问题的信心和动力。谢谢我们都不曾放弃无所畏惧自己。

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

  通过本次结对编程,我觉得是结对编程1+1>2的,因为在实验过程中,我确切的感受到了合作的重要性,当一个人的想法不正确的时候,你的同伴可以很快的提醒你,两个人一起讨论问题,可以更快的解决问题,可以有很多新的想法产生。而且当你遇到困难的时候,你也不会轻易的放弃,因为你的同伴还在努力尝试着。两个人一起编程,你感觉不到编程的枯燥与乏味,反而是很轻松,很愉快,很享受彼此讨论自己想法的过程。

原文地址:https://www.cnblogs.com/pwld/p/8696439.html