這個作業屬於哪個課程 | 班級鏈接 |
---|---|
這個作業要求在哪里 | 作業鏈接 |
這個作業的目標 | 完成項目 |
作業正文 | 本頁 |
其他參考文獻 |
Github
本項目使用Python3.7
https://github.com/Mauue/InfectStatistic-main
PSP表格
PSP2.1 | Personal Software Process Stages | 預估耗時(分鍾) | 實際耗時(分鍾) |
---|---|---|---|
Planning | 計划 | 10 | 5 |
- Estimate | 估計這個任務需要多少時間 | 10 | 5 |
Development | 開發 | 310 | 397 |
- Analysis | 需求分析 (包括學習新技術) | 30 | 60 |
- Design Spec | 生成設計文檔 | 10 | 1 |
- Design Review | 設計復審 | 5 | 1 |
- Coding Standard | 代碼規范 (為目前的開發制定合適的規范) | 5 | 5 |
- Design | 具體設計 | 10 | 10 |
- Coding | 具體編碼 | 120 | 120 |
- Code Review | 代碼復審 | 10 | 20 |
- Test | 測試(自我測試,修改代碼,提交修改) | 120 | 180 |
Reporting | 報告 | 45 | 50 |
- Test Report | 測試報告 | 30 | 30 |
- Size Measurement | 計算工作量 | 5 | 10 |
- Postmortem & Process Improvement Plan | 事后總結, 並提出過程改進計划 | 10 | 10 |
合計 | 365 | 452 |
解題思路
由於需求文檔足夠清晰,看完之后我就把項目大致規划為三個部分
1.解析命令行參數
該項因為之前沒寫過,所以單獨列出來。剛開始查閱資料后,找到了個看似可以的模塊 getopt模塊。但是仔細閱讀需求文檔發現,需求是解析list子命令,getopt好像不能解析子命令,查閱了官方文檔也沒看見。不過官方文檔里給出了另一條路:
The getopt module is a parser for command line options whose API is designed to be familiar to users of the C getopt() function. Users who are unfamiliar with the C getopt() function or who would like to write less code and get better help and error messages should consider using the argparse module instead.
於是就采用了argparse模塊
之后對着文檔操作了一波,能順利執行下去,此部分暫告一段落。
2.解析日志文件
對txt日志文件進行解析
該日志中出現以下幾種情況:
1、<省> 新增 感染患者 n人
2、<省> 新增 疑似患者 n人
3、<省1> 感染患者 流入 <省2> n人
4、<省1> 疑似患者 流入 <省2> n人
5、<省> 死亡 n人
6、<省> 治愈 n人
7、<省> 疑似患者 確診感染 n人
8、<省> 排除 疑似患者 n人
看的這段話后第一反應就是用正則,想了想應該是可行的,此部分就先這樣。
3.計算並輸出具體數據
將上一部分的解析結果存儲起來,按照要求輸出出去,因為兩個部分都不難,所以放在一起寫。
設計實現過程
按照上一部分的內容,設計出以下邏輯圖
代碼說明
程序的關鍵是對日志進行處理。
首先設計數據結構
def _new_province(self, province):
self.data.update({province: {"ip": 0, "sp": 0, "cure": 0, "dead": 0}})
數據按照省份的四項數據進行存儲
之后是數據處理函數
def _add_people(self, province, num, _type, _sub=False):
num = -int(num) if _sub else int(num)
if province not in self.data:
self._new_province(province)
self.data[province][_type] += num
操作的最小步驟為某一省份的某一數據增加或減少一定數量,所以設計了以上函數來處理。
解析日志的函數如下
def _parse_line(self, line):
if line.startswith('//'):
return
_patterns = [
('(.*?) 新增 感染患者 ([0-9]+)人', (((1, 2), 'ip', False),)),
('(.*?) 新增 疑似患者 ([0-9]+)人', (((1, 2), 'sp', False),)),
('(.*?) 感染患者 流入 (.*?) ([0-9]+)人', (((1, 3), 'ip', True), ((2, 3), 'ip', False))),
('(.*?) 疑似患者 流入 (.*?) ([0-9]+)人', (((1, 3), 'sp', True), ((2, 3), 'sp', False))),
('(.*?) 死亡 ([0-9]+)人', (((1, 2), 'dead', False), ((1, 2), 'ip', True))),
('(.*?) 治愈 ([0-9]+)人', (((1, 2), 'cure', False), ((1, 2), 'ip', True))),
('(.*?) 疑似患者 確診感染 ([0-9]+)人', (((1, 2), 'sp', True), ((1, 2), 'ip', False))),
('(.*?) 排除 疑似患者 ([0-9]+)人', (((1, 2), 'sp', True),)),
]
for _pattern, _args_list in _patterns:
result = re.match(_pattern, line)
if result:
for _args in _args_list:
index, _type, _sub = _args
province, num = result.group(*index)
self._add_people(province, num, _type, _sub)
return
通過匹配正則表達式來解析日志的數據,若之后出現其他的日志格式也可以直接在這添加語句。
拼音排序部分參考了這篇文章
其他部分個人認為較為簡單,不再說明。
單元測試
我設計了16種測試用例,覆蓋了不同的參數出現可能和可能發生的錯誤。
測試結果如下:
覆蓋率和性能測試
-
覆蓋率
除主程序入口和解析參數外 其余代碼全部覆蓋。
-
性能測試
-
時間
耗時最多的的函數是<built-in method _locale.setlocale>
耗時最多的是locale模塊的設置語言環境,用於拼音排序,只調用了一次。<built-in method io.open>
打開文件<built-in method nt.stat>
這個查閱資料后發現此函數是用於獲取文件信息的,調取log文件時要根據文件名篩選正確格式的日志文件,所以這個函數的調用次數取決於log目錄下的文件數 量。
-
調用次數
主程序運行部分集中在圖的上半部分左側,運行較多的主要是正則模塊相關部分。
-
代碼規范
心路歷程與收獲
有一說一,這次的作業不難,甚至還沒開始設計,我都想好了代碼會長什么樣,該怎么寫。
開發速度還是很快的,完成全部功能大概就兩個小時,剩下的都是對需求細節的調整。
收獲主要是單元測試和性能分析。
單元測試我以前也寫過一點,但是寫的不多,因為覺得太麻煩了。但是這次作業我認真的寫了十幾種測試用例后,尤其是對於接下來的性能分析,測試結果對我的代碼幫助真的很大,以后可能會寫的多一些。
性能分析這一塊,因為pycharm的單元測試機制和其他各種原因,這塊的報告我寫了四次,每次寫到一半發現有些函數根本不知道是在哪調用的,然后發現都是各種原因引入了與主程序無關的函數,導致的錯誤。摸索挺久算是找到個合理的解決方案,也是不容易。
5個倉庫
-
- 名稱:wemall
- github地址: https://github.com/Mauue/gxgk-wechat-server
- 簡介: 微信小程序,基於react, node.js, go開發的微商城。
-
- 名稱:Tinode Instant Messaging Server
- github地址: https://github.com/Mauue/chat
- 簡介:即時消息服務器后端,由go開發,一個大型的開源項目,支持gRPC等技術,一個值得去學習的項目。
-
- 名稱:kratos
- github地址: https://github.com/Mauue/kratos
- 簡介:bilibili開源的一套Go微服務框架,包含大量微服務相關框架及工具。
-
- 名稱:Archery
- github地址: https://github.com/Mauue/Archery
- 簡介:Python項目,定位於SQL審核查詢平台,旨在提升DBA的工作效率,支持主流數據庫的SQL上線和查詢,同時支持豐富的MySQL運維功能,所有功能都兼容手機端操作
-
- 名稱:git-webhook
- github地址: https://github.com/Mauue/git-webhook
- 簡介:一個使用 Python Flask + SQLAchemy + Celery + Redis + React 開發的用於迅速搭建並使用 WebHook 進行自動化部署和運維系統。