湖南大學結對程式設計——結對程式設計專案經驗總結
一、任務簡介
實現帶UI的小初高數學學習軟體
二、功能需求
- 所有功能通過圖形化介面操作,可以是桌面應用,可以是網站(程式語言和技術不限);
- 使用者註冊功能。使用者提供手機號碼,點選註冊將收到一個註冊碼,使用者可使用該註冊碼完成註冊;
- 使用者完成註冊後,介面提示設定密碼,使用者輸入兩次密碼匹配後設置密碼成功。密碼6-10位,必須含大小寫字母和數字。使用者在登入狀態下可修改密碼,輸入正確的原密碼,再輸入兩次相同的新密碼後修改密碼成功;
- 密碼設定成功後,跳轉到選擇介面,介面顯示小學、初中和高中三個選項,使用者點選其中之一後,提示使用者輸入需要生成的題目數量;
- 使用者輸入題目數量後,生成一張試卷(同一張卷子不能有相同題目,題目全部為選擇題),介面顯示第一題的題乾和四個選項,使用者選擇四個選項中的一個後提交,介面顯示第二題,...,直至最後一題;
- 最後一題提交後,介面顯示分數,分數根據答對的百分比計算;
- 使用者在分數介面可選擇退出或繼續做題;
- 小初高數學題目要求見個人專案。
三、功能實現
1.UI介面
因為個人專案我和搭檔都是用C++,為了更好地重用個人專案程式碼,所以採用QT編寫UI介面。介面分為6種:註冊介面,登入介面,挑選難度介面,更換密碼介面,答題介面,分數介面,如下圖。
基本框架:
每個介面寫一個類,封裝在XXXwindow.h中,需要使用時標頭檔案處include,然後呼叫類的建構函式生成物件即可實現對應的UI介面。
qt訊號與槽機制:
因為我和搭檔從來沒接觸過C++的圖形化程式設計,也從來沒有接觸過qt,是完全從小白慢慢摸索出來的。訊號和槽機制是Qt的核心特徵,是Qt不同於其他開發框架的最突出的特徵,訊號和槽用於兩個物件直接的通訊。如當按鈕被單擊,我們希望有響應,Qt在發生如單擊的事件時傳送訊號,用槽也就是函式在訊號發出後響應訊號以實現按鈕單擊事件的響應,注意需要用connect語句關聯訊號和槽函式,否則沒法如願響應。
如分數介面退出登入需要顯示登入介面重新登入,兩個介面的切換就需要使用訊號和槽機制:
分數介面定義退出訊號exitsignals(),登入介面定義槽函式login()響應分數介面的退出訊號。
登入介面宣告
|
分數介面宣告
|
分數介面在退出按鈕的槽函式中傳送exitsignals()。
void ScoreWindow::on_exitBtn_clicked()//退出按鈕 { QMessageBox::information(NULL,tr("資訊提示"),tr("退出成功")); this->hide(); //退出訊號 emit exitsignals(); }
登入介面的login函式呼叫show()顯示介面,關聯登入介面login槽函式和分數介面產生的退出訊號exitsignals即可實現分數介面按退出按鈕切換登入介面。
//關聯退出登入訊號和登入介面顯示 QObject::connect(&q.s,&ScoreWindow::exitsignals,&w,&MainWindow::login);
//顯示登入介面 void MainWindow::login() { this->show(); }
2.題目答案計算
之前的個人專案沒有要求計算答案,因為這次需要統計分數,所以需要實現答案計算。演算法思想史初中和高中的根號和三角先計算,然後採用中綴表示式的四則運算演算法:定義兩個棧分別儲存運算元和操作符,從左往右讀題目字串,如果是運算元直接入棧,如果是操作符先和棧頂操作符比較,棧頂操作符優先順序低直接入棧,棧頂優先順序高則彈出棧頂操作符和兩個棧頂運算元運算後再迴圈判斷操作符和當前棧頂優先順序直至運算元棧只有一個元素即結果。
舉例如下:
程式碼實現:
//表示式計算的過程 //中綴表示式使用棧計算 void tcal::process(){ symbol.push('#'); uint i=0; double num = 0.0; char *c; QByteArray ba = str.toLatin1(); c = ba.data();//得到字元 int ff = 0; while(symbol.top()!='#'||i<str.size()){ if(c[i]>='0'&&c[i]<='9'){ //為運算元 num=0; int f = 0; while((c[i]>='0')&&(c[i]<='9')||(c[i]=='.')){ if((i == 0)&&c[i]=='-') { ff = 1; } else if((c[i]=='.')||(f != 0)) { if(c[i]!='.') { num*=10; num+=c[i]-'0'; f++; ++i; } else { ++i; f++; } } else { num*=10; num+=c[i]-'0'; ++i; } } ff = 0; if(f!=0) num = num/pow(10,f-1); val.push(num); } else //操作符 { switch(cmp(symbol.top(),c[i])){ case '<': symbol.push(c[i]); ++i; break; case '=': symbol.pop(); ++i; break; case '>': double a=val.top(); val.pop(); double b=val.top(); val.pop(); val.push(cal_t(b,a,symbol.top())); symbol.pop(); break; } } } double res=val.top(); val.pop(); realresult = res; return; }
3.簡訊驗證
C++可依賴libcurl庫傳送http請求到第三方平臺,接入第三方平臺的簡訊介面以實現簡訊傳送。
注意windows上是沒有curl庫的,需要新增外部包進qt才能成功編譯呼叫curl.h的函式實現請求傳送。
LIBS += "E:\qt\qt01\lib\libcurldll.a" LIBS += "E:\qt\qt01\lib\libcurl.a" INCLUDEPATH +=$$PWD/include DEPENDPATH +=$$PWD/include
四、經驗教訓總結
經驗:
1.這次結對程式設計主要編寫程式碼由我編寫,搭檔主要負責程式碼測試和bug修改,搭檔看完我編寫程式碼後能夠很快指出我的不規範的編寫之處,像多打了分號,括號不匹配問題及時發現,避免很多不必要的bug的出現。
2.搭檔從另一個視角能很快發現我的bug來源,原本高中題目答題時有閃退bug,我看了很久沒有找到解決方法,搭檔重審我的程式碼後,提出了修改三角後的運算元的方案,改為更符合高中生水平的15的倍數且把單位改為度,解決了bug閃退,且找到了閃退原因是非特殊度數的三角函式值有小數不符合中綴表示式計算四則運算演算法,計算結果出錯程式非正常關閉從而發生閃退。
教訓:
1.因為國慶放假,我和搭檔分隔兩地,沒法並排坐在一起程式設計,只能我寫完一部分發給搭檔,沒法及時發現我的bug。如果我編寫程式碼時搭檔坐旁邊,我相信我會聽取搭檔意見三角運算元取特殊值且用度為單位,一方面符合現實情況,一方面三角函式值數值範圍合法,就能夠避免困擾我數天的高中答題閃退問題。
2.因為是Qt小白,對Qt缺乏瞭解,非常單純地用程式碼幹完整個介面的設計和佈局,後來才發現QtCreator有自帶的介面設計器可以通過拖拽控制元件設計介面,設計更便捷,且更方便控制空間佈局使介面更加美觀。但是純程式碼寫Qt介面也有一個很大的好處就是充分地瞭解Qt框架,對Qt介面設計更加熟練,自己手敲的程式碼更加熟悉,哪裡出了問題可以很快定位到出問題的地方。