实验二 结对编程(阶段二)

一、实验目标:

 1)体验敏捷开发中的两人合作。

2)进一步提高个人编程技巧与实践。

 

二 、实验内容:

1)根据以下问题描述,练习结对编程(pair programming)实践;

2)要求学生两人一组,自由组合。每组使用一台计算机,二人共同编码,完成实验要求。

3)要求在结对编程工作期间,两人的角色至少切换 4 次;

4)编程语言不限,版本不限。建议使用 Python 或 JAVA 进行编程。

 

三、问题描述

开发一个自动生成小学四则运算题目的命令行 “软件”。实现 输入你要出题的个数,随机产生四则运算,然后用户回答,并且进行打分。

规则:用随机数实现100以内的加、减、乘、除运算,其中和与积不能超过100,差不为负(即须大减小),商不为小数或分数(即必须整除)。要求总计输出10个运算式,每输出一个运算式,等待输入结果,然后进行对错判断并输出。最后输出统计答对的题数与分。

 

阶段一

 1)查阅相关资料加深对敏捷开发和结对编程的理解;
2)组队情况,各队博客地址,github仓库地址,所选择的课题;
3)针对课题查阅的资料,对课题的理解;
4)二个人商量后,采用开发平台和技术工具
5)其他,如二人讨论的记录

 

1)

敏捷开发的特点:敏捷开发是一种基于更紧密的团队协作、能够有效应对快速变化需求、快速交付高质量软件的迭代和增量的新型软件开发方法。更关注协作更关注质量更关注可工作的产品基于实践而非基于理论。

结对编程:(Pair programming)是一种敏捷软件开发的方法,两个程序员在一个计算机上共同工作。一个人输入代码,而另一个人审查他输入的每一行代码。输入代码的人称作驾驶员,审查代码的人称作观察员。两个程序员经常互换角色。在结对编程中,观察员同时考虑工作的战略性方向,提出改进的意见,或将来可能出现的问题以便处理。这样使得驾驶者可以集中全部注意力在完成当前任务的“战术”方面。观察员当作安全网和指南。结对编程对开发程序有很多好处。比如增加纪律性,写出更好的代码等。

 2)

组队情况:58/江苏电视台 方振响 https://www.cnblogs.com/fangzhenxiang/ 王宁 https://home.cnblogs.com/u/wangningshark/ 四则运算 https://github.com/bigApple00/four-types-compute

3)课题难度不是很大,采用模块化Java GUI编程。

4)eclipse GUI编程

5)选择四则运算题目和eclipse开发工具,掌握了git基本操作,采用GitHub托管。

 

阶段二

1.代码规范

变量名应遵循见名知意的命名原则
名称只能由字母、数字、下划线、$符号组成
不能以数字开头
名称不能使用Java中的关键字
不允许出现中文及拼音命名
项目名全部小写
包名全部小写
方法采用小驼峰式命名
对方法和变量名加上一定的注释
代码缩进要一致

变量在声明时,同时进行初始化。
同一行只声明一个变量。
勿把不同类型的变量声明放在同一行。
方法和方法之间空一行。

让一切东西都尽可能地"私有"--private。可使库的某一部分"公共化"(一个方法、类或者一个字段等等),就永远不能把它拿出。若强行拿出,就可能破坏其他人现有的代码,使他们不得不重新编写和设计。

 

2.程序的总体设计
随机生成两个数和运算符,用不同的方法实现不同的限制条件,把数字和运算符加到Jframe上面
用事件方法做出评分功能,方法均在构造界面时实现。


程序总体设计图

 

 

 3.程序结对编程过程

 这是用QQ屏幕分享,编写一些程序中的方法。我是驾驶员,他是领航员。

 

 这是在操作git命令进行pull request。他是驾驶员,我是领航员。

 

 这是在GitHub里进行merge。

 

4.功能实现情况

基本的功能都可以实现,大减小,整除,加法乘法小于一百,随机生成整数和运算符。输入之后答案之后点击按钮进行提交,评分结果显示在屏幕上。可重复答题和评分。

 

 

 

 

 

以下是代码,这是最初的未模块化的

