实验二 结对编程(阶段二)
一、实验目标:
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操作,结对编程的合作经历。
完

浙公网安备 33010602011771号