軟工實踐-團隊現場編程
隊名:起床一起肝活隊
組長博客:博客鏈接
作業博客:班級博客本次作業的鏈接
一、組員職責分工
組員 | 職責 |
---|---|
白晨曦 | 任務分配,過濾算法 |
樂忠豪 | 完成抽獎功能 |
蔡子陽 | 完成文案生成與qqbot |
黃培鑫 | 完成抽獎結果圖片生成 |
李麒 | 完成界面制作與功能對接 |
王煥仁 | 協助完成過濾算法 |
陳德斌 | 協助完成界面的制作,博客書寫 |
林誌華 | 過濾算法設計 |
何裕捷 | 抽獎結果的圖片顯示 |
二、github 的提交日誌截圖
三、程序運行截圖
1.程序界面
2.抽獎系統
輸入文本:
輸出結果:
3.高級過濾功能
4.發送通知
四、程序運行環境
環境 | 名稱 |
---|---|
操作系統 | windows10 |
編譯器 | visual studio |
五、GUI界面
六、基礎功能實現
抽獎系統
基本思路:
對每條記錄進行詞條化處理,賦予每個參與抽獎的人一定範圍的中獎碼(如:10-20是張三中獎),通過控制範圍改變一些參與者的中獎概率,再通過產生隨機數的方式獲得中獎號碼,輸出相應參與者的信息
代碼實現:
#include<iostream> #include<stdlib.h> #include<ctime> #include<fstream> #include <cstdlib> #include<string> #include <sstream> #include<vector> #include "DLL1.h" #include "stdafx.h" using namespace std; class people1 { public: string name; string QQ; int cs; int zongzishu; int zhongjiangdown; int zhongjiangup; }; people1 p[2000]; using namespace std; void choujiang(char *filename) { char word[1000]; string a; ifstream in(filename); int num = 0; int k = 0; while (in.getline(word, 1000)) { a = word; cout << a << endl; string b = ""; vector<string> res; //暫存從word中讀取的字符串 string result; //將字符串讀到input中 stringstream input(a); //依次輸出到result中,並存入res中 while (input >> result) res.push_back(result); //輸出res p[k].name = res[0]; p[k].QQ = res[1]; if (k <= 30 && k != 0) { p[k].zhongjiangdown = p[k - 1].zhongjiangup + 1; p[k].zhongjiangup = p[k].zhongjiangdown + 9; } else if (k == 0) { p[k].zhongjiangdown = 0; p[k].zhongjiangup = p[k].zhongjiangdown + 9; } else { p[k].zhongjiangdown = p[k - 1].zhongjiangup + 1; p[k].zhongjiangup = p[k].zhongjiangdown + 1; } k++; } int jieguo = 0; srand(time(0)); if (k <= 30) jieguo = rand() % (k * 10 - 1); else jieguo = rand() % (k + 269); cout << jieguo; ofstream fout("final.txt"); for (int i = 0; i < k; i++) { if (jieguo <= p[i].zhongjiangup && jieguo >= p[i].zhongjiangdown) fout << "恭喜 " << p[i].name << " (" << p[i].QQ << ") " << "中獎!" << endl; } fout.close(); }
過濾系統
代碼實現:
#include "pch.h" bool QWE_fenxi::cmp(qwe a,qwe b){ return a.zs>b.zs; } string QWE_fenxi::UTF8ToGB(const char* str) { string result; WCHAR *strSrc; LPSTR szRes; int i = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); strSrc = new WCHAR[i + 1]; MultiByteToWideChar(CP_UTF8, 0, str, -1, strSrc, i); i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL); szRes = new CHAR[i + 1]; WideCharToMultiByte(CP_ACP, 0, strSrc, -1, szRes, i, NULL, NULL); result = szRes; delete[]strSrc; delete[]szRes; return result; } bool QWE_fenxi::qgetline(char s[]){ if( fgets(s,1024,fp) ){ return true; } return false; } void QWE_fenxi::getfayan(int i){ string name="",qq=""; int zs=0,len=strlen(qLine[1]); for(int j=len-1;j>=0&&qLine[1][j]!=‘#‘;j--){ zs++; } for(i=i+1;qLine[0][i]!=‘(‘&&qLine[0][i]!=‘<‘;i++){ name+=qLine[0][i]; } for(i=i+1;qLine[0][i]!=‘)‘&&qLine[0][i]!=‘>‘;i++){ qq+=qLine[0][i]; } if (name == "系統消息")return; qq_name[qq]=name; qq_cs[qq]++; qq_zs[qq]+=zs; } bool QWE_fenxi::chanyucoujiang( char s[],string gjc){ int i=0,j,len=strlen(s); string tmp; while(i<len){ if(s[i]==‘#‘){ tmp=""; for( j=i+1;s[j]!=‘#‘;j++){ tmp+=s[j]; } if(tmp==gjc){ return true; }i=j+1; }else i++; } return false; } bool QWE_fenxi::between_time(char s[]) { int len = strlen(s); if (len < 19)return false; for (int i = 0; i < 19;i++) { if ( s[i]!=‘ ‘&& s[i] != ‘-‘&&s[i] != ‘:‘ && !(s[i] >= ‘0‘&&s[i] <= ‘9‘))return false; } for (int i = 0;i < 19;i++) { if (s[i] < time1[i])return false; else if (s[i] > time1[i])break; } for (int i = 0;i < 19;i++) { if (s[i] > time2[i])return false; else if (s[i] < time2[i])break; } return true; } bool QWE_fenxi::getperson(string gjc){ gjc=UTF8ToGB(gjc.c_str()); string str; if(!qgetline(qLine[0]) )return false; if (!between_time(qLine[0])) { return true; } if(!qgetline(qLine[1]) )return false; str=UTF8ToGB(qLine[1]); int j; for( j=0;j<str.size();j++){ qLine[1][j]=str[j]; } qLine[1][j]=‘\0‘; //de(qLine[1]); if(!qgetline(qLine[2]) )return false; if( !chanyucoujiang(qLine[1],gjc) ){ return true; } int i,t=0; for(i=0;;i++){ if(qLine[0][i]==‘ ‘){ t++; if(t==2)break; } } getfayan(i); return true; } void QWE_fenxi::getresult(string mgjc,string time11,string time22){ de("begin"); time1 = time11; time2 = time22; FILE *ffp; fopen_s(&fp,"record.txt","rt"); fopen_s(&ffp,"gjc.txt","rt"); string gjc; char ss[1024]; fgets(ss,1024,ffp); gjc=ss; gjc = mgjc; gjc=UTF8ToGB(gjc.c_str()); while(getperson(gjc) ){ } //de("-----------------------"); int cnt=0; int zs,cs; for( it1=qq_name.begin();it1!=qq_name.end();it1++){ a[cnt].name=it1->second; a[cnt].qq=it1->first; a[cnt].zs=qq_zs[ a[cnt].qq ]; a[cnt].cs=qq_cs[a[cnt].qq]; cnt++; } sort(a,a+cnt, & cmp ); freopen("result.txt","w",stdout); for(int j=0;j<cnt;j++){ cout<<a[j].name<<" "<<a[j].qq<<" "<<a[j].cs<<" "<<a[j].zs<<endl; } }
七、附加功能實現
附加功能方面只制作了抽獎結果的海報,還沒有連接上前面的代碼。所以只貼出海報截圖。
八、遇到的困難及解決方法
1.樂忠豪
遇到困難:
封裝Dll
解決辦法:
瘋狂百度!
2.林誌華
遇到困難:
1.遇到最煩的就是當時讀取record文件當中的漢字會產生亂碼,以前沒有遇到過這種情況,還以為是因為讀取的方式錯了,弄了一個上午。
2.作業提供的record文件裏面關於聊天記錄的爬取很令人不滿,人發的內容爬取的時候並沒有壓縮成一行,很亂。
解決方法:
1.當時百度了好久,用了很多方法都沒用,最後靈機一動,發現可能是txt編碼錯了,果然,把utf-8改成ANSI就不會出現亂碼了。
2.自己的事情自己做。
吐槽:要不是作業提供的文件編碼格式不對,內容格式不整齊,那就不用花費怎麽多時間浪費在這裏了,還能多做一些其他東西,晦氣。
3.李麒
遇到困難:
1.界面要調用其他組員的DLL,需要等待其他組員封裝,並且每次出問題都需要重新來過。
2.使用C#制作界面並調用C++的DLL,沒有經驗
3.成功接入,但在內存上報錯,無法確定是DLL的問題還是C#的問題
解決方法:
1.及時的溝通、調試
2.不斷的摸索,看其他優秀博客的教程等
3.嘗試過各種方法,均失敗,造成界面的制作失敗。
4.黃培鑫
遇到困難:
C++實現獲獎名單生成海報存在困難,沒有取得成功。
解決方法:
轉而使用C#
吐槽:如果可以重來,那麽我不會選軟工實踐(哭)
5.蔡子陽
遇到的困難:如何自動生成一個優美的文案
解決方法:暫時沒有解決方法(可以等京東的莎士比亞系統正式出後再試試)
6.王煥仁
遇到的困難:漢字在c++編程中的處理,編碼之前沒有清晰思路。
解決方法:多虧了有人幫忙和百度搜索引擎的幫忙。
7.陳德斌
遇到的困難:一開始大家為了統一語言選擇軟件討論了很久。
解決方法:大家統一選擇c++實現。
8.何裕捷
遇到的困難:
1.沒接觸過生成圖片的知識,需要百度很多知識,百度到的知識很多又是用不上的。
2.網上代碼copy下來會有很多bug。
解決方法:百度解決。
九、評估每位組員的貢獻比例
組員 | 得分 |
---|---|
白晨曦 | 5 |
樂忠豪 | 15 |
蔡子陽 | 10 |
黃培鑫 | 10 |
李麒 | 10 |
王煥仁 | 10 |
陳德斌 | 10 |
林誌華 | 20 |
何裕捷 | 10 |
PSP表格
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 180 | 190 |
· Estimate | · 估計這個任務需要多少時間 | 5 | 5 |
Development | 開發 | 90 | 120 |
· Analysis | · 需求分析 (包括學習新技術) | 60 | 60 |
· Design Spec | · 生成設計文檔 | 30 | 60 |
· Design Review | · 設計復審 (和同事審核設計文檔) | 0 | 0 |
· Coding Standard | · 代碼規範 (為目前的開發制定合適的規範) | 0 | 0 |
· Design | · 具體設計 | 60 | 70 |
· Coding | · 具體編碼 | 60 | 80 |
· Code Review | · 代碼復審 | 10 | 10 |
· Test | · 測試(自我測試,修改代碼,提交修改) | 10 | 10 |
Reporting | 報告 | 30 | 30 |
· Test Report | · 測試報告 | 0 | 0 |
· Size Measurement | · 計算工作量 | 20 | 20 |
· Postmortem & Process Improvement Plan | · 事後總結, 並提出過程改進計劃 | 30 | 30 |
合計 | 300 | 330 |
學習進度條
第N周 | 新增代碼(行) | 累計代碼(行) | 本周學習耗時 | 重要成長 |
---|---|---|---|---|
第0周 | 500 | 500 | 25 | 學會性能分析,單元測試,查看代碼覆蓋率 |
第1周 | 0 | 500 | 8 | 學習Axure Rp 的使用 |
第2周 | 300 | 800 | 5 | JAVA爬蟲及語法學習 |
第3周 | 300 | 1200 | 15 | JAVA爬蟲及語法學習 |
第4周 | 0 | 1200 | 8 | 了解需求規格說明書的格式及UML的設計 |
第5周 | 0 | 1200 | 8 | 學習思維導圖制作 |
第6周 | 100 | 1300 | 8 | 學習前端知識及嘗試編寫 |
軟工實踐-團隊現場編程