package package1;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UI extends JFrame implements ActionListener{  
	
    public 
    int x;		//x为被除数,y为除数,z为暂存x,y的商
    float z,y;

    JLabel[][] lab=new JLabel[10][4];		//存放四则运算的数和运算符
    JTextField[] text=new JTextField[10];		//存放输入结果
	Random random =new Random();
	JButton b1=new JButton("提交");

	public int produceNumber1() {	//产生被除数
		int random_number_x;
		random_number_x=random.nextInt(50)+1;
		return random_number_x;
	}
	
	public float produceNumber2() {		//产生除数
		int random_number_y;
		random_number_y=random.nextInt(50)+1;
		return random_number_y;
	}
	
	public void underHundred() {	//使加法结果小于一百
		while(x+y>100) {
			y--;
			if(x+y<100)
				break;
		}
	}
	
	public void underHundred2() {	//使乘积结果小于一百
		while(x*y>100) {
			y--;
			if(x*y<100) 
				break;
		}
	}
	
	
	public void bigSubtractsmall() {	//完成大减小
		while(x-y<0) {
			x++;
			if(x-y>0)
				break;
		}
	}
	
	public  void exactDivide() {	//使整除
		try {
			z=x/y;
		}
		catch (ArithmeticException e) {
			e.printStackTrace();
		}
		
		Pattern pattern=Pattern.compile("\\.0$");	//若不是以.0结尾,就没有整除
		String s = String.valueOf(z);
		Matcher matcher=pattern.matcher(s);
		while(!matcher.find()) {		//改变被除数y的值
			y=1f;
			y++;
			z=x/y;
			s = String.valueOf(z);
			matcher=pattern.matcher(s);
			if(matcher.find())
				break;
		}
	}
	
	public String chooseCharacter() {		//随机选择四种运算符的一个
		char[] a={'+','-','*','/'};
		String charString=String.valueOf(a[random.nextInt(a.length)]);
		return charString;
		
	}
	
	public void actionPerformed(ActionEvent a) {
		int right_count=0;		//记录正确的个数
		String char_string;
		if(a.getSource()==b1) {
			for(int i=0;i<10;i++) {
				int j=0;
				char_string=lab[i][j+1].getText();
				
				switch (char_string) {		//判断是哪一个运算符对应的算式
				case "+":
					try {		//Integer.parseInt该方法会抛出异常
					if(Integer.parseInt(lab[i][j].getText().trim())+Integer.parseInt(lab[i][j+2].getText().trim())==Integer.parseInt(text[i].getText().trim()))
					right_count++;
					}catch (NumberFormatException e) {
						e.printStackTrace();
					}
					break;
					
				case "-":
					try {
					if(Integer.parseInt(lab[i][j].getText().trim())-Integer.parseInt(lab[i][j+2].getText().trim())==Integer.parseInt(text[i].getText().trim()))
					right_count++;
					}catch (NumberFormatException e) {
						e.printStackTrace();
					}
					break;
					
				case "*":
					try {
					if(Integer.parseInt(lab[i][j].getText().trim())*Integer.parseInt(lab[i][j+2].getText().trim())==Integer.parseInt(text[i].getText().trim()))
					right_count++;
					}catch (NumberFormatException e) {
						e.printStackTrace();
					}
					break;
					
				case "/":
					try {
					if(Integer.parseInt(lab[i][j].getText().trim())/Integer.parseInt(lab[i][j+2].getText().trim())==Integer.parseInt(text[i].getText().trim()))
					right_count++;
					}catch (NumberFormatException e) {
						e.printStackTrace();
					}
					break;
	
				}
				
			}
			b1.setText("你答对了"+right_count+"题");			//最后评分输出到button上
			
		}
	}
	

	UI(){
		int j=0;
		String ch;
		
		for(int i=0;i<10;i++) {
		x=produceNumber1();
		y=produceNumber2();	
		bigSubtractsmall();
		ch=chooseCharacter();		
		switch(ch) {		//判断产生的是哪个运算符
		case "+" :
			underHundred();
			lab[i][j]=new JLabel(" "+x);
			add(lab[i][j]);
			lab[i][j+1]=new JLabel("+");
	    	add(lab[i][j+1]);
	    	lab[i][j+2]=new JLabel(" "+(int)y);		//被除数y为float型转为int型
	    	add(lab[i][j+2]);
	    	lab[i][j+3]=new JLabel("=");
	    	add(lab[i][j+3]);
	    	text[i] =new JTextField("      ");
			add(text[i]);
			break;
		
		case "-":
			lab[i][j]=new JLabel(" "+x);
			add(lab[i][j]);
			lab[i][j+1]=new JLabel("-");
	    	add(lab[i][j+1]);
	    	lab[i][j+2]=new JLabel(" "+(int)y);
	    	add(lab[i][j+2]);
	    	lab[i][j+3]=new JLabel("=");
	    	add(lab[i][j+3]);
	    	text[i] =new JTextField("      ");
			add(text[i]);
			break;
			
		case "*":
			underHundred2();
			lab[i][j]=new JLabel(" "+x);
			add(lab[i][j]);
			lab[i][j+1]=new JLabel("*");
	    	add(lab[i][j+1]);
	    	lab[i][j+2]=new JLabel(" "+(int)y);
	    	add(lab[i][j+2]);
	    	lab[i][j+3]=new JLabel("=");
	    	add(lab[i][j+3]);
	    	text[i] =new JTextField("      ");
			add(text[i]);
			break;
			
		case "/":
			exactDivide();
			lab[i][j]=new JLabel(" "+x);
			add(lab[i][j]);
			lab[i][j+1]=new JLabel("/");
	    	add(lab[i][j+1]);
	    	lab[i][j+2]=new JLabel(" "+(int)y);
	    	add(lab[i][j+2]);
	    	lab[i][j+3]=new JLabel("=");
	    	add(lab[i][j+3]);
	    	text[i] =new JTextField("      ");
			add(text[i]);
			break;
			
			}
			
		}
		 b1.addActionListener(this);		//添加按钮做出应答
		 add(b1);
	}

	public static void main(String[] args) {
		UI g=new UI();
		g.setLayout(new FlowLayout(1,10,3));
		g.setTitle("四则运算");
		g.setLocation(1000, 100);
		g.setSize(500,300);
		g.setVisible(true);
		g.setResizable(false);
		g.setDefaultCloseOperation(EXIT_ON_CLOSE);
		
	}
}

 

