【现代软件工程】结对编程 —— 四则运算UI

结对作业

                            —— 用户界面设计

徐楠青 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 功能设计

  • 对上述各属性参数(生成题目的数量、操作数的数量、操作数的最大值、结果的最大值,是否支持加减乘除,是否支持乘方,是否支持小数、真分数运算等)进行设置
  • 调用Core模块得到题目和运算结果,显示题目,接受输入,并能判断答案是否正确
  • 增加“倒计时”功能,每个题目必须在20秒内完成,否则,得0分并进入下一题
  • 增加“错题记录”功能,对于答错的题,将其保存下来,当下次进行“复习”时,增大错题在练习题中的概率
  • 增加”历史纪录“功能,把用户做题的成绩纪录下来并可以展现历史纪录
  • 增加“成绩分享”功能,生成成绩单,想一想成绩单里要展现什么,仅仅是最后的得分吗?错题的类型及数量?帮用户分析其薄弱的环节,提出合理的学习建议?

 

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 }
View Code

 

  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 }
View Code

 

  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 }
View Code

 

  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 }
View Code

 

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 今后的团队作业与每周的任务中,如何吸收个人作业与结对作业的经验,改善开发流程?

  首先,无论是个人作业、结对编程,还是今后的团队项目,第一步都应该是做好详细认真的规划。编写高质量代码的流程应该是这样的:思考、调研、规划、编写、验证和修改。第二,在团队项目中,一定会存在针对某一个人编写的代码进行沟通交流的过程,因此代码的可读性就相当重要。对个人或者结对编程来说,制定代码规范也许用处不大,但对团队项目来说,统一的代码规范可以提高团队工作的效率。第三,有效利用源代码管理工具,避免一味使用群文件来管理。最后,切勿闭门造车,学会查阅资料,多和别人交流。

 

posted @ 2018-04-15 23:12  Esther_Xr  阅读(423)  评论(1编辑  收藏  举报