Модуль:Cron/GenerateStats/doc: различия между версиями
Lord (обсуждение | вклад) Нет описания правки |
Lord (обсуждение | вклад) Нет описания правки |
||
| (не показана 1 промежуточная версия этого же участника) | |||
| Строка 2: | Строка 2: | ||
{{С*|prefix=Модуль:|format=ul|PlayerStats|PlayerAchievements|Автоматическая статистика}} | {{С*|prefix=Модуль:|format=ul|PlayerStats|PlayerAchievements|Автоматическая статистика}} | ||
* [[Служебная:Развёртка шаблонов]] ({{Параметр|#invoke:Cron/GenerateStats{{!}}main}} | * [[Служебная:Развёртка шаблонов]] ({{Параметр|#invoke:Cron/GenerateStats{{!}}main}} | ||
* [[Модуль:Data/GrandStats.json]] | |||
<markdown>**Модуль:Cron/GenerateStats** представляет собой служебный скрипт на языке Lua (Scribunto) для ЧТМ Вики, предназначенный для агрегации, расчёта и кэширования полной статистической базы данных проекта. | |||
Основная задача модуля — собрать данные обо всех сыгранных матчах, игроках, командах и наградах за все сезоны, провести ресурсоёмкие вычисления (такие как расчёт игровых серий, вычисление лидеров, распределение медалей и интеграция рейтинга) и экспортировать финальный структурированный результат в формате **JSON**. Полученный JSON-кэш используется другими модулями для быстрой отрисовки страниц и таблиц без повторного обхода всей базы данных при каждом просмотре. | |||
--- | |||
### 1. Зависимости модуля | |||
Для работы скрипт импортирует следующие компоненты: | |||
* **`Module:Config`** — содержит общую конфигурацию проекта (список сезонов `years`, настройки эры матчей `eras`, правила для плей-офф и корректировки). | |||
* **`Module:Data/Teams`** — справочник футбольных/спортивных команд. | |||
* **`Module:StatEngine/Pure`** — базовый движок сбора статистики. Метод `Harvester.run_all_time` производит первичный обход баз данных матчей. | |||
* **`Module:StatEngine/TournamentAwards`** — логика определения лучших игроков турниров, распределения номинаций (лучший бомбардир, ассистент) и обработки игровых дней (matchdays). | |||
* **`Module:Megarating`** — предоставляет исторические данные рейтинга игроков через метод `get_public_history()`. | |||
* **`Module:StatEngine/StreaksCore`** — специализированный компонент для вычисления последовательных серий (голевых, беспроигрышных, вратарских "сухих" и т. д.). | |||
* **`Module:Автоматическая статистика`** — содержит метаданные и структуру строк (`row_defs`) для формирования индивидуальных профилей игроков. | |||
--- | |||
### 2. Внутренние (вспомогательные) функции | |||
* **`plural(n, w1, w2, w5)`** | |||
Реализует алгоритм русской локализации числительных (согласование существительных с числами). | |||
* *Параметры*: `n` (число), `w1` ("день"), `w2` ("дня"), `w5` ("дней"). | |||
* *Возвращает*: соответствующую форму слова в зависимости от значения `n`. | |||
* **`date_diff(date1, date2)`** | |||
Вычисляет разницу во времени между двумя датами в формате `YYYY-MM-DD`. | |||
* *Возвращает*: | |||
1. Количество дней (число) для сравнения интервалов. | |||
2. Текстовое представление разницы на русском языке (например, `"1 год 2 месяца 5 дней"`). | |||
* **`apply_adj(s, m, v)`** | |||
Применяет ручные корректировки показателей игрока, если данные за старые периоды неполные или требуют точечного исправления. | |||
* *Параметры*: `s` — таблица статистики игрока, `m` — идентификатор метрики (например, `"goals"`, `"clean_sheets"`), `v` — числовое значение корректировки (прибавляется к текущему). | |||
--- | |||
### 3. Алгоритм работы `Cron.main` | |||
При вызове функции `Cron.main(frame)` выполняются следующие шаги: | |||
#### Шаг 3.1. Загрузка и первичный сбор данных | |||
1. Из `Module:Config` считывается массив активных сезонов. Скрипт поочерёдно загружает модули данных вида `Module:Data/<Год>` через безопасный вызов `pcall`. | |||
2. Функция `StatEngine.Harvester.run_all_time` собирает агрегированную сырую статистику по игрокам, командам и их связкам (`GrandStats`). | |||
#### Шаг 3.2. Применение ручных корректировок | |||
* На основе конфигурационных параметров `Config.award_adjustments` и индивидуальных настроек метрик `Config.metrics` вносятся исправления в показатели игроков за конкретные годы (например, добавляются голы или ассисты, не зафиксированные в стандартных протоколах). | |||
#### Шаг 3.3. Поматчевый хронологический анализ | |||
* Все матчи из всех сезонных баз данных объединяются в плоский список и сортируются строго по дате и ID матча. | |||
* Происходит последовательный обход матчей с помощью `StreaksEngine` для расчёта игровых серий. | |||
* Накапливаются данные о дебютных матчах игроков (`navbox_data.debuts`). | |||
* Для сезонов начиная с 2022 года формируется детальная поматчевая история игрока (`player_matches_list`), включающая: | |||
* Статус (старт/замена, роль вратаря или полевого). | |||
* Забитые мячи (включая тип: головой, автогол, с пенальти). | |||
* Голевые передачи. | |||
* Участие в сериях послематчевых пенальти и отражённые удары. | |||
* События матча (карточки, выносы из пустых ворот и т.д.). | |||
* Фиксируются перерывы в карьере игроков (вычисляется наибольший интервал без матчей через `date_diff`). | |||
* Выявляются победители турниров, обладатели индивидуальных наград финалов (Золотой мяч, Золотая бутса, лучший ассистент, приз Эльнура и др.). | |||
#### Шаг 3.4. Анализ игровых дней (Matchdays) | |||
* Для сезонов с 2022 года с помощью `TournamentAwards.evaluateMatchdayPrizes` рассчитываются индивидуальные достижения игроков в рамках отдельных туров/игровых дней (призы за MVP тура, лучший вратарь, результативность и т.д.). Эти данные суммируются в профилях игроков. | |||
#### Шаг 3.5. Определение лидеров сезона и распределение медалей | |||
* По каждой метрике из списка автоматической статистики определяется список лидеров за каждый год. | |||
* С помощью `TournamentAwards.getGenericMetric` рассчитываются "медали" (золотые, серебряные, бронзовые, деревянные) для игроков как за отдельные сезоны, так и в суммарном рейтинге за всё время. Медали присваивают игрокам соответствующие цветовые маркеры (`color`). | |||
#### Шаг 3.6. Интеграция рейтинга | |||
* Данные о динамике Мегарейтинга (`mr_hist`) распределяются по годам в профили игроков. | |||
#### Шаг 3.7. Подсчёт глобальных рекордов | |||
* Вычисляются максимальные (или минимальные для GAA) показатели среди всех игроков: | |||
* За всю историю проекта (`PA_GlobalRecords.AllTime`). | |||
* В рамках одного конкретного турнира (`PA_GlobalRecords.PerTournament`). | |||
#### Шаг 3.8. Минимизация размера JSON | |||
* Для снижения нагрузки на парсер MediaWiki производится очистка структуры данных. Из таблиц игроков удаляются пустые поля, неиспользуемые годы и метрики, у которых все показатели (значение, числитель, знаменатель, медали) равны нулю. | |||
#### Шаг 3.9. Сериализация и вывод | |||
* Собранная таблица `ExportData` преобразуется в JSON-строку при помощи встроенной функции `mw.text.jsonEncode` и возвращается вызывающей стороне. | |||
--- | |||
### 4. Структура экспортируемого JSON-кэша | |||
Финальный JSON содержит две основные ветки: `Global` (глобальные метаданные) и `Players` (индивидуальные профили).</markdown> | |||
<syntaxhighlight lang="json" line> | |||
{ | |||
"Global": { | |||
"navbox_data": { | |||
"champs": { "2022": ["Игрок А", "Игрок Б"], "2023": [...] }, | |||
"superchamps": [ [2022, "Игрок А"] ], | |||
"zshar": [ [2022, "Игрок Б"] ], | |||
"zbashmak": [ [2022, "Игрок В", 15, "TEAM_CODE"] ], | |||
"elnur": [], | |||
"final_goals": { "Игрок А": 5 }, | |||
"final_assists": { "Игрок Б": 3 }, | |||
"loyalty": [ [2022, "Игрок А", "Команда Х"] ], | |||
"debuts": { "Игрок А": 2021 }, | |||
"champ_counts": { "Игрок А": 3 }, | |||
"global_goals": { "Игрок А": 120 }, | |||
"team_matches": { "2022": { "Игрок А": { "TEAM_CODE": 10 } } } | |||
}, | |||
"PA_GlobalRecords": { | |||
"AllTime": { "goals": 150, "max_streaks_goals": 8, "...": 0 }, | |||
"PerTournament": { "goals": 25, "...": 0 } | |||
}, | |||
"PA_CustomStats": { | |||
"club100": [ { "name": "Игрок А", "year": 2022 } ], | |||
"stadiums": { "Стадион 1": { "Игрок А": 45 } }, | |||
"finals": { "2022": { "goals_count": {}, "superchampions": [], "...": "" } } | |||
}, | |||
"PA_Leaders": { | |||
"goals": { "2022": ["Игрок А"], "2023": ["Игрок Б", "Игрок В"] } | |||
}, | |||
"PA_TeamLeaders": { | |||
"TEAM_CODE": { "players": ["Игрок А"], "goals": 80 } | |||
}, | |||
"PA_StadiumLeaders": { | |||
"Стадион 1": { "players": ["Игрок А"], "goals": 45 } | |||
}, | |||
"PA_ShoeTeams": { "2022": { "Игрок А": "TEAM_CODE" } }, | |||
"PA_AssistTeams": { "2022": { "Игрок Б": "TEAM_CODE" } } | |||
}, | |||
"Players": { | |||
"Имя Игрока": { | |||
"name": "Имя Игрока", | |||
"AS_compiled": { | |||
"played_years": { "2022": true, "2023": true }, | |||
"last_played_year": 2023, | |||
"played_before_2022": false, | |||
"metrics": { | |||
"goals": { | |||
"total_val": 42, | |||
"total_num": 0, "total_den": 0, "color": "gold", | |||
"years": { | |||
"2022": { "val": 20, "num": 0, "den": 0, "color": "silver" }, | |||
"2023": { "val": 22, "num": 0, "den": 0, "color": "gold" } | |||
} | |||
} | |||
}, | |||
"player_matches_list": [ | |||
{ | |||
"year": 2022, "num_hist": 123, "date": "2022-05-12", "stage": "Группа", | |||
"team1": "Команда А", "team2": "Команда Б", "score1": 3, "score2": 1, | |||
"role_team": 1, "goals": 2, "assists": 1, "is_mvp": true, "events": ["Гол головой"] | |||
} | |||
] | |||
}, | |||
"PA_Player": { | |||
"goals": 42, "matches": 50, "champs": 2, "champs_years": [2022, 2023], | |||
"max_streaks": { "goals": 5, "unbeaten": 12 }, | |||
"tournaments": { | |||
"2022": { "goals": 20, "matches": 24, "playoff_goals": 4 } | |||
} | |||
}, | |||
"mr_history": { "total_pct": 74.5, "years": { "2022": { "pct": 72.0, "pts": 150 } } } | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
<markdown>--- | |||
### 5. Использование в других модулях | |||
Чтобы получить доступ к сгенерированной статистике без повторного обсчёта, другие Lua-скрипты используют декодирование JSON-строки, возвращаемой данным модулем. | |||
**Пример интеграции в стороннем модуле:**</markdown> | |||
<syntaxhighlight lang="lua" line> | |||
local CronStats = require('Module:Cron/GenerateStats') | |||
local p = {} | |||
function p.showPlayerGoals(frame) | |||
-- Получаем кэш в формате JSON | |||
local raw_json = CronStats.main(frame) | |||
local data = mw.text.jsonDecode(raw_json) | |||
local player_name = frame.args[1] or "Герыч" | |||
local player_data = data.Players[player_name] | |||
if player_data and player_data.PA_Player then | |||
return player_name .. " забил всего голов: " .. tostring(player_data.PA_Player.goals) | |||
else | |||
return "Игрок не найден или у него нет статистики." | |||
end | |||
end | |||
return p | |||
</syntaxhighlight> | |||
---- | ---- | ||
<includeonly>''Пожалуйста, добавляйте категории на страницу [[/doc|документации]]''.</includeonly>{{Doc/end}} | <includeonly>''Пожалуйста, добавляйте категории на страницу [[/doc|документации]]''.</includeonly>{{Doc/end}} | ||
Текущая версия от 21:33, 4 июня 2026
- PlayerStats
- PlayerAchievements
- Автоматическая статистика
- Служебная:Развёртка шаблонов (
{{#invoke:Cron/GenerateStats|main}} - Модуль:Data/GrandStats.json
Модуль:Cron/GenerateStats представляет собой служебный скрипт на языке Lua (Scribunto) для ЧТМ Вики, предназначенный для агрегации, расчёта и кэширования полной статистической базы данных проекта.
Основная задача модуля — собрать данные обо всех сыгранных матчах, игроках, командах и наградах за все сезоны, провести ресурсоёмкие вычисления (такие как расчёт игровых серий, вычисление лидеров, распределение медалей и интеграция рейтинга) и экспортировать финальный структурированный результат в формате JSON. Полученный JSON-кэш используется другими модулями для быстрой отрисовки страниц и таблиц без повторного обхода всей базы данных при каждом просмотре.
1. Зависимости модуля
Для работы скрипт импортирует следующие компоненты:
Module:Config— содержит общую конфигурацию проекта (список сезоновyears, настройки эры матчейeras, правила для плей-офф и корректировки).Module:Data/Teams— справочник футбольных/спортивных команд.Module:StatEngine/Pure— базовый движок сбора статистики. МетодHarvester.run_all_timeпроизводит первичный обход баз данных матчей.Module:StatEngine/TournamentAwards— логика определения лучших игроков турниров, распределения номинаций (лучший бомбардир, ассистент) и обработки игровых дней (matchdays).Module:Megarating— предоставляет исторические данные рейтинга игроков через методget_public_history().Module:StatEngine/StreaksCore— специализированный компонент для вычисления последовательных серий (голевых, беспроигрышных, вратарских "сухих" и т. д.).Module:Автоматическая статистика— содержит метаданные и структуру строк (row_defs) для формирования индивидуальных профилей игроков.
2. Внутренние (вспомогательные) функции
-
plural(n, w1, w2, w5)
Реализует алгоритм русской локализации числительных (согласование существительных с числами).- Параметры:
n(число),w1("день"),w2("дня"),w5("дней"). - Возвращает: соответствующую форму слова в зависимости от значения
n.
- Параметры:
-
date_diff(date1, date2)
Вычисляет разницу во времени между двумя датами в форматеYYYY-MM-DD.- Возвращает:
- Количество дней (число) для сравнения интервалов.
- Текстовое представление разницы на русском языке (например,
"1 год 2 месяца 5 дней").
- Возвращает:
-
apply_adj(s, m, v)
Применяет ручные корректировки показателей игрока, если данные за старые периоды неполные или требуют точечного исправления.- Параметры:
s— таблица статистики игрока,m— идентификатор метрики (например,"goals","clean_sheets"),v— числовое значение корректировки (прибавляется к текущему).
- Параметры:
3. Алгоритм работы Cron.main
При вызове функции Cron.main(frame) выполняются следующие шаги:
Шаг 3.1. Загрузка и первичный сбор данных
- Из
Module:Configсчитывается массив активных сезонов. Скрипт поочерёдно загружает модули данных видаModule:Data/<Год>через безопасный вызовpcall. - Функция
StatEngine.Harvester.run_all_timeсобирает агрегированную сырую статистику по игрокам, командам и их связкам (GrandStats).
Шаг 3.2. Применение ручных корректировок
- На основе конфигурационных параметров
Config.award_adjustmentsи индивидуальных настроек метрикConfig.metricsвносятся исправления в показатели игроков за конкретные годы (например, добавляются голы или ассисты, не зафиксированные в стандартных протоколах).
Шаг 3.3. Поматчевый хронологический анализ
- Все матчи из всех сезонных баз данных объединяются в плоский список и сортируются строго по дате и ID матча.
- Происходит последовательный обход матчей с помощью
StreaksEngineдля расчёта игровых серий. - Накапливаются данные о дебютных матчах игроков (
navbox_data.debuts). - Для сезонов начиная с 2022 года формируется детальная поматчевая история игрока (
player_matches_list), включающая:- Статус (старт/замена, роль вратаря или полевого).
- Забитые мячи (включая тип: головой, автогол, с пенальти).
- Голевые передачи.
- Участие в сериях послематчевых пенальти и отражённые удары.
- События матча (карточки, выносы из пустых ворот и т.д.).
- Фиксируются перерывы в карьере игроков (вычисляется наибольший интервал без матчей через
date_diff). - Выявляются победители турниров, обладатели индивидуальных наград финалов (Золотой мяч, Золотая бутса, лучший ассистент, приз Эльнура и др.).
Шаг 3.4. Анализ игровых дней (Matchdays)
- Для сезонов с 2022 года с помощью
TournamentAwards.evaluateMatchdayPrizesрассчитываются индивидуальные достижения игроков в рамках отдельных туров/игровых дней (призы за MVP тура, лучший вратарь, результативность и т.д.). Эти данные суммируются в профилях игроков.
Шаг 3.5. Определение лидеров сезона и распределение медалей
- По каждой метрике из списка автоматической статистики определяется список лидеров за каждый год.
- С помощью
TournamentAwards.getGenericMetricрассчитываются "медали" (золотые, серебряные, бронзовые, деревянные) для игроков как за отдельные сезоны, так и в суммарном рейтинге за всё время. Медали присваивают игрокам соответствующие цветовые маркеры (color).
Шаг 3.6. Интеграция рейтинга
- Данные о динамике Мегарейтинга (
mr_hist) распределяются по годам в профили игроков.
Шаг 3.7. Подсчёт глобальных рекордов
- Вычисляются максимальные (или минимальные для GAA) показатели среди всех игроков:
- За всю историю проекта (
PA_GlobalRecords.AllTime). - В рамках одного конкретного турнира (
PA_GlobalRecords.PerTournament).
- За всю историю проекта (
Шаг 3.8. Минимизация размера JSON
- Для снижения нагрузки на парсер MediaWiki производится очистка структуры данных. Из таблиц игроков удаляются пустые поля, неиспользуемые годы и метрики, у которых все показатели (значение, числитель, знаменатель, медали) равны нулю.
Шаг 3.9. Сериализация и вывод
- Собранная таблица
ExportDataпреобразуется в JSON-строку при помощи встроенной функцииmw.text.jsonEncodeи возвращается вызывающей стороне.
4. Структура экспортируемого JSON-кэша
Финальный JSON содержит две основные ветки: Global (глобальные метаданные) и Players (индивидуальные профили).
{
"Global": {
"navbox_data": {
"champs": { "2022": ["Игрок А", "Игрок Б"], "2023": [...] },
"superchamps": [ [2022, "Игрок А"] ],
"zshar": [ [2022, "Игрок Б"] ],
"zbashmak": [ [2022, "Игрок В", 15, "TEAM_CODE"] ],
"elnur": [],
"final_goals": { "Игрок А": 5 },
"final_assists": { "Игрок Б": 3 },
"loyalty": [ [2022, "Игрок А", "Команда Х"] ],
"debuts": { "Игрок А": 2021 },
"champ_counts": { "Игрок А": 3 },
"global_goals": { "Игрок А": 120 },
"team_matches": { "2022": { "Игрок А": { "TEAM_CODE": 10 } } }
},
"PA_GlobalRecords": {
"AllTime": { "goals": 150, "max_streaks_goals": 8, "...": 0 },
"PerTournament": { "goals": 25, "...": 0 }
},
"PA_CustomStats": {
"club100": [ { "name": "Игрок А", "year": 2022 } ],
"stadiums": { "Стадион 1": { "Игрок А": 45 } },
"finals": { "2022": { "goals_count": {}, "superchampions": [], "...": "" } }
},
"PA_Leaders": {
"goals": { "2022": ["Игрок А"], "2023": ["Игрок Б", "Игрок В"] }
},
"PA_TeamLeaders": {
"TEAM_CODE": { "players": ["Игрок А"], "goals": 80 }
},
"PA_StadiumLeaders": {
"Стадион 1": { "players": ["Игрок А"], "goals": 45 }
},
"PA_ShoeTeams": { "2022": { "Игрок А": "TEAM_CODE" } },
"PA_AssistTeams": { "2022": { "Игрок Б": "TEAM_CODE" } }
},
"Players": {
"Имя Игрока": {
"name": "Имя Игрока",
"AS_compiled": {
"played_years": { "2022": true, "2023": true },
"last_played_year": 2023,
"played_before_2022": false,
"metrics": {
"goals": {
"total_val": 42,
"total_num": 0, "total_den": 0, "color": "gold",
"years": {
"2022": { "val": 20, "num": 0, "den": 0, "color": "silver" },
"2023": { "val": 22, "num": 0, "den": 0, "color": "gold" }
}
}
},
"player_matches_list": [
{
"year": 2022, "num_hist": 123, "date": "2022-05-12", "stage": "Группа",
"team1": "Команда А", "team2": "Команда Б", "score1": 3, "score2": 1,
"role_team": 1, "goals": 2, "assists": 1, "is_mvp": true, "events": ["Гол головой"]
}
]
},
"PA_Player": {
"goals": 42, "matches": 50, "champs": 2, "champs_years": [2022, 2023],
"max_streaks": { "goals": 5, "unbeaten": 12 },
"tournaments": {
"2022": { "goals": 20, "matches": 24, "playoff_goals": 4 }
}
},
"mr_history": { "total_pct": 74.5, "years": { "2022": { "pct": 72.0, "pts": 150 } } }
}
}
}
5. Использование в других модулях
Чтобы получить доступ к сгенерированной статистике без повторного обсчёта, другие Lua-скрипты используют декодирование JSON-строки, возвращаемой данным модулем.
Пример интеграции в стороннем модуле:
local CronStats = require('Module:Cron/GenerateStats')
local p = {}
function p.showPlayerGoals(frame)
-- Получаем кэш в формате JSON
local raw_json = CronStats.main(frame)
local data = mw.text.jsonDecode(raw_json)
local player_name = frame.args[1] or "Герыч"
local player_data = data.Players[player_name]
if player_data and player_data.PA_Player then
return player_name .. " забил всего голов: " .. tostring(player_data.PA_Player.goals)
else
return "Игрок не найден или у него нет статистики."
end
end
return p