軟件工程實踐寒假作業(2/2)


這個作業屬於哪個課程 班級鏈接
這個作業要求在哪里 作業鏈接
這個作業的目標 完成項目
作業正文 本頁
其他參考文獻

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個倉庫

    • 名稱: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 進行自動化部署和運維系統。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM