结对编程作业
一、结对同学信息:
名字 | 学号 | 博客地址 | 码云地址 |
---|---|---|---|
徐璐琳 | 201521123010 | 徐璐琳-博客园 | 徐璐琳-码云 |
李家俊 | 201521123028 | 李家俊-博客园 | 李家俊-码云 |
一起讨论的照片。。
二、代码上传码云:
这里是结对编程项目地址,代码规范也已上传
三、关于代码:
①需求分析:
已经得到的这个代码是之前学长的,将项目Clone下来后运行,发现是一个可支持三种语言的、基于控制台的四则运算器,支持加减乘除的整数与分数运算。而我们的新需求则为:增加括号操作符;使出现题目中的算式不重复;去掉逻辑泥球;重构简化程序。为实现新需求,我们要先成功运行之前的代码,并对代码进行深究探索,找出其中的逻辑泥球,并重构简化。测试代码的覆盖率及对代码进行单元测试,之后再对其添加新功能,并测试性功能。
而在读旧代码的时候,发现原先代码的历史记录这一块有着明显错误,以及一些按键可以重复点击这一点,我们都对其做了改正;我们在看旧代码时,还完善了代码的一些小瑕疵。并对代码赋予了新功能(乘方、检查重复算式)。
②程序设计:
原始类图:
设计类图:
③代码展示:
- 对于加减乘除+乘方基本算法(整数):
public String int_operation()
{
int result = 0;
if(a==0)
result=f+g;
if(a==1)
result=f-g;
if(a==2)
result=f*g;
for(int i = 0; i <= flage; i++)//查询num3中有没有与result相同的元素
{
if(result == num3[i])
return null;//如果有相同的返回null
}
num3[flage++] = result;//如果没有相同的就把新的result的值放入num3中
astr = String.valueOf( result);
if(a==3)
{
if(g==0)
{
astr=int_operation();
return astr;
}
else
{
if(g!=0&&g!=1){
int d=common_divisor(f,g);
f=f/d;
g=g/d;
astr = (f+"/"+g);
}
if(g==1)
astr=(""+f);
}
}
if(a==4)
{
result=(int) Math.pow(f, g);
}
return astr;
}
- 对于加减乘除+乘方基本算法(分数):
public String fra_operation(){
this.b = new Random().nextInt(10)%(10-1+1) + 1;
this.c = new Random().nextInt(10)%(10-2+1) + 2;
this.d = new Random().nextInt(10)%(10-1+1) + 1;
this.e = new Random().nextInt(10)%(10-2+1) + 2;
if(c<b||e<d||c%b==0||e%d==0)
{
astr=fra_operation();
return astr;
}
int fz=1,fm=c*e;
if(a==0)
fz=b*e+c*d;
if(a==1){
fz=b*e-c*d;
if(fz==0)
{
return astr=("0");
}
}
if(a==2)
fz=b*d;
if(a==3)
{
fz=b*e;
fm=c*d;
}
int f=common_divisor(fm,fz);
if(f>0){
fm=fm/f;
fz=fz/f;
}
if(f<0){
fm=-fm/f;
fz=-fz/f;
}
if(a==4)
{
fz=(int) Math.pow(b*e, f);
fm=(int) Math.pow(c*d, f);
}
astr = (fz+"/"+fm);
return astr;
}
- 对于分数中最大公约数的处理:
public static int common_divisor(int m,int n)
{
while(m%n!=0){
int t=m%n;
m=n;
n=t;
}
return n;
}
- 对于计时函数:
public class Work_Time extends TimerTask{
static int y=0;
static int z=0;
@Override
public void run() {
// TODO Auto-generated method stub
String str_second = Frame.Time.getText().substring(6);
int x = Integer.parseInt(str_second);
if(Frame.Time.getText().equals("00:00.00")){
x=0;y=0;z=0;
}
x++;
if(z<10){
if(y<10)
{
if(x<100)
Frame.Time.setText("0"+z+":0"+y+"."+x);
if(x==100)
{
y++;
Frame.Time.setText("0"+z+":0"+y+".0");
x=0;
}
}
if(y<60&&y>=10)
{
if(x<100)
Frame.Time.setText("0"+z+":"+y+"."+x);
if(x==100)
{
y++;
Frame.Time.setText("0"+z+":"+y+".0");
x=0;
}
}
if(y==60){
y=0;
x=0;
z++;
}
}
if(z<60&&z>=10){
if(y<10)
{
if(x<100)
Frame.Time.setText(z+":0"+y+"."+x);
if(x==100)
{
y++;
Frame.Time.setText(z+":0"+y+".0");
x=0;
}
}
if(y<60&&y>=10)
{
if(x<100)
Frame.Time.setText(z+":"+y+"."+x);
if(x==100)
{
y++;
Frame.Time.setText(z+":"+y+".0");
x=0;
}
}
if(y==60){
y=0;
x=0;
z++;
}
else
{
Frame.Time.setText("超过一小时了,偶尔放弃也不是坏事呢。");
}
}
}
}
- 对于减少重复题目(主要代码):
int [][] num2 = new int[10][4];
int [][] num1 = new int[10][2];
int [] num3 = new int [10];//保存每道题的结果
int flage = 0;//记录num3数组中的元素个数
int flage2 = 0;//保存整数数组num1中的个数
int flage3= 0;//保存分数数组num2的个数
·
·
·
public String toString(){
if(x==true){
//先判断在num1里面有没有相同的元素
for(int i = 0; i <= flage2; i++)
{
if((f == num1[i][0] && g == num1[i][1]) || (f == num1[i][0] || g == num1[i][1]))
return null;
}
//如果没有就把原来的值放入
num1[flage2++][0] = f;
num1[flage][1] = g;
if(a==0)
qstr=(f+"+"+g+"=");
if(a==1)
qstr=(f+"-"+g+"=");
if(a==2)
qstr=(f+"*"+g+"=");
if(a==3)
qstr=(f+"/"+g+"=");
if(a==3)
qstr=(f+"/"+g+"=");
if(a==4)
qstr=(f+"^"+g+"=");
}
if(x==false){
//先判断在num2里面有没有分数运算相同的元素
for(int i = 0; i <= flage3; i++)
{
if((b == num2[i][0] && c == num2[i][1] && d == num2[i][2] && e == num2[i][3]) || (b == num2[i][2] && c == num2[i][3] && d == num2[i][0] && e == num2[i][1]))
return null;
}
//如果没有就把原来的值放入
num2[flage3++][0] = b;
num2[flage3][1] = c;
num2[flage3][2] = d;
num2[flage3][3] = e;
if(a==0)
qstr=(b+"/"+c+"+"+d+"/"+e+"=");
if(a==1)
qstr=(b+"/"+c+"-"+d+"/"+e+"=");
if(a==2)
qstr=(b+"/"+c+"*"+d+"/"+e+"=");
if(a==3)
qstr=(b+"/"+c+"/"+d+"/"+e+"=");
if(a==4)
qstr=(b+"/"+c+"^"+d+"/"+e+"=");
}
return qstr;
}
④程序运行:
以下是我们对代码进行运行的截图,原来我们只会有运行的界面,这一次学习到了很多关于测试代码的工具,所以以下也有截图展示:
程序运行视图:
乘方测试:
单元测试:
重复率测试:
HTML:
CHECKSTYLE:
效能测试:
⑤小结心得:
之前大一大二很多时候都是水过来的,这次难得好好地静下心来看一个项目的代码,结合老师题目要求的,去找代码里的逻辑泥球,逻辑混乱,冗杂的部分,然后改之。这次的结对编程给了我很多不一样的体验,觉得学到了很多东西,很多新名词,也更了解代码并不是简单的敲键盘,就像吃饭一样,有餐前小菜,正餐和餐后甜点。处理食物有很多方式,就像处理代码一样。这次也学会了运用其他测试代码的工具,感觉了解到了另一面的代码,十分有趣。
这次两人结对编程,我们的分工相对比较明确,做自己相较对方比较擅长的事,效率一下就提升上去了。而且两个人都没有拖延症,一开始做就会很快就做好,所以结对编程过程的体验是很好的。在这个过程中,问题和意见我们都会及时提出,所以沟通交流协商必不可少,这种通过合作完成一个作业的收获还是不少的,也证明了1+1>2这一说法。
逻辑泥球:我们通过一起观察深究代码,发现了之前代码中的逻辑泥球,就是对于变量定义得太多,所以在读代码的时候觉得会有一点繁琐不太方便理解,容易记杂记乱。如下代码所示,定义变量太多太杂,完全可以简单化,我认为我们代码中最大的逻辑泥球就是这里:
int a = new Random().nextInt(4);
int b = new Random().nextInt(10)%(10-1+1) + 1;
int c = new Random().nextInt(10)%(10-2+1) + 2;
int d = new Random().nextInt(10)%(10-1+1) + 1;
int e = new Random().nextInt(10)%(10-2+1) + 2;
int f = new Random().nextInt(100);
int g = new Random().nextInt(100);
public static javax.swing.JTextField Time;
private javax.swing.JButton Review;
private javax.swing.JLabel Right_answer1;
private javax.swing.JLabel Right_answer10;
private javax.swing.JLabel Right_answer2;
private javax.swing.JLabel Right_answer3;
private javax.swing.JLabel Right_answer4;
private javax.swing.JLabel Right_answer5;
private javax.swing.JLabel Right_answer6;
private javax.swing.JLabel Right_answer7;
private javax.swing.JLabel Right_answer8;
private javax.swing.JLabel Right_answer9;
private javax.swing.JLabel Right_percent;
private javax.swing.JButton Set_qusetion;
private javax.swing.JLabel Time_Cost;
private javax.swing.JLabel Tip1;
private javax.swing.JLabel Tip10;
private javax.swing.JLabel Tip2;
private javax.swing.JLabel Tip3;
private javax.swing.JLabel Tip4;
private javax.swing.JLabel Tip5;
private javax.swing.JLabel Tip6;
private javax.swing.JLabel Tip7;
private javax.swing.JLabel Tip8;
private javax.swing.JLabel Tip9;
private javax.swing.JTextField answer1;
private javax.swing.JTextField answer10;
private javax.swing.JTextField answer2;
private javax.swing.JTextField answer3;
private javax.swing.JTextField answer4;
private javax.swing.JTextField answer5;
private javax.swing.JTextField answer6;
private javax.swing.JTextField answer7;
private javax.swing.JTextField answer8;
private javax.swing.JTextField answer9;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel22;
private javax.swing.JLabel jLabel23;
private javax.swing.JLabel jLabel24;
private javax.swing.JLabel jLabel25;
private javax.swing.JLabel jLabel26;
private javax.swing.JLabel jLabel27;
private javax.swing.JLabel jLabel28;
private javax.swing.JLabel jLabel29;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel30;
private javax.swing.JLabel jLabel31;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JPanel jPanel1;
private javax.swing.JLabel qusetion1;
private javax.swing.JLabel qusetion10;
private javax.swing.JLabel qusetion2;
private javax.swing.JLabel qusetion3;
private javax.swing.JLabel qusetion4;
private javax.swing.JLabel qusetion5;
private javax.swing.JLabel qusetion6;
private javax.swing.JLabel qusetion7;
private javax.swing.JLabel qusetion8;
private javax.swing.JLabel qusetion9;