结对编程项目总结(core2组)

Posted wokeqty

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结对编程项目总结(core2组)相关的知识,希望对你有一定的参考价值。

----by 吴雪晴 齐天杨

 

一、项目简介

 项目的任务为制作一个给(貌似是?)小学生用的四则运算出题软件,我们的组别为Core组,也就是负责随机生成四则运算表达式,并将其封装成dll模块,供UI组使用

二、GITHUB地址

 https://github.com/shirley-wu/hw2-Core 代码

https://github.com/shirley-wu/hw2-CoreDll Dll 

三、功能介绍

 

1. 能自动生成小学四则运算题目并给出答案,生成题目时可以选择下列参数:

 

  1)生成题目数量

 

  2)每道题目中操作数数量

 

  3)操作数数值范围

 

  4)操作符的种类

 

  5)表达式的类型(整数,小数,分数(其中假分数已转化为带分数的形式,如3‘1/3))

 

  6)操作数的精度(保留到小数点后几位)

 

2. 将四则运算的计算功能包装在一个模块中( DLL)

 

3. 将Core模块通过一定的API 接口( Application Programming Interface ) 来和其他组的模块( UI )交流

四、代码主要架构

我们的代码可以主要的分为如下几个模块:

1、生成:

Node * generate_tree(int limit, bool num_en) {
    Node * p;
    NODETYPE type;
    if (limit == 1) {
        if (num_en == false) throw("wtf");
        else type = NUM;
    }
    else if (num_en == false) type = OPR;
    else type = NODETYPE(rand() % TYPENUM);

    if (type == NUM) {
        p = Node::randNum();
    }
    else {
        int v = rand() % OPRNUM;
        OPRTYPE opr = randomopr();
        p = new Node(opr);

        int limit1, limit2;
        if (limit == 2) limit1 = limit2 = 1;
        else {
            limit1 = (rand() % (limit - 2)) + 1;
            limit2 = limit - limit1;
        }

        if (setting.type == INT && opr == DIV) {
            int denom = rand() % (setting.num_max - 1) + 1;
            int numer = (rand() % (setting.num_max / denom)) * denom;
            p->set_lchild(create_int_node(numer, limit1));
            p->set_rchild(create_int_node(denom, limit2));
            p->calc_val();
        }
        else {
            if (opr == POW) {
                int v = rand() % 5;
                p->set_lchild(generate_tree(limit1));
                p->set_rchild(create_int_node(v, limit2));

                while (true) {
                    try {
                        p->calc_val();
                    }
                    catch (Overflow& e) {
                        v--;
                        p->set_rchild(create_int_node(v, limit2));
                        continue;
                    }
                    catch (...) {
                        throw;
                    }
                    break;
                }
            }
            else {
                p->set_lchild(generate_tree(limit1));
                p->set_rchild(generate_tree(limit2));

                while (true) {
                    try {
                        p->calc_val();
                    }
                    catch (Overflow& e) {
                        p->set_lchild(generate_tree(limit1));
                        p->set_rchild(generate_tree(limit2));
                        continue;
                    }
                    catch (Zeroerror& e) {
                        p->set_lchild(generate_tree(limit1));
                        p->set_rchild(generate_tree(limit2));
                        continue;
                    }
                    catch (Negerror& e) {
                        p->exchange_lr();
                        continue;
                    }
                    catch (Exaerror& e) {
                        p->set_lchild(generate_tree(limit1));
                        p->set_rchild(generate_tree(limit2));
                        continue;
                    }
                    catch (...) {
                        throw;
                    }
                    break;
                }
            }
        }

    }

    return p;
}

以及节点的构造:

Node * create_int_node(int a, int limit) {
    if (a < 0) throw(Negerror());

    Node *p = NULL;
    NODETYPE type;
    OPRTYPE tool;

    if (limit == 1 || (setting.opr[(int)SUB] == false && setting.opr[(int)ADD] == false)) {
        type = NUM;
    }
    else if (a == 0) {
        if (setting.opr[(int)SUB] == false) type = NUM;
        else {
            type = NODETYPE(rand() % TYPENUM);
            if (type == OPR) tool = SUB;
        }
    }
    else {
        type = NODETYPE(rand() % TYPENUM);
        if (type == OPR) {
            if (setting.opr[(int)SUB] == false) tool = ADD;
            else if (setting.opr[(int)ADD] == false) tool = SUB;
            else tool = (rand() % 2) == 0 ? ADD : SUB;
        }
    }
    

    if (type == NUM) {
        p = new Node(a);
    }
    else {
        int limit1, limit2;
        if (limit == 2) limit1 = limit2 = 1;
        else {
            limit1 = (rand() % (limit - 2)) + 1;
            limit2 = limit - limit1;
        }

        int lchnum, rchnum;

        if (tool == ADD) {
            lchnum = rand() % a;
            rchnum = a - lchnum;
            p = new Node(ADD);
            p->set_lchild(create_int_node(lchnum, limit1));
            p->set_rchild(create_int_node(rchnum, limit2));
            p->calc_val();
        }
        else {
            rchnum = rand() % (setting.num_max - a);
            lchnum = a + rchnum;
            p = new Node(SUB);
            p->set_lchild(create_int_node(lchnum, limit1));
            p->set_rchild(create_int_node(rchnum, limit2));
            p->calc_val();
        }
    }
    return p;
}

