Moduł:StatystykiHistoryczne
Wygląd
Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:StatystykiHistoryczne/opis
local p = {}
-- =========================================================
-- MODUŁ: STATYSTYKIHISTORYCZNE
--
-- Łączne statystyki zawodników ze wszystkich
-- wprowadzonych sezonów.
--
-- KOSZYKÓWKA
--
-- Tabele:
-- 1. Mecze
-- 2. Punkty
-- 3. Minuty
-- 4. Asysty
-- 5. Zbiórki
-- 6. Bloki
--
-- Użycie:
--
-- {{#invoke:StatystykiHistoryczne|main
-- |druzyna=Enea Basket Poznań
-- |sezon_biezacy=2025/2026
-- }}
--
-- Zawodnicy występujący w wybranym sezonie
-- są wyróżniani pogrubieniem.
-- =========================================================
function p.main(frame)
-- =====================================================
-- PARAMETRY
-- =====================================================
local druzyna =
mw.text.trim(
frame.args.druzyna or ""
)
local sezonBiezacy =
mw.text.trim(
frame.args.sezon_biezacy or ""
)
-- =====================================================
-- SPRAWDZENIE DRUŻYNY
-- =====================================================
if druzyna == "" then
return
"'''Błąd:''' nie podano parametru <code>druzyna</code>."
end
-- =====================================================
-- BEZPIECZNE PRZYGOTOWANIE NAZW
-- =====================================================
local druzynaSQL =
mw.ustring.gsub(
druzyna,
"'",
"''"
)
local sezonSQL = ""
if sezonBiezacy ~= "" then
sezonSQL =
mw.ustring.gsub(
sezonBiezacy,
"'",
"''"
)
end
-- =====================================================
-- FUNKCJA LICZBOWA
-- =====================================================
local function liczba(value)
return
tonumber(value or 0)
or 0
end
-- =====================================================
-- USTALENIE SEZONU WYRÓŻNIENIA
-- =====================================================
local sezonWyroznienia = ""
local znalezionoBiezacy = false
-- -----------------------------------------------------
-- Najpierw sprawdzamy sezon podany przez użytkownika
-- -----------------------------------------------------
if sezonSQL ~= "" then
local sprawdzenieSezonu =
mw.ext.cargo.query(
"UdzialZawodnika,Mecze",
"UdzialZawodnika.zawodnik=zawodnik",
{
join =
"UdzialZawodnika.mecz=Mecze.id",
where =
"UdzialZawodnika.druzyna='"
.. druzynaSQL
.. "'"
.. " AND Mecze.sezon='"
.. sezonSQL
.. "'"
.. " AND UdzialZawodnika.minuty > 0",
groupBy =
"UdzialZawodnika.zawodnik",
limit = 5000
}
)
if sprawdzenieSezonu
and #sprawdzenieSezonu > 0 then
sezonWyroznienia = sezonBiezacy
znalezionoBiezacy = true
end
end
-- =====================================================
-- JEŻELI NIE MA DANYCH DLA PODANEGO SEZONU
-- SZUKAMY OSTATNIEGO SEZONU
-- =====================================================
if not znalezionoBiezacy then
local sezony =
mw.ext.cargo.query(
"UdzialZawodnika,Mecze",
"Mecze.sezon=sezon",
{
join =
"UdzialZawodnika.mecz=Mecze.id",
where =
"UdzialZawodnika.druzyna='"
.. druzynaSQL
.. "'"
.. " AND UdzialZawodnika.minuty > 0",
groupBy =
"Mecze.sezon",
orderBy =
"Mecze.sezon DESC",
limit = 100
}
)
if sezony and #sezony > 0 then
sezonWyroznienia =
mw.text.trim(
sezony[1].sezon or ""
)
end
end
-- =====================================================
-- POBRANIE ŁĄCZNYCH DANYCH STATYSTYCZNYCH
-- =====================================================
local fields = table.concat({
"UdzialZawodnika.zawodnik=zawodnik",
"COUNT(UdzialZawodnika.mecz)=mecze",
"SUM(UdzialZawodnika.gol)=punkty",
"SUM(UdzialZawodnika.minuty)=minuty",
"SUM(UdzialZawodnika.asysta)=asysty",
"SUM(UdzialZawodnika.zbiorka)=zbiorki",
"SUM(UdzialZawodnika.blok)=bloki"
}, ",")
-- =====================================================
-- WARUNEK
-- =====================================================
local where =
"UdzialZawodnika.druzyna='"
.. druzynaSQL
.. "'"
.. " AND UdzialZawodnika.minuty > 0"
-- =====================================================
-- ZAPYTANIE
-- =====================================================
local rows =
mw.ext.cargo.query(
"UdzialZawodnika",
fields,
{
where = where,
groupBy =
"UdzialZawodnika.zawodnik",
limit = 5000
}
)
-- =====================================================
-- BRAK DANYCH
-- =====================================================
if not rows or #rows == 0 then
return
"''Brak danych statystycznych dla drużyny "
.. druzyna
.. ".''"
end
-- =====================================================
-- AKTUALNI ZAWODNICY
-- =====================================================
local aktualni = {}
if sezonWyroznienia ~= "" then
local sezonAktualnySQL =
mw.ustring.gsub(
sezonWyroznienia,
"'",
"''"
)
local currentRows =
mw.ext.cargo.query(
"UdzialZawodnika,Mecze",
"UdzialZawodnika.zawodnik=zawodnik",
{
join =
"UdzialZawodnika.mecz=Mecze.id",
where =
"UdzialZawodnika.druzyna='"
.. druzynaSQL
.. "'"
.. " AND Mecze.sezon='"
.. sezonAktualnySQL
.. "'"
.. " AND UdzialZawodnika.minuty > 0",
groupBy =
"UdzialZawodnika.zawodnik",
limit = 5000
}
)
if currentRows then
for _, row in ipairs(currentRows) do
local zawodnik =
mw.text.trim(
row.zawodnik or ""
)
if zawodnik ~= "" then
aktualni[zawodnik] = true
end
end
end
end
-- =====================================================
-- PRZYGOTOWANIE DANYCH
-- =====================================================
local zawodnicy = {}
for _, row in ipairs(rows) do
local zawodnik =
mw.text.trim(
row.zawodnik or ""
)
if zawodnik ~= "" then
table.insert(
zawodnicy,
{
zawodnik = zawodnik,
mecze =
liczba(row.mecze),
punkty =
liczba(row.punkty),
-- Cargo przechowuje minuty jako SEKUNDY
minuty =
liczba(row.minuty),
asysty =
liczba(row.asysty),
zbiorki =
liczba(row.zbiorki),
bloki =
liczba(row.bloki),
aktualny =
aktualni[zawodnik] or false
}
)
end
end
-- =====================================================
-- FORMATOWANIE MINUT
--
-- WAŻNE:
-- Pole UdzialZawodnika.minuty jest zapisane w SEKUNDACH.
--
-- Przykład:
-- 103775 sekund = 1729 minut 35 sekund
--
-- Wynik:
-- 1729:35
-- =====================================================
local function formatujMinuty(sekundy)
local wartosc =
tonumber(sekundy or 0)
or 0
wartosc =
math.floor(
wartosc + 0.5
)
local caleMinuty =
math.floor(
wartosc / 60
)
local pozostaleSekundy =
wartosc % 60
return string.format(
"%d:%02d",
caleMinuty,
pozostaleSekundy
)
end
-- =====================================================
-- LINK DO ZAWODNIKA
-- =====================================================
local function linkZawodnika(row)
local nazwa =
row.zawodnik
local tekst =
"[["
.. nazwa
.. "|"
.. nazwa
.. "]]"
-- -------------------------------------------------
-- AKTUALNY ZAWODNIK = POGRUBIENIE
-- -------------------------------------------------
if row.aktualny then
tekst =
"'''"
.. tekst
.. "'''"
end
return tekst
end
-- =====================================================
-- SORTOWANIE
-- =====================================================
local funkcjeSortowania = {
mecze = function(a, b)
if a.mecze ~= b.mecze then
return a.mecze > b.mecze
end
return a.zawodnik < b.zawodnik
end,
punkty = function(a, b)
if a.punkty ~= b.punkty then
return a.punkty > b.punkty
end
return a.zawodnik < b.zawodnik
end,
minuty = function(a, b)
if a.minuty ~= b.minuty then
return a.minuty > b.minuty
end
return a.zawodnik < b.zawodnik
end,
asysty = function(a, b)
if a.asysty ~= b.asysty then
return a.asysty > b.asysty
end
return a.zawodnik < b.zawodnik
end,
zbiorki = function(a, b)
if a.zbiorki ~= b.zbiorki then
return a.zbiorki > b.zbiorki
end
return a.zawodnik < b.zawodnik
end,
bloki = function(a, b)
if a.bloki ~= b.bloki then
return a.bloki > b.bloki
end
return a.zawodnik < b.zawodnik
end
}
-- =====================================================
-- DEFINICJA TABEL
-- =====================================================
local tabele = {
{
nazwa = "MECZE",
pole = "mecze",
format = function(v)
return tostring(v)
end
},
{
nazwa = "PUNKTY",
pole = "punkty",
format = function(v)
return tostring(v)
end
},
{
nazwa = "MINUTY",
pole = "minuty",
format = function(v)
return formatujMinuty(v)
end
},
{
nazwa = "ASYSTY",
pole = "asysty",
format = function(v)
return tostring(v)
end
},
{
nazwa = "ZBIÓRKI",
pole = "zbiorki",
format = function(v)
return tostring(v)
end
},
{
nazwa = "BLOKI",
pole = "bloki",
format = function(v)
return tostring(v)
end
}
}
-- =====================================================
-- BUDOWANIE POJEDYNCZEJ TABELI
-- =====================================================
local function zbudujTabele(definicja)
local lista = {}
for _, zawodnik in ipairs(zawodnicy) do
table.insert(
lista,
zawodnik
)
end
table.sort(
lista,
funkcjeSortowania[
definicja.pole
]
)
local wynik = {}
-- -------------------------------------------------
-- TABELA
-- -------------------------------------------------
table.insert(
wynik,
'{| class="wikitable" style="width:100%; text-align:center;"'
)
-- -------------------------------------------------
-- NAGŁÓWEK
-- -------------------------------------------------
table.insert(
wynik,
"|+ '''"
.. definicja.nazwa
.. "'''"
)
table.insert(
wynik,
"! Miejsce"
)
table.insert(
wynik,
"! Zawodnik"
)
table.insert(
wynik,
"! "
.. definicja.nazwa
)
-- -------------------------------------------------
-- WIERSZE
-- -------------------------------------------------
for i, zawodnik in ipairs(lista) do
table.insert(
wynik,
"|-"
)
-- miejsce
table.insert(
wynik,
"| "
.. i
)
-- zawodnik
table.insert(
wynik,
"| "
.. linkZawodnika(
zawodnik
)
)
-- wartość
table.insert(
wynik,
"| '''"
.. definicja.format(
zawodnik[
definicja.pole
]
)
.. "'''"
)
end
table.insert(
wynik,
"|}"
)
return table.concat(
wynik,
"\n"
)
end
-- =====================================================
-- WYNIK
-- =====================================================
local wynik = {}
table.insert(
wynik,
"== Statystyki historyczne – "
.. druzyna
.. " =="
)
table.insert(
wynik,
""
)
-- =====================================================
-- INFORMACJA O AKTUALNYCH ZAWODNIKACH
-- =====================================================
if sezonWyroznienia ~= "" then
table.insert(
wynik,
"'''''Pogrubieniem wyróżniono zawodników "
.. "występujących w sezonie "
.. sezonWyroznienia
.. ".'''''"
)
table.insert(
wynik,
""
)
end
-- =====================================================
-- UKŁAD 3 KOLUMNY
--
-- WAŻNE:
-- Każda tabela zaczyna się od początku linii.
-- Dzięki temu MediaWiki poprawnie rozpoznaje
-- składnię {| ... |}.
-- =====================================================
table.insert(
wynik,
'<div style="display:flex; flex-wrap:wrap; gap:12px; align-items:flex-start;">'
)
-- =====================================================
-- TABELA 1 – MECZE
-- =====================================================
table.insert(
wynik,
'<div style="flex:1 1 calc(33.333% - 12px); min-width:280px;">'
)
table.insert(
wynik,
zbudujTabele(
tabele[1]
)
)
table.insert(
wynik,
"</div>"
)
-- =====================================================
-- TABELA 2 – PUNKTY
-- =====================================================
table.insert(
wynik,
'<div style="flex:1 1 calc(33.333% - 12px); min-width:280px;">'
)
table.insert(
wynik,
zbudujTabele(
tabele[2]
)
)
table.insert(
wynik,
"</div>"
)
-- =====================================================
-- TABELA 3 – MINUTY
-- =====================================================
table.insert(
wynik,
'<div style="flex:1 1 calc(33.333% - 12px); min-width:280px;">'
)
table.insert(
wynik,
zbudujTabele(
tabele[3]
)
)
table.insert(
wynik,
"</div>"
)
-- =====================================================
-- TABELA 4 – ASYSTY
-- =====================================================
table.insert(
wynik,
'<div style="flex:1 1 calc(33.333% - 12px); min-width:280px;">'
)
table.insert(
wynik,
zbudujTabele(
tabele[4]
)
)
table.insert(
wynik,
"</div>"
)
-- =====================================================
-- TABELA 5 – ZBIÓRKI
-- =====================================================
table.insert(
wynik,
'<div style="flex:1 1 calc(33.333% - 12px); min-width:280px;">'
)
table.insert(
wynik,
zbudujTabele(
tabele[5]
)
)
table.insert(
wynik,
"</div>"
)
-- =====================================================
-- TABELA 6 – BLOKI
-- =====================================================
table.insert(
wynik,
'<div style="flex:1 1 calc(33.333% - 12px); min-width:280px;">'
)
table.insert(
wynik,
zbudujTabele(
tabele[6]
)
)
table.insert(
wynik,
"</div>"
)
-- =====================================================
-- KONIEC UKŁADU
-- =====================================================
table.insert(
wynik,
"</div>"
)
-- =====================================================
-- ZWRÓCENIE WYNIKU
-- =====================================================
return table.concat(
wynik,
"\n"
)
end
return p