这是后来修老师上课讲到划分和权限问题,我把代码分为了逻辑层和应用层。

package package2;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Random;

public class UI extends JFrame implements ActionListener{  
		
    protected static int x;	
    protected static float y;	
    protected static float z;				//x为被除数,y为除数,z为暂存x,y的商
			
    JLabel[][] lab=new JLabel[10][4];		//存放四则运算的数和运算符
    JTextField[] text=new JTextField[10];		//存放输入结果
	Random random =new Random();
	JButton b1=new JButton("提交");

	public void actionPerformed(ActionEvent a) {
		int right_count=0;		//记录正确的个数
		String char_string;
		if(a.getSource()==b1) {
			for(int i=0;i<10;i++) {
				int j=0;
				char_string=lab[i][j+1].getText();
				
				switch (char_string) {		//判断是哪一个运算符对应的算式
				case "+":
					try {		//Integer.parseInt该方法会抛出异常
					if(Integer.parseInt(lab[i][j].getText().trim())+Integer.parseInt(lab[i][j+2].getText().trim())==Integer.parseInt(text[i].getText().trim()))
					right_count++;
					}catch (NumberFormatException e) {
						e.printStackTrace();
					}
					break;
					
				case "-":
					try {
					if(Integer.parseInt(lab[i][j].getText().trim())-Integer.parseInt(lab[i][j+2].getText().trim())==Integer.parseInt(text[i].getText().trim()))
					right_count++;
					}catch (NumberFormatException e) {
						e.printStackTrace();
					}
					break;
					
				case "*":
					try {
					if(Integer.parseInt(lab[i][j].getText().trim())*Integer.parseInt(lab[i][j+2].getText().trim())==Integer.parseInt(text[i].getText().trim()))
					right_count++;
					}catch (NumberFormatException e) {
						e.printStackTrace();
					}
					break;
					
				case "/":
					try {
					if(Integer.parseInt(lab[i][j].getText().trim())/Integer.parseInt(lab[i][j+2].getText().trim())==Integer.parseInt(text[i].getText().trim()))
					right_count++;
					}catch (NumberFormatException e) {
						e.printStackTrace();
					}
					break;
	
				}
				
			}
			b1.setText("你答对了"+right_count+"题");			//最后评分输出到button上
			
		}
	}
	
