结对编程——四则运算出题及核对答案

发布时间 2023-04-13 13:55:25作者: 不迟到

结对编程对象:2152215 

目录

一、前言

二、题设

三、分析和设计思路

四、功能实现和代码

五、运行结果

六、实验总结和体会

 

一、前言

   结对编程(英语:Pair programming)是一种敏捷软件开发的方法,两个程序员在一个计算机上共同工作。一个人输入代码,而另一个人审查他输入的每一行代码。输入代码的人称作驾驶员,审查代码的人称作观察员(或导航员)。两个程序员经常互换角色。在结对编程中,观察员同时考虑工作的战略性方向,提出改进的意见,或将来可能出现的问题以便处理。这样使得驾驶者可以集中全部注意力在完成当前任务的“战术”方面。观察员当作安全网和指南。结对编程对开发程序有很多好处。比如增加纪律性,写出更好的代码等。

   本次实验由两位同学以结对编程的方式完成,即一个同学coding,另一个同学在旁边审核代码,再交换角色

二、题设

   ·小学老师要每周给同学出 300道四则运算练习题

   ·这个程序可以使用很多种实现方式:C/C++/C#/VB.net/Java/Excel/Unix Shell/Emacs/Powershell/Vbscript/Python

   ·练习题是一或两个运算符(a+ba+b+C)100 以内的数宇,先不写答案

   ·检查答案是否正确,并且保证答案在0-100之间

   ·尽可能地多设置一些条件

三、分析和设计思路

   对于这个程序,我和2152215同学都有很多想法。在组队成功之后,我们关于最后实现成果进行了一次激烈的讨论,我们的共同想法是不使用传统的一道题一道题的出题方式,将这组题目全部展示出来,再进行答题。这样可以直观地看出这组题地难易程度和未答题目,提前看到题目也可以提高做题效率,也更贴近于纸质化答题。

   我们的设计思路是,在随机出题之后先讲cout出来,同时运算结果存在数组arr[]里面,与输入的答案进行核对,再记录正确/错误的题目数量,且用另一个数组p[]记录回答错误的题目的下表。

   根据我们对该程序的期望,综合考虑,还是使用相对擅长的c++语言来编写程序。

   实现了两个数的四则运算之后,我们打算在这个功能的基础上进行扩展,再加一个困难模式,用来实现三个数的四则运算。设计思路是设置5个变量,3个数字abc2个运算符号f1f2,都用rand()函数进行随机数分配,先记录ab的运算结果,再和c运行运算得到最终结果,和两个数的运算一样,后续的操作和两个数的操作一样。

   同时,为了实现个性化需求,我们又增加了一个限时模式,用time(NULL)获取当前的时间,答题结束时间-开始时间就是答题的时间。如果答题时间超过规定时间就结束答题。这样子可以让答题者在保证自己的正确率的同时,练习答题的速度,从而提高答题者的运算能力。

四、功能实现和代码

编写语言:c++

   1.简单模式实现 a [+ - * /] b 

   两个随机数的四则运算,可以手动输入需要的题目数量,这两个数和计算结果都在0-100之间,除数不为0,分别统计出答题正确和错误的数量,计算出正确率,并且对于错题进行题号提示结果展示。

 

