#做業描述 | 問題 | 內容 | | :-----| :----| | 這個做業屬於哪一個課程 | 2020春丨W班| |這個做業要求在哪裏|寒假做業(2/2)| |這個做業的目標|完成疫情統計的程序以及博客| |做業正文|寒假做業(2/2)——疫情統計| |其餘參考文獻|...| #1.Github倉庫地址 本項目使用Java開發 做業倉庫地址:疫情統計html
學長因爲第一次使用GitHub不是很熟悉,剛開始的時候我編寫的時候新建了一個新的倉庫來編寫,任何commit,push操做都在那個倉庫完成,最後要pr的時候發現不能提交,才知道是本身理解錯了,因此 提交的那份做業裏面沒有commit記錄,若是容許的話我這裏貼一份舊的倉庫連接,須要看commit記錄的話能夠看這個倉庫的記錄,兩份的代碼是同樣的。 舊倉庫:有commit記錄的庫 #2.PSP表格 | PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘)| 實際耗時(分鐘) | :-----| :----| :-----| :----| :-----| :---- | | Planning | 計劃 | 30 | 40 | Estimate | 估計這個任務須要多少時間 | 720 | 900 | Development | 開發 | 600 | 720 | Analysis | 需求分析(包括學習新技術) | 60 | 120 | Design Spec | 生成設計文檔 | 30 | 30 | Design Review | 設計複審 | 30 | 60 | Coding Standard | 代碼規範 (爲目前的開發制定合適的規範) | 30 | 30 | Design | 具體設計 | 60 | 120 | Coding | 具體編碼 | 480 | 540 | Code Review | 代碼複審 | 60 | 50 | Test | 測試(自我測試,修改代碼,提交修改) | 120 | 180 | Reporting | 報告 | 120 | 150 | Test Report | 測試報告 | 60 | 120 | Size Measurement | 計算工做量 | 30 | 10 | Postmortem & Process Improvement Plan | 過後總結, 並提出過程改進計劃 | 30 | 30 | 合計 | | 2460 | 3100 #3.解題思路 ###1.命令行輸入命令的接收與保存 1.剛看到題目的時候,想的比較簡單,使用" "空格符號來分割傳入的命令便可,可是後面仔細一想,有的命令有多個參數僅僅依靠空格符並不能很好的實現,最後決定先依靠"-"符號分割,分割結束後依靠" "再次分割處理獲得傳入的命令。 2.爲了保存命令,聲明瞭一個命令類(class command)該類用於保存命令跟命令後帶的參數,同時也進行命令跟命令參數的格式檢查。 ###2.日誌文件的讀取 1.判斷日誌文件路徑是否正確。 2.聲明一個省份類對象數組(class province)用於保存各個省份的數據。 3.根據題目要求日誌文件內容的格式僅有8種。java
<省> 新增 感染患者 n人 <省> 新增 疑似患者 n人 <省1> 感染患者 流入 <省2> n人 <省1> 疑似患者 流入 <省2> n人 <省> 死亡 n人 <省> 治癒 n人 <省> 疑似患者 確診感染 n人 <省> 排除 疑似患者 n人git
便考慮到使用正則表達式去匹配每一行的數據,若命中跳轉分支去抓取省份名稱跟人數進行處理。 4.按照正則表達式抓取的數據修改province數組中的相應位置的數據。 ###3.結果的輸出 1.判斷結果輸出路徑是否正確 2.查看是否有特定輸出要求(-province,-type是否的指定) 3.輸出相應結果到指定的文件中 在畫這個圖片的時候,發現了判斷輸入/輸出路徑最好應該在判斷命令格式跟命令是一塊兒判斷,這樣若是有誤就能夠直接結束程序,不在浪費系統資源,如有修改將放在下面代碼優化部分。 ###4.設計實現過程 1.命令類(class command)程序員
//命令類 //list:判斷是否輸入-list //log:判斷是否輸入-log //out:判斷是否輸入-out //date:判斷是否輸入-date //type:判斷是否輸入-type //province:判斷是否輸入-province //dateContent:-date命令後帶參數 //logContent:-log命令後帶參數 //outContent:-out命令後帶參數 //provinceContent:-province後帶參數 //typeContent:-type後帶參數 //command:輸入的命令字符串數組 class Command{ private Boolean list=false; private Boolean log=false; private Boolean out=false; private Boolean date=false; private Boolean type=false; private Boolean province=false; private String dateContent; private String logContent; private String outContent; private List<String> provinceContent = new ArrayList<String>(); private List<String> typeContent = new ArrayList<String>(); private List<String> command = new ArrayList<String>(); ...... }
2.省份類github
//省份類 用於存儲各個全國和各個省份的各類數據 //代碼中開闢一個province數組,第0位存放全國,其他省份按排序一次存放 //name:省份的名稱 //ip:感染患者數量 //sp:疑似患者數量 //cure:治癒患者數量 //dead:死亡患者數量 //appear:用來判斷是否在日誌文件中出現該省份 class province { private String name; private int ip; private int sp; private int cure; private int dead; private boolean appear; .... }
3.文件操做-讀類正則表達式
//文件操做類-讀文件 //path:日誌文件的路徑,-log後帶的參數 //files:該路徑下的說有文件路徑(絕對路徑) //filesName:該路徑下全部文件的名稱,用於判斷輸入的日期是否超出範圍(僅名稱不帶後綴) //file:文件路徑打開的文件夾 //tempList:該路徑下的全部文件 //provinceList:省份數組 //templates:用於匹配日誌文件內容的正則表達式模板 //maxDate:該路徑下的日誌文件的最大日期 //minDate:該路徑下的日誌文件的最小日期 class readFile{ String path; ArrayList<String> files; ArrayList<String> filesName; File file; File[] tempList; province [] provinceList; String [] templates = { "(\\S+) 新增 感染患者 (\\d+)人","(\\S+) 新增 疑似患者 (\\d+)人","(\\S+) 感染患者 流入 (\\S+) (\\d+)人", "(\\S+) 疑似患者 流入 (\\S+) (\\d+)人","(\\S+) 死亡 (\\d+)人","(\\S+) 治癒 (\\d+)人", "(\\S+) 疑似患者 確診感染 (\\d+)人", "(\\S+) 排除 疑似患者 (\\d+)人" }; String maxDate; String minDate; ... }
4.文件操做-寫類編程
//文件操做類-寫文件 //provinceList:全國和各個省份的數據統計數組 //isProvince:命令行是否接收-province命令 若是有 isProvince=true反之false //provinceContent:-province命令後帶的參數 //isType:命令行是否接收-type命令 值同isProvince //typeContent:-type命令後帶的參數 //file:輸出結果文件 class writeFile { private province [] provinceList; private boolean isProvince; private List<String> provinceContent; private boolean isType; private List<String> typeContent; private File file; ... }
###5.代碼說明 看了下本身的代碼,好像發現沒什麼值得展現的,都是一些比較日常的代碼,也沒有難以理解,下面就解釋一下一些稍微難以理解的代碼(爲了偷懶寫的代碼) 代碼的具體解釋寫在來各個代碼塊的開頭的註釋和代碼旁邊的註釋中數組
//判單讀取日誌文件數量 //傳入參數:日期 如:2020-01-22 //返回值:false 或 true //path:-date命令後面帶的日期 //path有兩種取值:1.正常日期 ,輸入-date後帶的符合規範的日期。 // 2. 「all」 字符串,未輸入-date命令或者輸入-date命令後未指定具體日期時 // 爲了偷懶默認日期就爲all,僅當有輸入-date命名且輸入指定日期後才更新 public boolean readLog(String path) { if(path.equals("all")) //若是path是all直接讀取到maxDate日期爲止 { readLogFile(maxDate); return true; } else { if(path.compareTo(maxDate)>0||path.compareTo(minDate)<0)//判斷輸入的日期是否在日誌文件的 { //範圍中 return false; } else { readLogFile(path); return true; } } }
//輸入結果到文件方法 //沒有想到什麼好的解決辦法,就把每種狀況都列了出來 //isProvince=true這表明輸入了-province命令,反之沒有 //isType=true這表明輸入了-type命令,反之沒有 //按題目要求輸出有四種不一樣的狀況 //1.沒輸入-province命令,沒輸入-type //2.輸入-province命令,沒輸入-type //3.輸入-province命令,輸入-type //4.沒輸入-province命令,輸入-type //分別與下面的四個判斷對應 //因爲嵌套循環較多,若程序性能較差能夠考慮修改這方面的代碼(雖然我已經想過了) //由於嵌套循環跟判斷較多具體代碼就不貼了,詳細能夠看代碼,這理解解釋下這四個判斷的做用 if(isProvince==false&&isType==false){...} if(isProvince==true&&isType==false){...} if(isProvince==true&&isType==true){...} if(isProvince==false&&isType==true){...}
//判斷各命令參數是否合法 //輸入參數:無 //返回值:true或false //-list必不可少,-date無關緊要 日期格式(yyyy-mm-dd)缺一不可 //-log命名跟後帶參數均不可少 //-out命名跟後帶參數均不可少 //原本還應該-province後面的參數只能是「全國或各個省份名稱」,可是因爲偷懶就沒寫了。 //看做業要求好像測試的時候也不會出現這樣的狀況,就算出現了代碼也能正常運行不會異常終止罷了😂 public boolean isLegal() { if(!list) { System.out.println("-list命令缺失"); return false; } if(date) { String regex = "[0-9]{4}-[0-9]{2}-[0-9]{2}";//這段代碼的做用是爲了保證必須知足(yyyy-mm-dd)反例:如(2020-1-2)也是錯誤的 Pattern pattern = Pattern.compile(regex);//爲何寫它是由於好像java自帶的日期格式判斷會將上述反例判斷爲正確,顧添加了一段代碼 Matcher m = pattern.matcher(dateContent); boolean dateFlag = m.matches(); if (!dateFlag) { System.out.println("日期格式錯誤"); return false;//日期格式錯誤 例如:2020-1-3(正確爲2020-01-03) } DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); formatter.setLenient(false); try{ formatter.parse(dateContent); }catch(Exception e){ System.out.println("日期格式錯誤!"); return false;//日期格式錯誤 例如:2a20-01-03(出現非數字字符) } } if(log)//輸入了-log命令 { if(logContent==null)//logContent爲-log命令後面後帶的參數 { System.out.println("-log命名參數缺失!"); return false;//輸入-log命令 卻未輸入參數 } } else { System.out.println("缺失-log命令!"); return false;//缺乏-log命令 } if(out) { if(outContent==null) { System.out.println("-out命令參數缺失!"); return false;//輸入-out命令 卻未輸入參數 } } else { System.out.println("缺失-out命令!"); return false;//缺失-out命令 } if(type) { if(typeContent==null) { System.out.println("-typy命令參數缺失!"); return false;//輸入-type 命令 卻不輸入參數 } else { for(int i=0;i<typeContent.size();i++) { if(!typeContent.get(i).equals("sp")&&!typeContent.get(i).equals("ip") &&!typeContent.get(i).equals("cure")&&!typeContent.get(i).equals("dead")) { System.out.println("-type命令參數錯誤!"); return false;//type的參數不是(ip sp cure dead四種之一) } } } } if(province) { if(provinceContent==null) { return false;//輸入 -province命令卻不輸入參數 } } return true; }
###6.單元測試截圖和描述 測試日誌文件日期: 測試日誌文件內容:
測試結果以下: (1)輸入命名 list -log C:\log\ -out C:\result\ListOut1.txt -date 2020-01-22
(2)輸入命令 list -log C:\log\ -out C:\result\ListOut2.txt -date 2020-01-22 -province 福建 河北
(3)輸入命令 list -log C:\log\ -out C:\result\ListOut7.txt -date 2020-01-23 -type cure dead ip -province 全國 浙江 福建
(4)輸入命令 list -log C:\log\ -out C:\result\ListOut.txt (無-date命令,統計所有結果)
(5) 輸入命令 list -log C:\log\ -out C:\result\ListOut.txt -date 2020-03-22 (日期超出範圍)
(6) 輸入命令 list -log C:\log\ -out C:\result\ListOut.txt -date 2020-01-a2 (日期格式錯誤)
(7) 輸入命令 list -log C:\log\ -out C:\result\ListOut.txt -type aa (type命令參數錯誤)
(8) 輸入命令 list -log D:\log\ -out C:\result\ListOut.txt (日誌文件路徑錯誤,電腦不存在D盤)
(9) 輸入命令 list -log C:\log\ -out D:\result\ListOut.txt (輸出文件路徑錯誤,電腦不存在D盤)
(10) 輸入命令 list -out D:\result\ListOut.txt (缺失-log命令)
(11) 輸入命令 list -log -out D:\result\ListOut.txt (缺失-log命令後帶參數)
###7.單元測試覆蓋優化和性能測試 單元測試覆蓋率代碼: 測試命令:list -log C:\log -out C:\result\ListOut7.txt -date 2020-01-27 結果:
分析: 1.Command覆蓋率較低是因爲命令並未徹底輸入 未輸入-province等命令致使分支並未跑到,同時其中還包含命令正確性判斷模塊。 2.writeFile類覆蓋率低但接近預期值,這是因爲輸出模塊爲四個判斷分支,只選取其中一段分支運行故接近25% 性能測試結果:
分析: 1.輸出模塊中for循環嵌套較多,性能較差。 2.分支判斷過多致使一些分支執行的次數較少。 3.性能優化暫無辦法,寫的時候就已經考慮過了。 ###8.代碼規範 個人代碼規範 ###9.心路歷程與收穫 1.經過此次做業,瞭解到了Java的單元測試跟單元測試覆蓋率還有性能測試,這是我認爲經過此次做業最大的收穫,以前寫代碼都是寫完便可並無去考慮這些。 2.做業也讓我從新複習了一遍Java的各類語法跟使用,對java有了更深的瞭解。 3.此次做業也讓咱們規範了本身的編程風格,這是在以前的日子從未有過的致使本身寫出來的代碼有時候本身都看不懂,經過代碼規範讓本身的代碼更加的易懂。 4.同時發現本身過於心急,並無拿到手上並無很是好的進行需求分析,一到手就開始編寫,致使不少東西在編寫的過程當中改來改去,這一點很是很差之後要認認真真的進行需求分析。 5.學習了GitHub的使用,以前老以爲這些東西沒什麼好的,本身寫就是了,用了以後發現真香。 6.認清了本身的位置,對於成爲一名合格的程序員還有很長的路要走 ###10.技術路線圖相關的5個倉庫 | 名稱 | 連接 | 簡介 | | :-----| :----|:----| | RxJava | RxJava | JAVA的一種異步框架,使用可觀測的序列來組成異步的,基於事件的程序的庫 | | RxAndroid | RxAndroid | RxAndroid是專供Android平臺的RxJava | | Android佈局 | Android佈局 | 一些Android佈局教材跟例子 | | Android學習筆記 | Android學習筆記 | 由國內知名博主編寫的Android入門教材 | |《第一行代碼》中天氣案例 | 《第一行代碼》中天氣案例| 《第一行代碼》中的天氣預報的例子加改寫 |性能優化