【Python CI】圈複雜度 lizard

1. 圈複雜度

1.1 什麼是圈複雜度?

引用[1]
圈複雜度是 Thomas J. McCabe 在 1976年開創的軟件指標,用來判斷程序的複雜度。這個指標度量源代碼中線性獨立的路徑或分支的數量。根據 McCabe 所說,一個方法的複雜度最好保持在10 以下。這是因爲對人類記憶力的研究表明,人的短期記憶只能存儲 7 件事(偏差爲正負 2)。

如果開發人員編寫的代碼有 50 個線性獨立的路徑,那麼爲了在頭腦中描繪出方法中發生的情況,需要的記憶力大約超過短期記憶容量的 5倍。簡單的方法不會超過人的短期記憶力的極限,因此更容易應付,事實證明它們的錯誤更少。Enerjy 在 2008年所做的研究表明,在圈複雜度與錯誤數量之間有很強的相關性。複雜度爲 11 的類的出錯概率爲 0.28,而複雜度爲 74的類的出錯概率會上升到 0.98。

1.2 計算原理

TODO

2. lizard

Git源碼鏈接 https://github.com/terryyin/lizard

  • 默認遞歸分析文件夾
  • 支持15中開發語言: C/C++ (works with C++14); Java; C# (C Sharp); JavaScript (With ES6 and JSX); Objective-C; Swift; Python; Ruby; TTCN-3; PHP; Scala; GDScript;Golang; Lua; Rust

2.1 依賴安裝

方式一 pip安裝

pip install lizard

方式二 源碼安裝

python setup.py install --install-dir=/path/to/installation/directory/

方式三 直接運行
直接將lizard.py及依賴的目錄移動到待檢測的文件目錄中, 直接在命令行中運行以下命令,控制檯數據結果表格

python lizard.py 

2.2 使用

命令行使用

lizard [options] [PATH or FILE] [PATH] ...
# 示例 檢測某目錄下 除 tests目錄下 Python文件
lizard mySource/ -x"./tests/*" -l python

-h, --help            顯示幫助並退出
--version             顯示當前lizard版本並退出
-l LANGUAGES, --languages LANGUAGES
                      開發語言列表, 檢測支持的開發語言 例如:lizard -l cpp -l java
                      支持語言:cpp, csharp, java, javascript, objectivec, php, python, ruby, swift, ttcn
-V, --verbose         Output in verbose mode (long function name)
-C CCN, --CCN CCN     Threshold for cyclomatic complexity number warning.
                      The default value is 15. Functions with CCN bigger
                      than it will generate warning
-L LENGTH, --length LENGTH
                      Threshold for maximum function length warning. The
                      default value is 1000. Functions length bigger than it
                      will generate warning
-a ARGUMENTS, --arguments ARGUMENTS
                      Limit for number of parameters
-w, --warnings_only   Show warnings only, using clang/gcc's warning format
                      for printing warnings.
                      http://clang.llvm.org/docs/UsersManual.html#cmdoption-
                      fdiagnostics-format
-i NUMBER, --ignore_warnings NUMBER
                      If the number of warnings is equal or less than the
                      number, the tool will exit normally, otherwise it will
                      generate error. Useful in makefile for legacy code.
-x EXCLUDE, --exclude EXCLUDE    不檢測文件
                      Exclude files that match this pattern. * matches
                      everything, ? matches any single character,
                      "./folder/*" exclude everything in the folder
                      recursively. Multiple patterns can be specified. Don't
                      forget to add "" around the pattern.
--csv                 Generate CSV output as a transform of the default
                      output
-X, --xml             Generate XML in cppncss style instead of the tabular
                      output. Useful to generate report in Jenkins server
-t WORKING_THREADS, --working_threads WORKING_THREADS
                      number of working threads. The default value is 1.
                      Using a bigger number can fully utilize the CPU and
                      often faster.
-m, --modified        Calculate modified cyclomatic complexity number,
                      which count a switch/case with multiple cases as
                      one CCN.
-E EXTENSIONS, --extension EXTENSIONS
                      User the extensions. The available extensions are:
                      -Ecpre: it will ignore code in the #else branch.
                      -Ewordcount: count word frequencies and generate tag
                      cloud. -Eoutside: include the global code as one
                      function.
-s SORTING, --sort SORTING
                      Sort the warning with field. The field can be nloc,
                      cyclomatic_complexity, token_count, parameter_count,
                      etc. Or an customized file.
-W WHITELIST, --whitelist WHITELIST  白名單
                      The path and file name to the whitelist file. It's
                      './whitelizard.txt' by default.

結果解讀

NLOC    the nloc (lines of code without comments),
CCN     cyclomatic complexity number
token   token count of functions.
param   parameter count of functions.

結果樣例

================================================== ============
  NLOC CCN令牌參數function @ line @ file
-------------------------------------------------- ------------
    10 2 29 2 start_new_player @ 26 @。/ html_game.c
   ...
     6 1 3 0 set_shutdown_flag @ 449 @。/ httpd.c
    24 3 61 1 server_main @ 454 @。/ httpd.c
-------------------------------------------------- ------------
2文件分析。
================================================== ============
LOC Avg.NLOC AvgCCN Avg.ttoken function_cnt文件
-------------------------------------------------- ------------
    191 15 3 51 12 ./html_game.c
    363 24 4 86 15 ./httpd.c

=====================================
!!!! 警告(CCN> 15)!!!!
=====================================
    66 19 247 1 accept_request @ 64 @。/ httpd.c
================================================== ==============================
NLOC平均總NLOC平均CCN平均代幣Fun Cnt警告cnt Fun Rt NLOC Rt
-------------------------------------------------- ------------------------------
       554 20 4.07 71.15 27 1 0.04 0.12

更多用法:

  • 白名單設置
  • CNN閾值設置
  • 重複代碼檢測

2.* Jenkins中配置

TODO

3. PyCmetrics

TODO

4.pygenie

TODO

5. 圈複雜度優化建議

  • 儘量少用 if …else … ,等分支語句
  • 每個函數要有明確的功能實現,不要爲了追求行數少而合併功能實現
  • 模型數據的賦值、校驗最好放在 model 自己裏面
  • 邏輯模塊和數據模塊要區分開編寫

引用

[1] 用 Python 編寫乾淨、可測試、高質量的代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章