Skip to content

PPROGER/python-ai-oo-metrics

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Аналіз метрик Python AI-проєктів

Опис

Цей проєкт збирає та аналізує метрики об'єктно-орієнтованого коду з Python-репозиторіїв, пов'язаних зі штучним інтелектом (ML/DL/NLP/CV/LLM).

Структура метрик

Всі метрикиділяться на дві групи:

📏 1. Метрики по розміру

  • Кількість рядків коду (KLOC)
  • Кількість класів
  • Середня кількість методів у класі
  • Глибина дерева наслідування (середня)
  • Кількість відносин між класами (оцінка)

⚙️ 2. Метрики по якості та складності (CK-метрики)

  • RFC — Response For a Class
  • CBO — Coupling Between Objects
  • WMC — Weighted Methods per Class

📏 Детальний опис метрик по розміру

🧮 1.1. Кількість рядків коду (KLOC)

Формула:

KLOC = Кількість рядків коду / 1000

Як рахується:

  • Використовується cloc (якщо є) або ручний підрахунок всіх непорожніх рядків у .py файлах
  • Виключаються директорії: tests, docs, examples, build, dist, venv, тощо
  • Результат — значення в тисячах рядків (KLOC)

🧮 1.2. Кількість класів

Формула:

Nс = кількість конструкцій class у коді

Як рахується:

  • Парсер ast Python обходить всі файли
  • Кожен вузол ast.ClassDef враховується як окремий клас

🧮 1.3. Середня кількість методів у класі

Формула:

M̄с = (Σ Mᵢ) / Nс

де Mᵢ — кількість методів (функцій) у класі i

Як рахується:

  • Для кожного класу підраховуються внутрішні FunctionDef або AsyncFunctionDef
  • Береться середня кількість методів на клас

🧮 1.4. Глибина дерева наслідування (DIT)

Формула для одного класу:

DIT(C) = довжина найдовшого ланцюга наслідування від класу C

Середнє значення:

DIT̄ = (1/Nс) × Σ DIT(Cᵢ)

Як рахується:

  • Для кожного класу беруться його базові класи (bases в ast.ClassDef)
  • Якщо базові класи також визначені в проєкті — продовжуємо по ланцюгу
  • DIT збільшується на 1 за кожен рівень наслідування
  • Середнє значення по всіх класах — середня глибина дерева

Приклад:

class A: pass
class B(A): pass
class C(B): pass
  • DIT(A) = 0
  • DIT(B) = 1
  • DIT(C) = 2

🧮 1.5. Кількість відносин між класами (оцінка)

Формула:

R = |Eінheritance ∪ Eusage|

де:

  • Eінheritance — множина ребер "A → B" (A наслідує B)
  • Eusage — множина ребер "A → B" (A використовує B)

Як рахується:

  • Якщо клас наслідує інший (по bases), додається зв'язок
  • Якщо клас використовує інший клас (згадування імені іншого класу в атрибутах або викликах), також додається зв'язок
  • Рахується кількість унікальних пар (клас A → клас B)

⚙️ Детальний опис метрик по якості та складності

🧩 2.1. RFC — Response For a Class

Ідея: Скільки потенційних «реакцій» (методів) може викликати об'єкт даного класу при запиті.

Формула:

RFC(C) = |M| + |R|

де:

  • M — кількість методів у класі
  • R — кількість унікальних викликів методів з цього класу (усіх функцій, викликаних усередині методів)

Як рахується:

  1. Збираємо всі FunctionDef всередині класу
  2. Проходимо по тілу кожного методу, знаходимо всі ast.Call
  3. RFC = кількість власних методів + кількість унікальних викликів

Інтерпретація:

  • Чим вище RFC — тим складніше зрозуміти поведінку класу при виклику (висока відповідальність)
  • Високе значення RFC вказує на складність тестування та підтримки

🧩 2.2. CBO — Coupling Between Objects

Ідея: Кількість унікальних зовнішніх класів, з якими даний клас пов'язаний (використовує, імпортує, викликає тощо).

Формула (апроксимація):

CBO(C) = |(Rcamel ∪ Rknown) − {C}|

де:

  • Rcamel — множина всіх CamelCase ідентифікаторів (схожих на імена класів)
  • Rknown — множина імен інших класів, визначених в цьому ж проєкті
  • {C} — сам клас (виключається)

Як рахується:

  1. Для кожного класу аналізуються всі імена (ast.Name, ast.Attribute)
  2. Якщо ідентифікатор схожий на назву класу (CamelCase) або співпадає з іншим класом проєкту — вважається зв'язком
  3. Підрахунок унікальних імен

Інтерпретація:

  • Висока зв'язаність (високий CBO) ускладнює тестування та повторне використання
  • Низький CBO вказує на слабку залежність між класами (добре для модульності)

🧩 2.3. WMC — Weighted Methods per Class

Ідея: Сумарна складність методів класу.

Формула:

WMC(C) = Σ CCᵢ

де:

  • M — кількість методів у класі
  • CCᵢ — цикломатична складність методу i

Як рахується:

  1. Використовується бібліотека radon, яка обчислює Cyclomatic Complexity (CC) кожного методу
  2. Якщо radon недоступний — береться CCᵢ = 1
  3. WMC = сума CC по всіх методах класу