	UI(){
		int j=0;
		String ch;
		
		for(int i=0;i<10;i++) {
		x=Logic.produceNumber1();
		y=Logic.produceNumber2();	
		Logic.bigSubtractsmall();
		ch=Logic.chooseCharacter();		
		switch(ch) {		//判断产生的是哪个运算符
		case "+" :
			Logic.underHundred();
			lab[i][j]=new JLabel(" "+x);
			add(lab[i][j]);
			lab[i][j+1]=new JLabel("+");
	    	add(lab[i][j+1]);
	    	lab[i][j+2]=new JLabel(" "+(int)y);		//被除数y为float型转为int型
	    	add(lab[i][j+2]);
	    	lab[i][j+3]=new JLabel("=");
	    	add(lab[i][j+3]);
	    	text[i] =new JTextField("      ");
			add(text[i]);
			break;
		
		case "-":
			lab[i][j]=new JLabel(" "+x);
			add(lab[i][j]);
			lab[i][j+1]=new JLabel("-");
	    	add(lab[i][j+1]);
	    	lab[i][j+2]=new JLabel(" "+(int)y);
	    	add(lab[i][j+2]);
	    	lab[i][j+3]=new JLabel("=");
	    	add(lab[i][j+3]);
	    	text[i] =new JTextField("      ");
			add(text[i]);
			break;
			
		case "*":
			Logic.underHundred2();
			lab[i][j]=new JLabel(" "+x);
			add(lab[i][j]);
			lab[i][j+1]=new JLabel("*");
	    	add(lab[i][j+1]);
	    	lab[i][j+2]=new JLabel(" "+(int)y);
	    	add(lab[i][j+2]);
	    	lab[i][j+3]=new JLabel("=");
	    	add(lab[i][j+3]);
	    	text[i] =new JTextField("      ");
			add(text[i]);
			break;
			
		case "/":
			Logic.exactDivide();
			lab[i][j]=new JLabel(" "+x);
			add(lab[i][j]);
			lab[i][j+1]=new JLabel("/");
	    	add(lab[i][j+1]);
	    	lab[i][j+2]=new JLabel(" "+(int)y);
	    	add(lab[i][j+2]);
	    	lab[i][j+3]=new JLabel("=");
	    	add(lab[i][j+3]);
	    	text[i] =new JTextField("      ");
			add(text[i]);
			break;
			
			}
			
		}
		b1.addActionListener(this);		//添加按钮做出应答
		add(b1);
		setLayout(new FlowLayout(1,10,3));
		setTitle("四则运算");
		setLocation(1000, 100);
		setSize(500,300);
		setVisible(true);
		setResizable(false);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	public static void main(String[] args) {
		UI g=new UI();
		g.setResizable(false);
		
	}
}

  

package package2;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Logic {
	
	static Random random =new Random();
	
	public static int produceNumber1() {	//产生被除数
		int random_number_x;
		random_number_x=random.nextInt(50)+1;
		return random_number_x;
	}
	
	public static float produceNumber2() {		//产生除数
		int random_number_y;
		random_number_y=random.nextInt(50)+1;
		return random_number_y;
	}
	
	public static void underHundred() {	//使加法结果小于一百
		while(UI.x+UI.y>100) {
			UI.y--;
			if(UI.x+UI.y<100)
				break;
		}
	}
	
	public static void underHundred2() {	//使乘积结果小于一百
		while(UI.x*UI.y>100) {
			UI.y--;
			if(UI.x*UI.y<100) 
				break;
		}
	}
	
	
	public static void bigSubtractsmall() {	//完成大减小
		while(UI.x-UI.y<0) {
			UI.x++;
			if(UI.x-UI.y>0)
				break;
		}
	}
	
	public static void exactDivide() {	//使整除
		try {
			UI.z=UI.x/UI.y;
		}
		catch (ArithmeticException e) {
			e.printStackTrace();
		}
		
		Pattern pattern=Pattern.compile("\\.0$");	//若不是以.0结尾,就没有整除
		String s = String.valueOf(UI.z);
		Matcher matcher=pattern.matcher(s);
		while(!matcher.find()) {		//改变被除数y的值
			UI.y=1f;
			UI.y++;
			UI.z=UI.x/UI.y;
			s = String.valueOf(UI.z);
			matcher=pattern.matcher(s);
			if(matcher.find())
				break;
		}
	}
	
	public static String chooseCharacter() {		//随机选择四种运算符的一个
		char[] a={'+','-','*','/'};
		String charString=String.valueOf(a[random.nextInt(a.length)]);
		return charString;
		
	}

}

这是分开之后的运行结果,仍然可以正常运行。

 

 

5.项目github地址

https://github.com/bigApple00/four-types-compute

直接看图,package1中是未划分的版本,package2是划分为用户和算法层。

 

 

 这是push 、pull request 和merge的过程。

 

 

 

实验总结


之前没做过Java的项目,这次用Java和队友一起写了这个小程序,进一步熟悉了Java语言。在编程过程中遇到很多问题,就比如说正则表达式的使用,GUI的构造函数,都是不太熟悉。只能一点一点去查资料去学习,不断探索,发现问题,寻找解决办法,修改,调试,发现问题....就这样循环下去,直到消除大部分bug能基本运行。还有button和label的布局,用了流式布局显得不是很美观。整数的范围由于为了实现一些要求限制,整除什么的,范围不是很大,这是一方面的不足。

这个小项目虽然不是很起眼,但是包含了我很多的学习探索的过程,勉强说得上增加了项目经验。

进一步掌握了git的命令,GitHub的操作,Java语言,eclipse的debug操作,结对编程的合作经历。

 

 

posted @ 2020-04-05 13:16  蔡虚空  阅读(215)  评论(0编辑  收藏  举报