2、对操作数的计算(包括整数,小数,分数3种类型)

friend void add(const Fraction& f1, const Fraction& f2, Fraction& f);
    friend void sub(const Fraction& f1, const Fraction& f2, Fraction& f);
    friend void mul(const Fraction& f1, const Fraction& f2, Fraction& f);
    friend void div(const Fraction& f1, const Fraction& f2, Fraction& f);
    friend void pow(const Fraction& f1, int p, Fraction& f);

    bool operator==(const Fraction& f) const;
    friend std::ostream& operator<<(std::ostream& os, const Fraction& f);

    int to_str(char * s, int start, int end) const;

3、对参数的设置

typedef struct Setting {

    int num_max = 1000;
    // maximum of num
    int num_limit = 20;
    // limit of nums
    int exp_num = 5;
    // number of expressions
    NumType type = DOUBLE;
    // type of number
    int precision = 2;
    // precision of double
    int pow_max = 5;
    // max power exp
    bool opr[OPRNUM] = { true, true, true, true, false };
    // available opr
    int opr_num = 4;
    // number of available opr
    bool power_signal = true;
    // way to show power: true -> ‘^‘, false -> ‘**‘

} Setting;

4、DLL文件的对接

CORE_DLL_API void set(int num_max, int num_limit, int exp_num, int type = 0, int precision = 2);
CORE_DLL_API void set_precision(int precision);
CORE_DLL_API void set_opr(bool add, bool sub, bool mul, bool div, bool pow);
CORE_DLL_API void set_power_signal(bool s);

CORE_DLL_API void generate();
CORE_DLL_API void clear();

CORE_DLL_API bool get_exp(int i, std::string& s, std::string& result);

CORE_DLL_API bool get_expression(int i, char *s, int size);
CORE_DLL_API bool get_answer(int i, char *s, int size);

CORE_DLL_API bool exp_to_file(const char* dir);
CORE_DLL_API bool ans_to_file(const char* dir);

五、样例输出(包括文件输出):

1、小数

技术分享图片

 

技术分享图片

2、整数

技术分享图片

技术分享图片

3、分数

技术分享图片

技术分享图片

、过程中产生的问题

首先,我们遇到的第一个问题是对于题意理解的有误,导致既写了CALC函数又写了GENERATE函数,浪费了时间。

其次,由于我(齐)对C++的一些功能有些不了解,导致代码撰写效率极其低下,不得不让队友多写了好多代码

另外,在对接过程中发现将表达式存储在string中容易出现bug,将其改为char型数组后BUG解决

七、结对编程的意义

1、互相鼓励,不容易沮丧:两个人一起工作能增加每个人的工作积极性。因为在面对问题的时候,会有人一起分担,共同尝试新的策略。(只要2个人有一个会的)

2、互相监督,不容易偷懒:两个人一起工作需要互相配合,如果想偷懒去干别的,就会拖延工作进度。

3、互相学习编程技巧:在编程中,相互讨论,可以更快更有效地解决问题,互相请教对方,可以得到能力上的互补。

4、多双眼睛,少点 bug:两人互相监督工作,可以增强代码和产品质量,并有效的减少 BUG。

 八、感想

感觉这门课对编程和自学的能力要求较高,比较适合编程基础比较弱的同学借此强化一下编程的能力(比如我)。另外,特别值得称赞的一点是这门课的任务布置模式,同真正的工作岗位上的任务模式比较相近,有助于以后在工作岗位上的驾轻就熟。这是在科大这种可能对外接触机会比较少的地方来说是一个非常宝贵的经历。

 



以上是关于结对编程项目总结(core2组)的主要内容,如果未能解决你的问题,请参考以下文章

总结如何复用个人项目实现结对编程项目,以及结对编程的经验教训。

20165318 结对编程项目-四则运算 整体总结

结对编程项目总结

结对-英文词频分析-结对项目总结

结对编程项目总结

课后作业-结对编程项目总结