int suiji()
{
    srand((unsigned)time(NULL));//随机函数
    clockid_t a = 0;
    struct timespec p = {0, 0};
    clock_gettime(a, &p);
    srand((unsigned)p.tv_nsec);
    return rand();
}
int chuti2()
{
    int a,b,f;
    a=suiji()%100;
    Sleep(10);
    b=suiji()%100;
    Sleep(200);
    f=suiji()%4;//运算符号
    switch(f)
    {
        case 0:
            while(1)
            {
                a=suiji()%100;
                Sleep(10);
                b=suiji()%100;
                if(a+b<=100)
                {
                    cout<<a<<" + "<<b<<" = ";
                    cout<<"\t\t";
                    intal++;
                    if(intal%5==0)
                        cout<<endl;
                    return a+b;
                }
            }
            break;
        case 1:
            while(1)
            {
                a=suiji()%100;
                Sleep(10);
                b=suiji()%100;
                if(a>b)
                {
                    cout<<a<<" - "<<b<<" = ";
                    cout<<"\t\t";
                    intal++; 
                    if(intal%5==0)
                        cout<<endl;
                    return a-b;
                }
            }
            break;
        case 2:
            while(1)
            {
                a=suiji()%100;
                Sleep(10);
                b=suiji()%100;
                if(a*b<=100)
                {
                    cout<<a<<" * "<<b<<" = ";
                    cout<<"\t\t";
                    intal++;
                    if(intal%5==0)
                        cout<<endl;
                    return a*b;
                }
            }
            break;
        case 3:
            while(1)
            {
                a=suiji()%100;
                Sleep(10);
                b=suiji()%100;
                if(b!=0)
                {
                    if(a%b==0)
                    {
                        cout<<a<<" / "<<b<<" = ";
                        cout<<"\t\t";
                        intal++;
                        if(intal%5==0)
                            cout<<endl;
                        return a/b;
                    }    
                }
            }
            break;
     } 
}
void simple()
{
    cout<<"请输入需要的题数:"<<endl;
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        Sleep(10);
        arr[i]=chuti2();//打印并存结果
    }
    cout<<endl;
    cout<<"请输入你的答题结果:"<<endl; 
    for(int j=0;j<n;j++)
    {
        int shu;
        cin>>shu;
        if(shu==arr[j])
        {
            rig++;
        }
        else if(shu!=arr[j])
        {
            p[fal]=j;
            fal++;
        }
    }
    cout<<"您一共答对了"<<rig<<"道题!也有"<<fal<<"道题回答错误!"<<endl;
    cout<<"您的正确率是"<<((double)rig/intal)*100<<"%"<<endl;
    if(fal!=0)
        cout<<"错题结果如下:" <<endl;
    for(int i=0;i<fal;i++)
    {
        cout<<""<<p[i]+1<<"道题正确答案是:"<<arr[p[i]]<<endl;
    }
}
简单模式代码

 

         2.困难模式实现( a [+ - * /] b )[+ - * /] c

   三个随机数的四则运算,可以手动输入需要的题目数量,这三个数和计算结果都在0-100之间,除数不为0,分别统计出答题正确和错误的数量,计算出正确率,并且对于错题进行题号提示结果展示。但是由于我们两个人的能力有限,还未能实现不加括号的情况。

 

int chuti3()
{
    int a,b,c,f1,f2;
    int result;
    a=suiji()%100;
    Sleep(10);
    b=suiji()%100;
    Sleep(200);
    f1=suiji()%4;//前一个运算符号
    switch(f1)
    {
        case 0:
            while(1)
            {
                a=suiji()%100;
                Sleep(10);
                b=suiji()%100;
                if(a+b<=100)
                {
                    cout<<" ( "<<a<<" + "<<b<<" ) ";
                    result=a+b;
                    break;
                }
            }
            break;
        case 1:
            while(1)
            {
                a=suiji()%100;
                Sleep(10);
                b=suiji()%100;
                if(a>b)
                {
                    cout<<" ( "<<a<<" - "<<b<<" ) ";
                    result=a-b;
                    break;
                }
            }
            break;
        case 2:
            while(1)
            {
                a=suiji()%100;
                Sleep(10);
                b=suiji()%100;
                if(a*b<=100)
                {
                    cout<<" ( "<<a<<" * "<<b<<" ) ";
                    result=a*b;
                    break;
                }
            }
            break;
        case 3:
            while(1)
            {
                a=suiji()%100;
                Sleep(10);
                b=suiji()%100;
                if(b!=0 && a%b==0)
                {
                    cout<<" ( "<<a<<" / "<<b<<" ) ";
                    result=a/b;
                    break;
                }
            }
            break;
    }
    f2=suiji()%4;//后一个运算符号
    c=suiji()%100;
    switch(f2)
    {
        case 0:
            while(1)
            {
                c=suiji()%100;
                if(result+c<=100)
                {
                    cout<<" + "<<c<<" = ";
                    cout<<"\t\t";
                    intal++;
                    if(intal%3==0)
                        cout<<endl;
                    return result+c;
                }
            }
            break;
        case 1:
            while(1)
            {
                c=suiji()%100;
                if(result>c)
                {
                    cout<<" - "<<c<<" = ";
                    cout<<"\t\t";
                    intal++;
                    if(intal%3==0)
                        cout<<endl;
                    return result-c;
                }
            }
            break;
        case 2:
            while(1)
            {
                c=suiji()%100;
                if(result*c<=100)
                {
                    cout<<" * "<<c<<" = ";
                    cout<<"\t\t";
                    intal++;
                    if(intal%3==0)
                        cout<<endl;
                    return result*c;
                }    
            }    
            break;
        case 3:
            while(1)
            {
                c=suiji()%100;
                if(c!=0 && result%c==0)
                {
                    cout<<" / "<<c<<" = ";
                    cout<<"\t\t";
                    intal++;
                    if(intal%3==0)
                        cout<<endl;
                    return result/c;
                }
            }
            break;
    }
}
void difficult()
{
    cout<<"请输入需要的题数:"<<endl;
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        Sleep(10);
        arr[i]=chuti3(); //打印并存结果 
    }
    cout<<endl;
    cout<<"请输入你的答题结果:"<<endl; 
    for(int j=0;j<n;j++)
    {
        int shu;
        cin>>shu;
        if(shu==arr[j])
        {
            rig++;
        }
        else if(shu!=arr[j])
        {
            p[fal]=j;
            fal++;
        }
    }
    cout<<"您一共答对了"<<rig<<"道题!也有"<<fal<<"道题回答错误!"<<endl;
    cout<<"您的正确率是"<<((double)rig/intal)*100<<"%"<<endl;
    if(fal!=0)
        cout<<"错题结果如下:" <<endl;
    for(int i=0;i<fal;i++)
    {
        cout<<""<<p[i]+1<<"道题正确答案是:"<<arr[p[i]]<<endl;
    }
}
困难模式代码

 

         3.限时模式

   手动输入需要的题目数量,在规定时间内(题目数量*2秒)进行答题,时间到则无法继续作答。这几个数和计算结果都在0-100之间,除数不为0,分别统计出答题正确和错误的数量,计算出正确率,并且对于错题进行题号提示结果展示。如果在规定时间内完成了答题,则还显示总作答时间。

 

void xianshi()
{
    srand(time(NULL)); // 随机数种子
    int correct_count = 0; // 正确答题数量
    int total_count = 0; // 总答题数量
    cout<<"您需要挑战几道题目(300以内):"<<endl;
    int n;
    cin>>n;
    cout<<"您有"<<n<<"道题,总共有"<<2*n<<"秒来完成,请做好准备!"<<endl;
    time_t start_time = time(NULL); // 开始时间
    time_t end_time = start_time + n*2; // 结束时间,n*2秒后
    for(int i=0;i<n;i++)
    {
        arr[i]=chuti2();
    }
    cout<<endl;
    int shuru;
    int count=0;
    int j=0; 
    while (time(NULL) < end_time && total_count<n) 
    { // 在规定时间内循环
        cin>>shuru;
        count++;
        if(shuru==arr[j])
        {
            rig++;
        }
        else if(shuru!=arr[j])
        {
            p[fal]=j;
            fal++;
        }
        j++;
        total_count++;    
    }
    time_t elapsed_time = time(NULL) - start_time; // 统计花费时间
    if(elapsed_time >= n*2)
        cout<<"时间到!一共回答了"<<total_count<<"道题!"<<endl;
    else if(elapsed_time < n*2) 
        cout <<"总用时 " << elapsed_time / 60 << " 分钟 " << elapsed_time % 60 << " 秒。" << endl;    
    cout<<"其中答对了"<<rig<<"道题!有"<<fal<<"道题回答错误!"<<endl;
    cout<<"正确率为:"<<((double)rig/n)*100<<"%"<<endl;
    if(fal!=0)
        cout<<"错题结果如下:" <<endl;
    for(int i=0;i<fal;i++)
    {
        cout<<""<<p[i]+1<<"道题正确答案是:"<<arr[p[i]]<<endl; 
    }
}
限时模式代码

 

五、运行结果

1.简单模式

2.困难模式

3.限时模式

3.1规定时间内未完成所有题目

3.2规定时间内完成所有题目且显示所用时间

六、实验总结和体会

   在这次结对编程中,首先是头脑风暴,两个人进行沟通交流,对该程序的实现有一个大致的方向。编写程序的过程中,任何一段代码都被两双眼睛看过,两个脑袋思考过。这个过程是一个互相督促的过程,自己的一举一动都在对方的视线之内,所有的想法都会受到对方的评价。由于这种督促的压力,使得coding者更认真地工作。一个人敲代码,另一个人能及时发现错误,出现了问题也能一起谈论,效率更高了。

   结对编程不同于以往的独立编程模式,需要两个人合作,在合作的过程当中难免会出现一千个读者就有一千个哈姆雷特这样的情况,我们也遇到了这样的问题。例如就计时功能的实现方式的讨论中产生了明显的分歧,一位同学认为可以获取两次系统时间相减来实现,一位同学则认为这样的方式使得系统负载过大,可以采用倒计时的方式,最终我们基于自身编程能力水平以及时间因素综合考虑,在不断讨论碰撞的过程中决定仍采用前者的方案。

   在具体coding的过程当中同样也遇到了问题。不难发现,虽每个人代码所实现的功能不经相同,但其代码的风格很可能是大相径庭的,在审核过程当中互相之间都发现看对方所coding的代码有一种强迫症的感觉,并且在交换之后,也需要看对方的代码来完成自己的代码,看别人风格的代码很累;其次由于习惯2152215不喜欢写注释,导致另一位同学在阅读查找的过程当中遇到了一些困难。

   对于这样的问题我们在完成作业之后也进行了讨论和反思。在前期需要做好完善的讨论准备工作,从整体思路到具体功能实现,从具体功能是否要用函数实现到代码是否写注释或是一方顺应另一方代码风格等等。看似冗杂的前期准备却能够在后期项目实施过程当中给双方带来很多的便利。总之,通过这次结对编程,受益匪浅。