第三次作业-结对编程
Github項目地址:https://github.com/WHYNOTEN/WordCount.git
合作同學(xué)作業(yè)地址:https://www.cnblogs.com/Mchandu/p/10657935.html
?一.PSP表格
| PSP2.1 | Personal Software Process Stages | 預(yù)估耗時(分鐘) | 實際耗時(分鐘) |
| Planning | 計劃 | 890 | ?1435 |
| · Estimate | · 估計這個任務(wù)需要多少時間 | 890 | ?1435 |
| Development | 開發(fā) | 770? | ?1270 |
| · Analysis | · 需求分析 (包括學(xué)習(xí)新技術(shù)) | 40? | ?50 |
| · Design Spec | · 生成設(shè)計文檔 | 30? | ?35 |
| · Design Review | · 設(shè)計復(fù)審 (和同事審核設(shè)計文檔) | 50? | ?60 |
| · Coding Standard | · 代碼規(guī)范 (為目前的開發(fā)制定合適的規(guī)范) | 20? | ?15 |
| · Design | · 具體設(shè)計 | 30? | ?50 |
| · Coding | · 具體編碼 | 420? | ?900 |
| · Code Review | · 代碼復(fù)審 | 60? | ?40 |
| · Test | · 測試(自我測試,修改代碼,提交修改) | 120? | ?120 |
| Reporting | 報告 | 120? | ?165 |
| · Test Report | · 測試報告 | ?60 | ?80 |
| · Size Measurement | · 計算工作量 | 30? | ?60 |
| · Postmortem & Process Improvement Plan | · 事后總結(jié), 并提出過程改進(jìn)計劃 | 30? | ?25 |
| ? | 合計 | 900? | ?1435 |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
二.計算接口模塊的設(shè)計與實現(xiàn)過程
?1.需求分析(由兩人共同商議)
基礎(chǔ)功能:
1.統(tǒng)計文件字符數(shù)(包括字母/數(shù)字/特殊符號/空白符)
2.統(tǒng)計單詞總數(shù)(單詞必須四個英文字母開頭,后面可以為數(shù)字,不區(qū)分大小寫)
3.統(tǒng)計文件中有效行數(shù)
4.統(tǒng)計文件中單詞單詞總數(shù),按頻率排序,對于相同頻率單詞按字典順序排列
5.按照字典順序輸出到文件中
6.調(diào)用程序時,通過命令行傳入文件讀取和寫入路徑
新功能:
1.輸出前n個頻率最高的單詞
? 2.指定一個詞組長度,輸出詞組及其出現(xiàn)頻率
? 3.多參數(shù)混合使用
實現(xiàn)所有需求思路:
最終確定主要寫兩個.cs文件,其中一個對功能實現(xiàn),另外一個進(jìn)行功能類調(diào)用,這樣測試時即只需要對功能類函數(shù)進(jìn)行測試即可,基本功能由筆者實現(xiàn),對于新功能有合作者實現(xiàn),最終整合在功能中:
Function.cs:主要實現(xiàn)對文本內(nèi)容的提取篩選實現(xiàn)需求功能;
Program.cs:對命令行參數(shù)進(jìn)行分析(GetMand()),調(diào)用Function.cs對文本內(nèi)容分析,實現(xiàn)功能(Main()).
?算法關(guān)鍵在于正則表達(dá)式的書寫以及將內(nèi)容寫入字典整合:
?
文件讀取代碼:
//讀取文件中的字符數(shù)目并保存文件內(nèi)容public void GetChar(){//打開文件FileInfo file = new FileInfo(this.path);//定義讀取文件對象StreamReader sw = file.OpenText();//按行進(jìn)行讀取,不為空行記錄行數(shù)并保存內(nèi)容,返回null打斷循環(huán)while (true){//對文件讀取內(nèi)容進(jìn)行判斷,如果不為空用變量接收,行數(shù)加一string temp = sw.ReadLine();if (temp != null){account++;this.content += temp;}//為空則停止else{break;}}} View Code正則匹配函數(shù):
public void ExtractChar(){//利用正則進(jìn)行匹配,以字母開頭,可以數(shù)字結(jié)尾MatchCollection rel = Regex.Matches(this.content, @"([a-zA-Z]{4}\w*)");for (int i = 0; i < rel.Count; i++){//匹配到的單詞進(jìn)入列表this.result.Add(Convert.ToString(rel[i]));}} View Code字典寫入代碼:
//利用字典統(tǒng)計單詞出現(xiàn)次數(shù)public void Statistical(){//建立臨時字典保存單詞以及出現(xiàn)次數(shù)Dictionary<string, int> words = new Dictionary<string, int>();for (int i = 0; i < this.result.Count; i++){if (words.ContainsKey(this.result[i])){words[this.result[i]]++;}else{words[this.result[i]] = 1;}}//對字典內(nèi)容排序,并賦值給類變量this.words_sort = words.OrderByDescending(p => p.Value).ToDictionary(p => p.Key, o => o.Value);//清空臨時字典內(nèi)容 words.Clear();} View Code?
三.代碼復(fù)審
代碼規(guī)范:詳情請查看鏈接
各自完成代碼交換代碼,對代碼內(nèi)容進(jìn)行查看,基本均按照代碼規(guī)范進(jìn)行編碼,對于不懂部分進(jìn)行了增添注釋,使代碼得到可讀性提高。同時對命名部分進(jìn)行了詳細(xì)檢查,修改了部分變量名。
?
四.性能改進(jìn)
從性能分析圖看出Program.Main()與Function.ToFile()分配最多,但由于這兩個函數(shù)都是調(diào)用了其余函數(shù),所以減去其余調(diào)用函數(shù)分配,得出Function.ToFile()分配最多,為786,其次是Function.ExtractChar()
//將內(nèi)容寫入文件中public void ToFile(string path){//運行先行函數(shù),將需要的文件內(nèi)容保存至變量中this.GetChar();this.ExtractChar();this.ToLow();this.Statistical();//獲取當(dāng)前文件路徑string filepath = Directory.GetCurrentDirectory();//定義文件輸出路徑filepath += path;FileInfo file = new FileInfo(@filepath);StreamWriter sw = file.AppendText();sw.WriteLine("characters: {0}", this.CharNum());sw.WriteLine("words: {0}", this.WordsNum());sw.WriteLine("lines: {0}", this.account);//遍歷字典將內(nèi)容寫入文件foreach(KeyValuePair<string,int> kvp in this.words_sort){sw.WriteLine("{0,-10}:{1,-3}", kvp.Key, kvp.Value);}//關(guān)閉文件 sw.Close();Console.WriteLine("結(jié)果文件保存于:{0}", filepath);} View Code分析代碼發(fā)現(xiàn)在ToFile()函數(shù)中進(jìn)行了當(dāng)前文件路徑讀取,讀取文件,并多次寫入文件(特別是遍歷字典同時進(jìn)行寫入文件),由此可見循環(huán)寫入文件是導(dǎo)致性能變差的原因。改進(jìn)方法是將需要寫入的內(nèi)容保存至一個臨時字符串中,遍歷字典后再對整個字符串進(jìn)行寫入文件操作。ExtractChar()函數(shù)使用了正則進(jìn)行匹配,由于對Regex類具體實現(xiàn)不清楚,暫時無法進(jìn)行性能優(yōu)化。
?
?五.單元測試
? 由于項目中函數(shù)依賴關(guān)系,故只需要對部分函數(shù)進(jìn)行單元測試即可,即對CharNum()和WordsNum()兩個函數(shù)查看返回結(jié)果是否正確即可,若返回字符數(shù)與單詞數(shù)均正確,則單元測試通過。但是有一個缺陷那就是對于命令行輸入內(nèi)容的測試,沒有找到方法對于.exe運行時接收的外部參數(shù)進(jìn)行測試判斷.同時部分函數(shù)是將內(nèi)容寫入文件中,沒有找到合適的途徑進(jìn)行測試。另外由于VS2017社區(qū)版本無自動輸出代碼覆蓋率功能,無法判斷代碼覆蓋率是否符合要求。下面是部分測試代碼:
?
?
六.異常處理
異常處理主要針對命令行傳入?yún)?shù)的判定:
1.文件傳入路徑
//對得到內(nèi)容進(jìn)行處理 - i參數(shù)確定文件是否存在try{StreamReader sw = new StreamReader(command["-i"]);}catch{Console.WriteLine("需處理的文件不存在!請檢查路徑重新運行!");}2.-m 與-n 參數(shù)內(nèi)容是否為整數(shù)
//對-m -n 參數(shù)內(nèi)容進(jìn)行強(qiáng)制轉(zhuǎn)換看是否為整數(shù) if (command.ContainsKey("-n") && command.ContainsKey("-m")){try{int nums = Convert.ToInt32(command["-n"]);int length = Convert.ToInt32(command["-m"]);}catch{Console.WriteLine("參數(shù)輸入有誤,請重新運行!");}}else if (command.ContainsKey("-m") && !command.ContainsKey("-n")){try{int length = Convert.ToInt32(command["-m"]);}catch{Console.WriteLine("參數(shù)輸入有誤,請重新運行!");}}else if (!command.ContainsKey("-m") && command.ContainsKey("-n")){try{int length = Convert.ToInt32(command["-n"]);}catch{Console.WriteLine("參數(shù)輸入有誤,請重新運行!");}}else { }?
七.結(jié)對過程
在結(jié)對之后,選定了兩方都有空的時間進(jìn)行討論,根據(jù)PSP表格預(yù)估時間,討論出項目需求,代碼設(shè)計,根據(jù)各自水平進(jìn)行分工,完成代碼先進(jìn)性自省,然后交換代碼進(jìn)行復(fù)審,最后匯總生成.exe文件進(jìn)行實例測試,單元測試并不斷提交進(jìn)度,最后撰寫博客。
?
八.總結(jié)
這是第一次與人進(jìn)行真正意義上的結(jié)對編程,最大的感覺就是比單獨一個人編程輕松許多,同時更容易發(fā)現(xiàn)問題所在,在代碼注釋方面也明顯比單獨編程時多了許多,代碼可讀性更高,變量命名更加規(guī)范。同時也有一些小問題,兩個人的想法會有不同,對于同一個問題的理解有一些差別,而這個意見統(tǒng)一過程花費的時間顯然更多。但總的來說,這次的結(jié)對編程收獲頗豐。
轉(zhuǎn)載于:https://www.cnblogs.com/SW-P-WY/p/10657136.html
總結(jié)
以上是生活随笔為你收集整理的第三次作业-结对编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一次php curl卡住的bug分析
- 下一篇: 洛谷 5205 【模板】多项式开根