Інтерпретація:

  • Чим вище WMC — тим складніше тестувати та супроводжувати клас
  • WMC > 50 зазвичай сигнал про надмірну складність

Цикломатична складність (CC):

  • CC вимірює кількість незалежних шляхів виконання через код
  • Враховує умови (if, elif, else), цикли (for, while), винятки (try/except)
  • CC = 1 для простої функції без розгалужень

📊 Агрегація метрик на рівні проєкту

Після обчислення всіх метрик для кожного класу в проєкті береться середнє значення по класах:

Метрика Символ Опис
Середня кількість методів у класі M̄с Просте середнє
Глибина дерева наслідування (середня) DIT̄ Середня глибина ланцюга
RFC (середнє) RFC̄ Середній RFC по всіх класах
CBO (середнє) CBŌ Середній coupling
WMC (середнє) WMC̄ Середня сумарна складність методів

🧠 Зведена таблиця метрик

Категорія Метрика Символ Формула Коментар
По розміру Кількість рядків коду KLOC LOC / 1000 Кількість непорожніх рядків
Кількість класів AST ClassDef
Середня кількість методів M̄с ΣMᵢ / Nс Методи в класах
Глибина наслідування DIT̄ ΣDIT(Cᵢ) / Nс Ланцюги наслідування
Відносини між класами R |Eінheritance ∪ Eusage| Наслідування + використання
По якості та складності RFC RFC(C) |M| + |R| Відповідь класу
CBO CBO(C) |Rcamel ∪ Rknown| Зв'язаність об'єктів
WMC WMC(C) ΣCCᵢ Вага методів (цикломатика)

🔧 Методологія збору даних

Пошук репозиторіїв

Використовується GitHub Search API з наступними критеріями:

  • Мова: Python
  • Теми: machine-learning, deep-learning, nlp, llm, computer-vision
  • Мінімальна кількість зірок: 300 (за замовчуванням)
  • Виключаються форки

Клонування

  • Використовується shallow clone (--depth 1) для економії місця
  • Репозиторії зберігаються у work_ai_metrics/repos/

Аналіз коду

Двопрохідний аналіз:

  1. Перший прохід: збір всіх класів та їх базових класів

    • Парсинг всіх .py файлів через ast
    • Збір імен класів та їх bases
  2. Другий прохід: підрахунок метрик для кожного класу

    • Аналіз методів
    • Підрахунок цикломатичної складності (через radon)
    • Виявлення викликів та залежностей
    • Побудова графу відносин

Виключення

З аналізу виключаються файли з директорій:

  • venv, .venv, site-packages
  • tests, test
  • docs, examples
  • build, dist
  • node_modules
  • .git, __pycache__

📦 Залежності

pip install requests radon

Опціонально (для точного підрахунку LOC):

# cloc - https://github.com/AlDanial/cloc
# macOS:
brew install cloc
# Linux:
sudo apt-get install cloc

🚀 Використання

# Базове використання
python collect_ai_python_metrics.py

# З налаштуваннями
python collect_ai_python_metrics.py \
  --limit 100 \
  --min-stars 500 \
  --out результати.csv \
  --workdir робоча_директорія

# Аналіз без клонування (використовувати існуючі репозиторії)
python collect_ai_python_metrics.py --no-clone

Параметри

Параметр Опис За замовчуванням
--limit Кількість репозиторіїв для збору 50
--min-stars Мінімальна кількість зірок на GitHub 300
--out Файл для збереження результатів results.csv
--workdir Робоча директорія work_ai_metrics
--no-clone Аналізувати існуючі репозиторії без клонування

GitHub Token

Для збільшення ліміту API-запитів:

export GITHUB_TOKEN="ваш_токен"

📄 Вихідні дані

CSV-файл з UTF-8 BOM кодуванням, колонки:

  1. Назва проєкту
  2. Посилання
  3. Кількість рядків коду (тис.)
  4. Кількість класів
  5. Середня кількість методів у класі
  6. Глибина дерева наслідування (середня)
  7. Кількість відносин між класами (оцінка)
  8. RFC (середнє)
  9. CBO (середнє)
  10. WMC (середнє)

🔬 Технічні деталі

AST-парсинг

Використовується вбудований модуль ast Python для статичного аналізу коду:

  • Виявлення класів: ast.ClassDef
  • Виявлення методів: ast.FunctionDef, ast.AsyncFunctionDef
  • Виявлення викликів: ast.Call
  • Виявлення посилань: ast.Name, ast.Attribute

Цикломатична складність

Обчислюється за допомогою бібліотеки radon:

  • Аналізує структуру коду (умови, цикли, винятки)
  • Повертає числове значення складності для кожної функції/методу
  • Fallback: якщо radon недоступний — використовується CC = 1 для кожного методу

Граф залежностей

Будується граф відносин між класами:

  • Вершини: класи проєкту
  • Ребра: відносини наслідування та використання
  • Підраховується загальна кількість унікальних ребер

📚 Посилання та ресурси

  • CK Metrics: Chidamber & Kemerer (1994) — класичні об'єктно-орієнтовані метрики
  • Radon: https://radon.readthedocs.io/ — бібліотека для розрахунку метрик коду
  • cloc: https://github.com/AlDanial/cloc — підрахунок рядків коду

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages