结对作业
—— 用户界面设计
徐楠青 PB16120408
王馨儿 PB16060765
项目简介:
本次结对编程的任务是写一个能自动生成小学四则运算题目并给出答案的软件,分为core组和ui组。我们抽到的是ui组,负责用户界面设计。
github地址:https://github.com/EstherXr/learngit/tree/master
目录
1.1 需求分析
1.2 功能设计
1.3 界面设计
1.4 代码架构
1.5 测试运行
1.6 PSP
1.7 总结
1.1 需求分析
在core组的基础上完成Windows和Linux电脑图形界面的程序,使其有一定的界面和辅助功能,最终交付给用户使用。
1.2 功能设计
1.3 界面设计
初始界面:1)输入题目数量,操作数数量,操作数最大值,结果最大值,小数精度
2)是否支持加减乘除、小数、真分数、乘方运算
3)是否需要启用错题记录功能
4)是否展示历史记录
完成初始设置后,点击“OK”,提示输入合法与否与生成题目数量。
做题界面:1)界面上方显示20秒倒计时,倒计时结束自动进入下一题且该题得分为0
2)输入答案后可以点击“下一题”按钮
3)所有题目答题结束可以点击“提交”按钮,显示得分
若选择错题记录功能,则在做题过程中的所有错题都将会被记录到一文件中。
若选择历史记录功能,则每一次的成绩都将会被记录到一文件中。
若选择清空错题记录,则记录错题的文件将会被一键清空。
在过程中,可以随时点击“Reset"按钮,回到初始界面进行各种设置。
1.4 代码架构
首先通过Qt Creator中的ui界面安放各个Push Button,再转到每个Push Button的槽编写代码。
OK Button:
1 void Widget::on_pushButton_clicked()//OK Button 2 { 3 QString a=tr("叮咚!题目已生成:"); 4 QString b=ui->lineEdit_2->text(); 5 QString str=a+b; 6 QString exe; 7 canshu sample; 8 9 bool ok; 10 int sign; 11 total=b.toInt(&ok,10); //将字符串转换为int整形数据 12 13 string c_str; 14 c_str=ui->lineEdit_2->text().toStdString();//问题数量 15 sample.num_ques=c_str+" "; 16 17 ok=ui->checkBox_6->checkState();//是否支持加法运算 18 if(ok==true) 19 add=1; 20 else 21 add=0; 22 23 ok=ui->checkBox_7->checkState();//是否支持减法运算 24 if(ok==true) 25 sub=1; 26 else 27 sub=0; 28 29 ok=ui->checkBox_8->checkState();//是否支持乘法运算 30 if(ok==true) 31 mul=1; 32 else 33 mul=0; 34 ok=ui->checkBox_9->checkState();//是否支持除法运算 35 if(ok==true) 36 div1=1; 37 else 38 div1=0; 39 ok=ui->checkBox_3->checkState();//是否支持小数运算 40 if(ok==true) 41 decimal=1; 42 else 43 decimal=0; 44 ok=ui->checkBox_4->checkState();//是否支持真分数运算 45 if(ok==true) 46 real=1; 47 else 48 real=0; 49 ok=ui->checkBox_5->checkState();//是否支持乘方运算 50 if(ok==true) 51 power=1; 52 else 53 power=0; 54 55 op=ui->lineEdit->text().toStdString()+" ";//操作数的个数 56 c_str=ui->lineEdit_3->text().toStdString();//操作数的最大值 57 sample.scalemax_op=c_str+" "; 58 jingdu=ui->lineEdit_7->text().toStdString()+" ";//小数精度 59 biggest=ui->lineEdit_6->text().toStdString()+" ";//结果最大值 60 61 sign=Setting(sample); 62 if(sign==-1) 63 { 64 QMessageBox::warning(this, tr("提示"),tr("非法输入")); 65 ui->lineEdit_2->clear(); //clear lineEdit_2, make users fill in the number of exercise again 66 ui->lineEdit->clear(); 67 ui->lineEdit_3->clear(); 68 ui->lineEdit_6->clear(); 69 ui->lineEdit_7->clear(); 70 ui->checkBox->setCheckState(Qt::Unchecked); 71 ui->checkBox_2->setCheckState(Qt::Unchecked); 72 ui->checkBox_3->setCheckState(Qt::Unchecked); 73 ui->checkBox_4->setCheckState(Qt::Unchecked); 74 ui->checkBox_5->setCheckState(Qt::Unchecked); 75 ui->checkBox_6->setCheckState(Qt::Unchecked); 76 ui->checkBox_7->setCheckState(Qt::Unchecked); 77 ui->checkBox_8->setCheckState(Qt::Unchecked); 78 ui->checkBox_9->setCheckState(Qt::Unchecked); 79 return; 80 }//how to deal with error input? 81 82 score=(int *)malloc(sizeof(int)*total); //allot saving spaces 83 if(total==1) 84 ui->pushButton_4->setEnabled(false);//if there is one exercise,disenable "xia yi ti" button 85 for(int i=0;i<total;i++) 86 score[i]=0; 87 88 exe=QString::fromStdString(expResult[circle-1].express); 89 ui->label_3->setText(exe); 90 ui->lineEdit_2->clear(); //clear lineEdit_2, and users put the answer in it 91 ui->lineEdit->clear(); 92 ui->lineEdit_3->clear(); 93 ui->lineEdit_6->clear(); 94 ui->lineEdit_7->clear(); 95 ui->pushButton->setVisible(false); 96 ui->pushButton_2->setVisible(false); //make "OK" and "Cancel" buttons unvisible 97 ui->lineEdit->setEnabled(false); 98 ui->lineEdit_3->setEnabled(false); 99 ui->lineEdit_6->setEnabled(false); 100 ui->lineEdit_7->setEnabled(false); 101 ui->checkBox->setEnabled(false); 102 ui->checkBox_2->setEnabled(false); 103 ui->checkBox_3->setEnabled(false); 104 ui->checkBox_4->setEnabled(false); 105 ui->checkBox_5->setEnabled(false); 106 ui->checkBox_6->setEnabled(false); 107 ui->checkBox_7->setEnabled(false); 108 ui->checkBox_8->setEnabled(false); 109 ui->checkBox_9->setEnabled(false); 110 ui->pushButton_4->setVisible(true); 111 ui->pushButton_5->setVisible(true); //make "xia yi ti" and "ti jiao" buttons visible 112 QMessageBox::information(this, tr("提示"), str);//tell users the exercise have been placed 113 114 timer = new QTimer(this); 115 tim = new QTimer(this); 116 117 connect(timer, SIGNAL(timeout()), this, SLOT(showTimelimit())); 118 connect(tim, SIGNAL(timeout()), this, SLOT(on_pushButton_4_clicked())); 119 120 timer->start(1000); 121 tim->start(TIME); 122 if(total==1) 123 { 124 disconnect(tim, SIGNAL(timeout()), this, SLOT(on_pushButton_4_clicked())); 125 connect(tim, SIGNAL(timeout()), this, SLOT(on_pushButton_5_clicked())); 126 } 127 128 if(num>=20) 129 { 130 timer->stop(); 131 // tim->stop(); 132 } 133 }
Next Question Button:
1 void Widget::on_pushButton_4_clicked()//下一题按钮 2 { 3 timerinit(); 4 timinit(); 5 6 timer = new QTimer(this); 7 connect(timer, SIGNAL(timeout()), this, SLOT(showTimelimit())); 8 tim = new QTimer(this); 9 connect(tim, SIGNAL(timeout()), this, SLOT(on_pushButton_4_clicked())); 10 11 timer->start(1000); 12 tim->start(TIME); 13 14 if(num>=20) 15 { 16 timer->stop(); 17 // tim->stop(); 18 } 19 20 circle++; 21 QString c="题目"; 22 QString d=QString::number(circle, 10); 23 QString str1; 24 QString e,exe; 25 string f; 26 27 if(circle<=total) 28 { 29 if(circle==total) 30 { 31 ui->pushButton_4->setEnabled(false); 32 disconnect(timer, SIGNAL(timeout()), this, SLOT(showTimelimit())); 33 disconnect(tim, SIGNAL(timeout()), this, SLOT(on_pushButton_4_clicked())); 34 connect(timer, SIGNAL(timeout()), this, SLOT(showTimelimit())); 35 connect(tim, SIGNAL(timeout()), this, SLOT(on_pushButton_5_clicked())); 36 } 37 exe= QString::fromStdString(expResult[circle-1].express); 38 str1=c+d+":"+exe; 39 ui->label_3->setText(str1); 40 e=ui->lineEdit_2->text(); 41 f=e.toStdString(); 42 if(f.compare(expResult[circle-2].result)==0) 43 score[circle-2]=1; 44 else 45 score[circle-2]=0; //judge whether the answer is correct 46 ui->lineEdit_2->clear(); 47 } 48 }
Reset Button:
1 void Widget::on_pushButton_3_clicked()//Reset 2 { 3 timerinit(); 4 timinit(); 5 6 ui->pushButton->setVisible(true); 7 ui->pushButton_2->setVisible(true);//make "OK" and "Cancel" buttons visible 8 ui->pushButton_4->setVisible(false); 9 ui->pushButton_5->setVisible(false);//make "xia yi ti" and "ti jiao" buttons unvisible 10 ui->lineEdit_2->clear(); //clear lineEdit_2, make users fill in the number of exercise again 11 ui->label_3->setText(tr("请在下行中输入题目总数")); 12 ui->pushButton_4->setEnabled(true); 13 ui->pushButton_5->setEnabled(true); 14 ui->lineEdit->setEnabled(true); 15 ui->lineEdit_3->setEnabled(true); 16 ui->lineEdit_6->setEnabled(true); 17 ui->lineEdit_7->setEnabled(true); 18 ui->checkBox->setEnabled(true); 19 ui->checkBox_2->setEnabled(true); 20 ui->checkBox_3->setEnabled(true); 21 ui->checkBox_4->setEnabled(true); 22 ui->checkBox_5->setEnabled(true); 23 ui->checkBox_6->setEnabled(true); 24 ui->checkBox_7->setEnabled(true); 25 ui->checkBox_8->setEnabled(true); 26 ui->checkBox_9->setEnabled(true); 27 ui->checkBox->setCheckState(Qt::Unchecked); 28 ui->checkBox_2->setCheckState(Qt::Unchecked); 29 ui->checkBox_3->setCheckState(Qt::Unchecked); 30 ui->checkBox_4->setCheckState(Qt::Unchecked); 31 ui->checkBox_5->setCheckState(Qt::Unchecked); 32 ui->checkBox_6->setCheckState(Qt::Unchecked); 33 ui->checkBox_7->setCheckState(Qt::Unchecked); 34 ui->checkBox_8->setCheckState(Qt::Unchecked); 35 ui->checkBox_9->setCheckState(Qt::Unchecked); 36 ui->label_2->clear(); 37 circle=1; 38 sum=0; 39 if(score!=NULL) 40 { 41 free(score); 42 score=NULL; 43 } 44 }
Hand In Button:
1 void Widget::on_pushButton_5_clicked()//hand in button 2 { 3 timerinit(); 4 timinit(); 5 6 QString a,b,e,str; 7 int i; 8 string f; 9 e=ui->lineEdit_2->text(); 10 f=e.toStdString(); 11 if(f.compare(expResult[circle-1].result)==0) 12 score[circle-1]=1; 13 else 14 score[circle-1]=0; //judge whether the answer is correct 15 ui->lineEdit_2->clear(); 16 for(i=0;i<total;i++) 17 { 18 sum+=score[i]; 19 } 20 ui->pushButton_4->setEnabled(false); 21 ui->pushButton_5->setEnabled(false); 22 ui->checkBox->setCheckState(Qt::Unchecked); 23 ui->checkBox_2->setCheckState(Qt::Unchecked); 24 ui->checkBox_3->setCheckState(Qt::Unchecked); 25 ui->checkBox_4->setCheckState(Qt::Unchecked); 26 ui->checkBox_5->setCheckState(Qt::Unchecked); 27 ui->checkBox_6->setCheckState(Qt::Unchecked); 28 ui->checkBox_7->setCheckState(Qt::Unchecked); 29 ui->checkBox_8->setCheckState(Qt::Unchecked); 30 ui->checkBox_9->setCheckState(Qt::Unchecked); 31 ui->label_3->clear(); 32 ui->label_2->clear(); 33 a=tr("提交成功!您的成绩为:"); 34 b=QString::number(sum, 10); 35 str=a+b; 36 QMessageBox::information(this, tr("提示"), str); //give the score 37 }
1.5 测试运行
在与core对接并完善页面之后,下面选用了与某一组对接以后的最终界面:
输入题目数量、操作数个数与操作数最大值,并选择想要练习的运算类型后,输出提示界面:
做题时的界面:
做题结束,显示成绩:
若选用错题记录功能,则在文件中显示历史错题:
1.6 PSP
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
90 |
90 |
.Estimate |
估计这个任务需要多少时间 |
90 |
90 |
Development |
开发 |
3420 |
3600 |
Analysis |
需求分析(包括学习新技术) |
360 |
380 |
.Design Spec |
生成设计文档 |
360 |
380 |
.Design Review |
设计复审 |
180 |
120 |
Coding Standard |
代码规范 |
180 |
200 |
Design |
具体设计 |
720 |
740 |
Coding |
具体编码 |
1440 |
1480 |
Code Review |
代码复审 |
90 |
120 |
Test |
测试(自我测试,修改代码,提交修改) |
180 |
200 |
Reporting |
报告 |
540 |
540 |
Test Report |
测试报告 |
180 |
180 |
Size Measurement |
计算工作量 |
180 |
180 |
Postmortem & Process Improvement Plan |
事后总结,并提出过程改进计划 |
180 |
180 |
All |
合计 |
4050 |
4250 |
1.7 总结
1.7.1 结对编程的意义
每个人在各自独立设计,实现软件的过程中,避免不了走弯路和犯错误。而在结对编程的过程中,因为有频繁的交流和讨论,可以在一定程度上扬长避短,减少犯错的几率。遇到困难的时候,可以一起想办法。当有另一个人和你同时工作的时候,你会不好意思开小差,也不好意思糊弄和划水。
本次结对编程遇到的最主要的困难是,我们都是第一次接触UI设计,不会使用相关的工具。但是大家在一起学习的氛围很好。其次,就是在与core组对接的时候,会发现各种各样的BUG。
1.7.2 走上工作岗位后,是否选择结对编程用于解决部分任务?
走上工作岗位后,我会试着在部分工作情况下采用结对编程的方式。首先结对编程具有一些非常好的性质,它能够让两个人在编程的过程中相互学习,共同成长。此外,还能增进我们的人际交流与合作能力,是非常必要的。然而,在追求效率的方面,结对编程可能就落了下乘,由于结对常常会使两个人的工作效率下降(很难避免)。并且结对编程需要两个人的配合,如果其中一个人的性格比较“独”,那么合作就难以成功,所以说遇到能力强,性格好的人可以试着组队;如果是刺儿头,那还是敬谢不敏吧。
1.7.3 对课程的意见和看法
这门课程的名叫“现代软件工程”,课程的初衷是好的,是让我们学习一下软件的开发流程,接触实际应用中的编程。邓老师也称得上是软件工程领域的一位“老”人,加上富有经验的助教,构成了非常强大的“教练”组合。不得不说,邓老师为我们在这方面的确也是操碎了心,积极联络各方,为我们奔走找了很多资源。然而在具体的操作方面是值得商榷的。首先,在第一次个人作业的时候具体要求的不明确和频繁改动,让许多同学叫苦不迭。虽然说老师认为这是模拟实际公司中的突发情况,但是作为作业的一部分,希望老师还是不要过多地改动要求,毕竟我们也没有像实际公司一样领工资呀(括弧笑)。
其次,信息发布的不对称性,可能是因为各位喜欢在QQ群里发言的缘故,老师和助教的零碎的有效信息总被覆盖,而且并没有及时更新,叹气。
再次,在课业和任务有明显冲突的时候,“教练团”并没有给出很好的解决方案。当同学在课堂上明确提出有期中考会挤占作业时间的时候,邓老师采取了较为强硬的态度。直到快到DDL的时候才宣布延后,尽管效果一样,然而心里感觉还是不舒服的。
总的来说,有以下几点建议:1.要求在合理范围内合理变动。2.信息发布能够公开化、及时化。3.多考虑一些学生需求,以免大幅度临时变动。
1.7.4 今后的团队作业与每周的任务中,如何吸收个人作业与结对作业的经验,改善开发流程?
首先,无论是个人作业、结对编程,还是今后的团队项目,第一步都应该是做好详细认真的规划。编写高质量代码的流程应该是这样的:思考、调研、规划、编写、验证和修改。第二,在团队项目中,一定会存在针对某一个人编写的代码进行沟通交流的过程,因此代码的可读性就相当重要。对个人或者结对编程来说,制定代码规范也许用处不大,但对团队项目来说,统一的代码规范可以提高团队工作的效率。第三,有效利用源代码管理工具,避免一味使用群文件来管理。最后,切勿闭门造车,学会查阅资料,多和别人交流。