結對編程項目總結(core2組)
----by 吳雪晴 齊天楊
一、項目簡介
項目的任務為制作一個給(貌似是?)小學生用的四則運算出題軟件,我們的組別為Core組,也就是負責隨機生成四則運算表達式,並將其封裝成dll模塊,供UI組使用
二、GITHUB地址
https://github.com/shirley-wu/hw2-Core 代碼
https://github.com/shirley-wu/hw2-CoreDll Dll
三、功能介紹
1.
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組)