软件工程——结对作业(2)
一、项目选题
本次作业要求两个人合作完成,驾驶员和导航员角色自定。在小学四则运算自动生成程序和电梯调度问题中,我们选择了四则运算题目。
二、题目要求
①能够自动生成四则运算练习题
②可以定制题目数量
③用户可以选择运算符
④用户设置最大数(如十以内、百以内等)
⑤用户选择是否有括号、是否有小数
⑥用户选择输出方式(如输出到文件、打印机等)
⑦最好能提供图形用户界面(根据自己能力选做,以完成上述功能为主)
三、角色选定
- 驾驶员:王成成
- 任务
(1)能够完成全部代码工作,程序基本实现全部要求功能,并将代码上传至coding.net或者GitHub代码托管系统中。
(2)能够对导航员在本次编程工作中起到的作用给出客观评价。
- 任务
- 领航员:耿蝶芮
- 任务
(1)能够辅助驾驶员完成全部代码工作,并且为关键函数选用合适的覆盖标准设计测试用例,并编写代码进行单元自动测试。
(2)能够根据上次作业的代码检查表对驾驶员的本次工作进行评价。
- 任务
四、代码上传
五、程序设计
四则运算问题,关键是能够自动生成算数表达式。在这部分中,我们整体代码采用C++和结构体进行设计。而针对页面显示结构,我们则采用了html以及js进行设计。我们给出表达式的组数、表达式中涉及到的数据的大小范围以及数据类型。除此之外,还要考虑到生成的表达式是否含有括号、具体包含哪些运算符等。因此,我们在代码中进行了详细分析设计,并且进行了重构,从而使得代码整洁、可修改性强。
1、结构体设计
struct data
{
int num[10001];
float num1[10001];
}p[10001];
2、主函数
在主函数中,我们主要针对一些必要要求进行了判断,并依据此在其各个子函数中进行处理。对于运算符的选择,我们依据学生的要求进行设计,通过设定字符串数组来完成运算符的选择。
int main()
{
int NUM,Num,Max;
int parentheses,print_yes_no,decimal;
char op_operator[5];
cout<<"----------------------------------------------------------\n";
cout<<"请输入共有多少组运算表达式:";
cin>>NUM;
cout<<"----------------------------------------------------------\n";
cout<<"请输入运算数的最大值,以保证所有计算数据都在该数字以内: ";
cin>>Max;
cout<<"----------------------------------------------------------\n";
cout<<"请输入有无括号(1代表有括号、0代表无括号): ";
cin>>parentheses;
cout<<"----------------------------------------------------------\n";
cout<<"请输入是否将结果存到文件中(1代表存放、0代表不存放): ";
cin>>print_yes_no;
cout<<"----------------------------------------------------------\n";
cout<<"请选择输入是小数还是整数(1代表整数、0代表小数):";
cin>>decimal;
cout<<"----------------------------------------------------------\n";
cout<<"请选择输入的运算符:";
cin>>op_operator;
cout<<"----------------------------------------------------------\n";
Num=-1;
while(1)
{
if(Num<2||Num>8)
Num=int(rand()%10);//定义每个表达式有多少个参与运算的实数
else
break;
}
if(parentheses==1)
Have_parentheses(NUM,Max,Num,print_yes_no,op_operator,decimal);
else if(parentheses==0)
No_parentheses(NUM,Max,Num,print_yes_no,op_operator,decimal);
system("pause");
return 0;
}
3、括号处理
对于表达式中是否含有括号的问题,我们分为两部分:有括号形式和无括号形式。在程序中,我们利用了随机数生成函数进行处理。
(1)无括号形式的表达式
void No_parentheses(int NUM,int Max,int Num,int print_yes_no,char op_operator[],int decimal)//无括号的运算形式
{
int i,j,len;
int op;
len=strlen(op_operator);
ofstream outfile;
outfile.open("a.txt");
for(i=0;i<NUM;i++)
{
for(j=0;j<Num;j++)
{
op=int(rand()%len);
if(decimal==1)
{
p[i].num[j]=rand()%Max+1;
p[i].num[j+1]=rand()%Max+1;
}
if(decimal==0)
{
p[i].num1[j]=rand()%Max*0.3;
p[i].num1[j+1]=rand()%Max*0.7;
}
if(j<Num-1)
{
if(decimal==1)
{
cout<<p[i].num[j]<<" "<<op_operator[op]<<" ";
if(print_yes_no==1)
outfile<<p[i].num[j]<<" "<<op_operator[op]<<" ";
}
else
{
cout<<setprecision(1)<<std::fixed<<p[i].num1[j]<<" "<<op_operator[op]<<" ";
if(print_yes_no==1)
outfile<<setprecision(1)<<std::fixed<<p[i].num1[j]<<" "<<op_operator[op]<<" ";
}
}
if(j==Num-1)
{
if(decimal==1)
{
cout<<p[i].num[j]<<" ";
if(print_yes_no==1)
outfile<<p[i].num[j]<<" ";
}
else
{
cout<<setprecision(1)<<std::fixed<<p[i].num1[j];
if(print_yes_no==1)
outfile<<setprecision(1)<<std::fixed<<p[i].num1[j];
}
}
}
cout<<"= "<<"\n";
if(print_yes_no==1)
outfile<<"= "<<"\n";
}
outfile.close();
}
(2)有括号形式的表达式
void Have_parentheses(int NUM,int Max,int Num,int print_yes_no,char op_operator[],int decimal)//带括号的运算
{
int flag1=0,flag2=0;
int k1,k2;
int op;
int i,j,len;
len=strlen(op_operator);
ofstream outfile;
outfile.open("a.txt");
for(i=0;i<NUM;i++)
{
k1=-1;
k2=-1;
while(1)
{
if(k1>k2||k2-k1<2||k2>Num)
{
k1=int(rand()%(Num-1));
k2=int(rand()%(Num-1));
}
else
break;
}
for(j=0;j<Num;j++)
{
op=int(rand()%len);
if(decimal==1)
{
p[i].num[j]=rand()%Max+1;
p[i].num[j+1]=rand()%Max+1;
}
if(decimal==0)
{
p[i].num1[j]=rand()%Max*0.3;
p[i].num1[j+1]=rand()%Max*0.7;
}
if(j<Num-1)
{
if(j==k1)
{
if(decimal==1)
{
cout<<"("<<p[i].num[j]<<" "<<op_operator[op]<<" ";
flag1=1;
if(print_yes_no==1)
outfile<<"("<<p[i].num[j]<<" "<<op_operator[op]<<" ";
}
else
{
cout<<"("<<setprecision(1)<<std::fixed<<p[i].num1[j]<<" "<<op_operator[op]<<" ";
flag1=1;
if(print_yes_no==1)
outfile<<"("<<setprecision(1)<<std::fixed<<p[i].num1[j]<<" "<<op_operator[op]<<" ";
}
}
else if(j==k2)
{
if(decimal==1)
{
cout<<p[i].num[j]<<")"<<" "<<op_operator[op]<<" ";
flag2=1;
if(print_yes_no==1)
outfile<<p[i].num[j]<<")"<<" "<<op_operator[op]<<" ";
}
else
{
cout<<setprecision(1)<<std::fixed<<p[i].num1[j]<<")"<<" "<<op_operator[op]<<" ";
flag2=1;
if(print_yes_no==1)
outfile<<setprecision(1)<<std::fixed<<p[i].num1[j]<<")"<<" "<<op_operator[op]<<" ";
}
}
else
{
if(decimal==1)
{
cout<<p[i].num[j]<<" "<<op_operator[op]<<" ";
if(print_yes_no==1)
outfile<<p[i].num[j]<<" "<<op_operator[op]<<" ";
}
else
{
cout<<setprecision(1)<<std::fixed<<p[i].num1[j]<<" "<<op_operator[op]<<" ";
if(print_yes_no==1)
outfile<<setprecision(1)<<std::fixed<<p[i].num1[j]<<" "<<op_operator[op]<<" ";
}
}
}
else
{
if(flag1==1&&flag2==0)
{
if(decimal==1)
{
cout<<p[i].num[j]<<")"<<" ";
if(print_yes_no==1)
outfile<<p[i].num[j]<<")"<<" ";
}
else
{
cout<<setprecision(1)<<std::fixed<<p[i].num1[j]<<')';
if(print_yes_no==1)
outfile<<setprecision(1)<<std::fixed<<p[i].num1[j]<<')';
}
}
else
{
if(decimal==1)
{
cout<<p[i].num[j]<<" ";
if(print_yes_no==1)
outfile<<p[i].num[j]<<" ";
}
else
{
cout<<setprecision(1)<<std::fixed<<p[i].num1[j];
if(print_yes_no==1)
outfile<<setprecision(1)<<std::fixed<<p[i].num1[j];
}
}
}
}
cout<<"= "<<"\n";
if(print_yes_no==1)
outfile<<"= "<<"\n";
}
outfile.close();
}
六、界面设计
1、对于界面的设计,我们采用了html以及js等技术,大体上实现了四则运算的显示界面。实现代码如下:
- 亦或可戳地址:https://dev.tencent.com/u/wang_chengcheng/p/sizeyunsuanchengxu/git/blob/master/software_project.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<form method="post">
运算表达式组数:<input type='text' id="NUM" size="15" maxlength="10"/><br /><br />
运算数据最大值:<input type='text' id="Max" size="15" maxlength="10"/><br /><br />
表达式有无括号:
<input type="radio" name="gender1" value="有括号"/>有括号
<input type="radio" name="gender1" value="无括号"/>无括号
<br />
<br />
数据的数据类型:
<select id="datatype">
<option value=0>整数</option>
<option value=1>小数</option>
</select>
<br />
<br />
运算操作符:
<input type="checkbox" name="gender2" value="+"/>+
<input type="checkbox" name="gender2" value="-"/>-
<input type="checkbox" name="gender2" value="*"/>*
<input type="checkbox" name="gender2" value="/"/>/
</form>
<textarea name="textContent" cols="80" rows="15" id="textContent"></textarea> <br />
<form>
<input type="button" id="Button" value="Done!">
</form>
<script>
window.onload = init;
var p=[];
function Have_parentheses(NUM,Max,Num,print_yes_no,op_operator,decimal)
{
var flag1=0;
var flag2=0;
var k1;
var k2;
var op;
var i;
var j;
var len;
len=op_operator.length;
var s="";
p=new Array();
for(i=0;i<NUM;i++)
{
k1=-1;
k2=-1;
while(1)
{
if(k1>k2||k2-k1<2||k2>Num)
{
k1=Math.floor(Math.random()*(Num-1));
k2=Math.floor(Math.random()*(Num-1));
}
else
break;
}
var num=new Array();
for(j=0;j<Num+1;j++){
num.push(j);
}
p.push(num);
for(j=0;j<Num;j++)
{
op=Math.random()*len;
if(decimal==0){
p[i][j]=Math.floor(Math.random()*Max+1);
p[i][j+1]=Math.floor(Math.random()*Max+1);
}
else{
p[i][j]=(Math.random()*Max+1).toFixed(2);
p[i][j+1]=(Math.random()*Max+1).toFixed(2);
}
if(j<Num-1)
{
if(j==k1)
{
flag1=1;
s+="(";
s+=p[i][j].toString();
s+=" ";
var num=Math.floor(Math.random()*len);
s+=op_operator[num];
s+=" ";
}
else if(j==k2)
{
flag2=1;
s+=p[i][j].toString();
s+=")";
s+=" ";
var num=Math.floor(Math.random()*len);
s+=op_operator[num];
s+=" ";
}
else
{
var num=Math.floor(Math.random()*len);
s+=p[i][j].toString();s+=" ";s+=op_operator[num];s+=" ";
}
}
else
{
if(flag1==1&&flag2==0)
{
s+=p[i][j].toString();s+=")";s+=" ";
}
else
{
s+=p[i][j].toString();s+=" ";
}
}
console.log(s);
}
s+="= \n ";
}
var output = document.getElementById("textContent");
output.value=s;
}
function No_parentheses(NUM,Max,Num,print_yes_no,op_operator,decimal)
{
var flag1=0;
var flag2=0;
var k1;
var k2;
var op;
var i;
var j;
var len;
len=op_operator.length;
var s="";
p=new Array();
for(i=0;i<NUM;i++)
{
k1=-1;
k2=-1;
while(1)
{
if(k1>k2||k2-k1<2||k2>Num)
{
k1=Math.random()*5;
k2=Math.random()*5;
}
else
break;
}
var num=new Array();
for(j=0;j<Num+1;j++){
num.push(j);
}
p.push(num);
for(j=0;j<Num;j++)
{
op=Math.random()*len;
if(decimal==0){
p[i][j]=Math.floor(Math.random()*Max+1);
p[i][j+1]=Math.floor(Math.random()*Max+1);
}
else{
p[i][j]=(Math.random()*Max+1).toFixed(2);
p[i][j+1]=(Math.random()*Max+1).toFixed(2);
}
if(j<Num-1)
{
if(j==k1)
{
s+=p[i][j].toString();
s+=" ";
var num=Math.floor(Math.random()*len);
s+=op_operator[num];
s+=" ";
}
else if(j==k2)
{
s+=p[i][j].toString();
s+=" ";
var num=Math.floor(Math.random()*len);
s+=op_operator[num];
s+=" ";
}
else
{
var num=Math.floor(Math.random()*len);
s+=p[i][j].toString();s+=" ";s+=op_operator[num];s+=" ";
}
}
else
{
if(flag1==1&&flag2==0)
{
s+=p[i][j].toString();s+=" ";
}
else
{
s+=p[i][j].toString();s+=" ";
}
}
console.log(s);
}
s+="= \n ";
}
var output = document.getElementById("textContent");
output.value=s;
}
function handleButton(){
var input1=document.getElementById("NUM");
var input2=document.getElementById("Max");
var input3=document.getElementsByName("gender1");
var select =document.getElementById("datatype");
var value = select.value;
var input4 = document.getElementsByName("gender2");
var NUM,Num=-1,Max,parentheses,print_yes_no,decimal;
var op_operator=[];
NUM=input1.value;
while(1)
{
if(Num<2||Num>8)
Num=Math.floor(Math.random()*10); //定义每个表达式有多少个参与运算的实数
else
break;
}
Max=input2.value;
parentheses=-1;
if(input3[0].checked)
parentheses=1;
if(input3[1].checked)
parentheses=0;
print_yes_no=0;
if(value==1)
decimal=1;
else
decimal=0;
if(input4[0].checked)
op_operator.push('+');
if(input4[1].checked)
op_operator.push('-');
if(input4[2].checked)
op_operator.push('*');
if(input4[3].checked)
op_operator.push('/');
if(parentheses==1){ //有括号
Have_parentheses(NUM,Max,Num,print_yes_no,op_operator,decimal);
}
else if(parentheses==0){//无括号
No_parentheses(NUM,Max,Num,print_yes_no,op_operator,decimal);
}
}
function init() {
var Button = document.getElementById("Button");
Button.onclick = handleButton;
}
</script>
</head>
<body>
</body>
<html>
2、针对不同的选择条件,我们选择几种形式,并给出如下页面显示结果。
(1)选择单操作符进行表达式的生成,包括整数、小数、有无括号的形式。


(2)选择多操作符进行表达式的生成,包括整数、小数、有无括号的形式。



七、总结
本次结对作业,我和耿蝶芮同学配合十分默契。我担任驾驶员的角色,主要负责代码的编写、重构、修复以及界面的设计工作。而耿蝶芮同学作为领航员,非常负责地对编写的代码进行检查,并提出意见,从而充分满足要求。在配合的过程中,耿蝶芮同学尽职尽责、一直在不断监督,生怕出现一些问题。而我在编写 过程中也遇到了一些问题,尤其是将运算表达式填充到文件中时。最后经过查找资料,并且不断修改,发现导致问题出现的原因在于频繁地开关文件。经过修改之后,问题得以解决。同时,耿蝶芮同学对于代码质量以及代码规范要求很高,具有较好的风格,所以我们也遇到了一些其他的小问题,不过好在最后得以解决。在合作的过程中,我们发现了彼此的优缺点,取其精华,去其糟粕,非常成功地完成了本次作业。通过这次合作,使我们能够更好理解到底什么是合作,这个过程是非常享受的。我们为着同一个目标一起努力,不断向对方学习,不断交流思想。我相信这次经历对未来的团队合作也会有很大益处。最后还是感谢我的伙伴——耿耿!

浙公网安备 33010602011771号