Compare commits
No commits in common. "71dc7ee56914978a2c459794149edbb446423980" and "fb2d2944596538de2764f87b11eea1fb462f52ad" have entirely different histories.
71dc7ee569
...
fb2d294459
2 changed files with 2 additions and 381 deletions
4
main.py
4
main.py
|
|
@ -293,5 +293,5 @@ def main():
|
||||||
show_table(west, 'Конференция Запад ' + season)
|
show_table(west, 'Конференция Запад ' + season)
|
||||||
show_table(east, 'Конференция Восток ' + season)
|
show_table(east, 'Конференция Восток ' + season)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
379
new_main.py
379
new_main.py
|
|
@ -1,379 +0,0 @@
|
||||||
'''
|
|
||||||
new_main.py - построение турнирной таблицы КХЛ из файла с результатами матчей.
|
|
||||||
|
|
||||||
ОБЩАЯ ЛОГИКА (что происходит, сверху вниз):
|
|
||||||
1. Запуск: python3 main.py khl_3/khl_2018_19.csv
|
|
||||||
2. По имени файла определяется код сезона (например, "2018_19") и берётся
|
|
||||||
словарь "команда -> конференция" из CONFERENCES.
|
|
||||||
3. CSV читается в таблицу матчей df (одна строка = один матч, счёт по периодам).
|
|
||||||
4. build_standings(df, conf_map) превращает матчи в турнирную таблицу команд:
|
|
||||||
по каждому матчу определяется исход (победа/поражение и каким образом),
|
|
||||||
результаты разносятся на обе команды, суммируются и сортируются по правилам КХЛ.
|
|
||||||
5. Для таблиц конференций учитываются дивизионы: в нужных сезонах победители
|
|
||||||
дивизионов получают места 1 и 2 внутри своей конференции.
|
|
||||||
6. show_table(...) печатает таблицу: общую по чемпионату и отдельно по двум
|
|
||||||
конференциям (Запад / Восток).
|
|
||||||
|
|
||||||
ВХОДНЫЕ ДАННЫЕ (столбцы CSV):
|
|
||||||
Команда_1 - хозяева, Команда_2 - гости;
|
|
||||||
Период_1/2/3 - счёт по периодам в формате "3:1" (хозяева:гости);
|
|
||||||
Овертайм, Буллиты - счёт за овертайм и серию буллитов (или ":" если их не было).
|
|
||||||
|
|
||||||
Зависимости: pandas (таблицы), numpy (нумерация мест).
|
|
||||||
'''
|
|
||||||
|
|
||||||
import sys # для аргументов командной строки
|
|
||||||
import os # чтобы достать имя файла из пути
|
|
||||||
import pandas as pd
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
|
|
||||||
def make_conf(west, east):
|
|
||||||
'''
|
|
||||||
Собрать словарь {название команды -> конференция} из двух списков команд.
|
|
||||||
|
|
||||||
Принимает: west, east - списки названий команд Западной и Восточной конференций.
|
|
||||||
Возвращает: dict, где каждой команде сопоставлена строка 'Запад' или 'Восток'.
|
|
||||||
|
|
||||||
Нужен, чтобы позже одной операцией .map() приписать каждой команде её конференцию.
|
|
||||||
'''
|
|
||||||
d = {}
|
|
||||||
d.update({team: 'Запад' for team in west})
|
|
||||||
d.update({team: 'Восток' for team in east})
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
# ключ - это код сезона (например, 2018_19)
|
|
||||||
CONFERENCES = {
|
|
||||||
'2018_19': make_conf(
|
|
||||||
west=['ЦСКА', 'СКА', 'Локомотив', 'Йокерит', 'Динамо М', 'ХК Сочи',
|
|
||||||
'Спартак', 'Витязь', 'Динамо Р', 'Северсталь', 'Динамо Мн', 'Слован'],
|
|
||||||
east=['Автомобилист', 'Барыс', 'Металлург Мг', 'Авангард', 'Ак Барс',
|
|
||||||
'Салават Юлаев', 'Торпедо НН', 'Трактор', 'Сибирь', 'Нефтехимик',
|
|
||||||
'Куньлунь РС', 'Адмирал', 'Амур'],
|
|
||||||
),
|
|
||||||
'2019_20': make_conf(
|
|
||||||
west=['ЦСКА', 'СКА', 'Йокерит', 'Динамо М', 'Спартак', 'Локомотив',
|
|
||||||
'Витязь', 'Торпедо НН', 'ХК Сочи', 'Северсталь', 'Динамо Р', 'Динамо Мн'],
|
|
||||||
east=['Ак Барс', 'Барыс', 'Авангард', 'Автомобилист', 'Сибирь',
|
|
||||||
'Салават Юлаев', 'Металлург Мг', 'Нефтехимик', 'Амур', 'Куньлунь РС',
|
|
||||||
'Трактор', 'Адмирал'],
|
|
||||||
),
|
|
||||||
'2020_21': make_conf(
|
|
||||||
west=['ЦСКА', 'СКА', 'Динамо М', 'Локомотив', 'Йокерит', 'Северсталь',
|
|
||||||
'Динамо Мн', 'Спартак', 'Витязь', 'ХК Сочи', 'Динамо Р'],
|
|
||||||
east=['Ак Барс', 'Авангард', 'Металлург Мг', 'Салават Юлаев', 'Трактор',
|
|
||||||
'Барыс', 'Автомобилист', 'Торпедо НН', 'Сибирь', 'Амур', 'Нефтехимик',
|
|
||||||
'Куньлунь РС'],
|
|
||||||
),
|
|
||||||
'2021_22': make_conf(
|
|
||||||
west=['СКА', 'Йокерит', 'ЦСКА', 'Динамо М', 'Северсталь', 'Локомотив',
|
|
||||||
'Спартак', 'Динамо Мн', 'Торпедо', 'Витязь', 'ХК Сочи', 'Динамо Р'],
|
|
||||||
east=['Металлург Мг', 'Трактор', 'Салават Юлаев', 'Ак Барс', 'Авангард',
|
|
||||||
'Сибирь', 'Нефтехимик', 'Барыс', 'Автомобилист', 'Амур', 'Адмирал',
|
|
||||||
'Куньлунь РС'],
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def make_div(bobrov, tarasov, kharlamov, chernyshev):
|
|
||||||
'''
|
|
||||||
Собрать словарь {название команды -> дивизион} из четырёх списков команд.
|
|
||||||
|
|
||||||
Дивизионы Боброва и Тарасова относятся к Западу, Харламова и Чернышёва -
|
|
||||||
к Востоку. Нужны для финального посева победителей дивизионов в таблицах
|
|
||||||
конференций.
|
|
||||||
'''
|
|
||||||
d = {}
|
|
||||||
d.update({team: 'Боброва' for team in bobrov})
|
|
||||||
d.update({team: 'Тарасова' for team in tarasov})
|
|
||||||
d.update({team: 'Харламова' for team in kharlamov})
|
|
||||||
d.update({team: 'Чернышёва' for team in chernyshev})
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
DIVISIONS = {
|
|
||||||
'2018_19': make_div(
|
|
||||||
bobrov=['СКА', 'Йокерит', 'Динамо М', 'Динамо Мн', 'Динамо Р', 'Слован'],
|
|
||||||
tarasov=['ЦСКА', 'Локомотив', 'ХК Сочи', 'Спартак', 'Витязь', 'Северсталь'],
|
|
||||||
kharlamov=['Автомобилист', 'Металлург Мг', 'Ак Барс', 'Трактор',
|
|
||||||
'Нефтехимик', 'Куньлунь РС', 'Адмирал'],
|
|
||||||
chernyshev=['Барыс', 'Авангард', 'Салават Юлаев', 'Сибирь',
|
|
||||||
'Торпедо НН', 'Амур'],
|
|
||||||
),
|
|
||||||
'2019_20': make_div(
|
|
||||||
bobrov=['СКА', 'Йокерит', 'Спартак', 'Динамо М', 'Динамо Мн', 'Динамо Р'],
|
|
||||||
tarasov=['ЦСКА', 'Локомотив', 'Витязь', 'Торпедо НН', 'ХК Сочи', 'Северсталь'],
|
|
||||||
kharlamov=['Ак Барс', 'Металлург Мг', 'Автомобилист', 'Нефтехимик',
|
|
||||||
'Трактор', 'Адмирал'],
|
|
||||||
chernyshev=['Авангард', 'Барыс', 'Салават Юлаев', 'Сибирь',
|
|
||||||
'Амур', 'Куньлунь РС'],
|
|
||||||
),
|
|
||||||
'2020_21': make_div(
|
|
||||||
bobrov=['СКА', 'Йокерит', 'Северсталь', 'Спартак', 'Витязь', 'ХК Сочи'],
|
|
||||||
tarasov=['ЦСКА', 'Динамо М', 'Локомотив', 'Динамо Мн', 'Динамо Р'],
|
|
||||||
kharlamov=['Автомобилист', 'Ак Барс', 'Металлург Мг', 'Нефтехимик',
|
|
||||||
'Трактор', 'Торпедо НН'],
|
|
||||||
chernyshev=['Авангард', 'Амур', 'Барыс', 'Куньлунь РС',
|
|
||||||
'Салават Юлаев', 'Сибирь'],
|
|
||||||
),
|
|
||||||
'2021_22': make_div(
|
|
||||||
bobrov=['Витязь', 'Йокерит', 'СКА', 'ХК Сочи', 'Торпедо', 'Спартак'],
|
|
||||||
tarasov=['Динамо М', 'Динамо Мн', 'Динамо Р', 'Локомотив', 'Северсталь', 'ЦСКА'],
|
|
||||||
kharlamov=['Автомобилист', 'Ак Барс', 'Куньлунь РС', 'Металлург Мг',
|
|
||||||
'Нефтехимик', 'Трактор'],
|
|
||||||
chernyshev=['Авангард', 'Амур', 'Барыс', 'Сибирь', 'Салават Юлаев', 'Адмирал'],
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SEED_BY_DIVISION = {
|
|
||||||
'2018_19': True,
|
|
||||||
'2019_20': True,
|
|
||||||
'2020_21': True,
|
|
||||||
'2021_22': False,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def seed_conference(conf_table):
|
|
||||||
'''
|
|
||||||
Поставить победителей двух дивизионов на места 1 и 2 в конференции.
|
|
||||||
|
|
||||||
На вход приходит таблица одной конференции, уже отсортированная по основным
|
|
||||||
правилам КХЛ. Поэтому первая команда каждого дивизиона - победитель
|
|
||||||
дивизиона, а порядок между двумя победителями уже правильный.
|
|
||||||
'''
|
|
||||||
winners = conf_table.groupby('Див', sort=False).head(1)
|
|
||||||
rest = conf_table.drop(winners.index)
|
|
||||||
return pd.concat([winners, rest])
|
|
||||||
|
|
||||||
|
|
||||||
def parse_score(df, col):
|
|
||||||
'''
|
|
||||||
Шаг 1. Разобрать столбец со счётом вида "3:1" на два числовых столбца.
|
|
||||||
|
|
||||||
Принимает: df - таблица матчей; col - имя столбца ('Период_1', 'Овертайм' и т.п.).
|
|
||||||
Возвращает: (home, away) - два числовых столбца (Series): голы хозяев и голы гостей.
|
|
||||||
|
|
||||||
Как работает:
|
|
||||||
- str.split(':', expand=True) разбивает "3:1" на части "3" и "1" сразу по
|
|
||||||
всему столбцу и раскладывает их в два столбца (expand=True);
|
|
||||||
- pd.to_numeric(..., errors='coerce') превращает текст в число, а всё, что
|
|
||||||
числом не является (пустая строка при ":" или знаки "+ — -"), делает NaN;
|
|
||||||
- fillna(0) заменяет NaN на 0. Итог: не сыгранный период читается как "0:0".
|
|
||||||
'''
|
|
||||||
parts = df[col].str.split(':', expand=True)
|
|
||||||
home = pd.to_numeric(parts[0], errors='coerce').fillna(0)
|
|
||||||
away = pd.to_numeric(parts[1], errors='coerce').fillna(0)
|
|
||||||
return home, away
|
|
||||||
|
|
||||||
|
|
||||||
def build_standings(df, conf_map):
|
|
||||||
'''
|
|
||||||
Шаг 2. Превратить таблицу матчей в турнирную таблицу команд.
|
|
||||||
|
|
||||||
Принимает: df - матчи (одна строка = один матч); conf_map - словарь
|
|
||||||
{команда -> конференция} из make_conf.
|
|
||||||
Возвращает: таблицу (DataFrame), где индекс - название команды, а столбцы -
|
|
||||||
И, В, ВО, ВБ, ПБ, ПО, П, ГЗ, ГП, О, Р, %О, Конф; строки уже
|
|
||||||
отсортированы по правилам КХЛ (лучшая команда сверху).
|
|
||||||
|
|
||||||
Идея целиком:
|
|
||||||
1) разбираем счёт по периодам/овертайму/буллитам;
|
|
||||||
2) по каждому матчу определяем ОДИН из шести исходов для хозяев и для гостей
|
|
||||||
(победа в основное/овертайме/буллитах и зеркальные поражения);
|
|
||||||
3) отдельно учитываем технические результаты ("+ — -" / "- — +");
|
|
||||||
4) считаем заброшенные/пропущенные шайбы;
|
|
||||||
5) разносим каждый матч на две строки (взгляд хозяев и взгляд гостей),
|
|
||||||
склеиваем и группируем по команде - получаем суммы по сезону;
|
|
||||||
6) считаем производные показатели (И, О, Р, %О) и сортируем.
|
|
||||||
'''
|
|
||||||
# Достаём счёт по периодам и т.д.
|
|
||||||
h1, a1 = parse_score(df, 'Период_1') # голы хозяев/гостей в 1 периоде
|
|
||||||
h2, a2 = parse_score(df, 'Период_2') # второй
|
|
||||||
h3, a3 = parse_score(df, 'Период_3') # третий
|
|
||||||
oth, ota = parse_score(df, 'Овертайм') # овертайм (0/0, если его не было)
|
|
||||||
soh, soa = parse_score(df, 'Буллиты') # серия буллитов (0/0, если её не было)
|
|
||||||
|
|
||||||
# Голы в основное время (сумма трёх периодов), складываются поэлементно, строка к строке
|
|
||||||
reg_h = h1 + h2 + h3 # сколько хозяева забили за три периода
|
|
||||||
reg_a = a1 + a2 + a3 # сколько гости забили за три периода
|
|
||||||
|
|
||||||
# Определяем ТИП исхода каждого матча через сравнение столбцов
|
|
||||||
# (любое сравнение возвращает столбец False/True)
|
|
||||||
|
|
||||||
tie = (reg_h == reg_a) # True там, где после 3 периодов была ничья
|
|
||||||
|
|
||||||
win_home_reg = (reg_h > reg_a) # хозяева победили в основное время
|
|
||||||
win_away_reg = (reg_a > reg_h) # гости победили в основное время
|
|
||||||
|
|
||||||
win_home_ot = tie & (oth > ota) # ничья в основное + хозяева забили в ОТ = победа в ОТ
|
|
||||||
win_away_ot = tie & (ota > oth) # ничья в основное + гости забили в ОТ
|
|
||||||
|
|
||||||
win_home_so = tie & (oth == ota) & (soh > soa) # ОТ ничейный -> буллиты выиграли хозяева
|
|
||||||
win_away_so = tie & (oth == ota) & (soa > soh) # буллиты выиграли гости
|
|
||||||
|
|
||||||
'''
|
|
||||||
Технические результаты (неявка/отмена матча). В файле счёт записан не цифрами,
|
|
||||||
а знаками: "+ — -" - техническая победа хозяев, "- — +" - техническая победа гостей.
|
|
||||||
КХЛ засчитывает их как победу/поражение в основное время (2 и 0 очков), но шайбы
|
|
||||||
при этом НЕ начисляются (в графу Ш такой матч идёт как 0:0).
|
|
||||||
'''
|
|
||||||
p1 = df['Период_1'].astype(str).str.strip()
|
|
||||||
tech_home = p1.str.startswith('+') # техническая победа хозяев
|
|
||||||
tech_away = p1.str.endswith('+') # техническая победа гостей
|
|
||||||
tech = tech_home | tech_away
|
|
||||||
|
|
||||||
# Для технических матчей перекрываем обычную классификацию (там сейчас "ничья 0:0").
|
|
||||||
win_home_reg = (win_home_reg & ~tech) | tech_home
|
|
||||||
win_away_reg = (win_away_reg & ~tech) | tech_away
|
|
||||||
win_home_ot = win_home_ot & ~tech
|
|
||||||
win_away_ot = win_away_ot & ~tech
|
|
||||||
win_home_so = win_home_so & ~tech
|
|
||||||
win_away_so = win_away_so & ~tech
|
|
||||||
|
|
||||||
'''
|
|
||||||
Считаем заброшенные шайбы для итоговой таблицы.
|
|
||||||
К голам в основное время прибавляем голы овертайма, а победителю серии буллитов
|
|
||||||
добавляем ровно 1 решающую шайбу. astype(int) переводит True/False в 1/0.
|
|
||||||
'''
|
|
||||||
goals_home = reg_h + oth + win_home_so.astype(int) # все шайбы хозяев
|
|
||||||
goals_away = reg_a + ota + win_away_so.astype(int) # все шайбы гостей
|
|
||||||
|
|
||||||
'''
|
|
||||||
Конвертируем "по одной строке на матч" -> "по две строки на матч".
|
|
||||||
В каждом матче участвует 2 команды. Делаем две таблицы:
|
|
||||||
home - взгляд со стороны хозяев, away - со стороны гостей,
|
|
||||||
а потом склеиваем и группируем по названию команды.
|
|
||||||
Столбцы В, ВО, ВБ, ПБ, ПО, П - это булевы маски (выиграл/проиграл).
|
|
||||||
'''
|
|
||||||
home = pd.DataFrame({
|
|
||||||
'Команда': df['Команда_1'], # имя хозяев
|
|
||||||
'В': win_home_reg, # победа в основное время
|
|
||||||
'ВО': win_home_ot, # победа в овертайме
|
|
||||||
'ВБ': win_home_so, # победа по буллитам
|
|
||||||
'ПБ': win_away_so, # поражение по буллитам (гости выиграли буллиты)
|
|
||||||
'ПО': win_away_ot, # поражение в овертайме
|
|
||||||
'П': win_away_reg, # поражение в основное время
|
|
||||||
'ГЗ': goals_home, # голы, забитые хозяевами
|
|
||||||
'ГП': goals_away, # голы, пропущенные (забитые гостями)
|
|
||||||
})
|
|
||||||
away = pd.DataFrame({
|
|
||||||
'Команда': df['Команда_2'],
|
|
||||||
'В': win_away_reg,
|
|
||||||
'ВО': win_away_ot,
|
|
||||||
'ВБ': win_away_so,
|
|
||||||
'ПБ': win_home_so,
|
|
||||||
'ПО': win_home_ot,
|
|
||||||
'П': win_home_reg,
|
|
||||||
'ГЗ': goals_away,
|
|
||||||
'ГП': goals_home,
|
|
||||||
})
|
|
||||||
|
|
||||||
# pd.concat склеивает две таблицы одну под другой (как два списка матчей подряд).
|
|
||||||
# ignore_index=True перенумеровывает строки заново, чтобы номера не повторялись.
|
|
||||||
both = pd.concat([home, away], ignore_index=True)
|
|
||||||
|
|
||||||
# Булевы столбцы (True/False) переводим в числа (1/0), чтобы их можно было суммировать.
|
|
||||||
flag_cols = ['В', 'ВО', 'ВБ', 'ПБ', 'ПО', 'П']
|
|
||||||
both[flag_cols] = both[flag_cols].astype(int)
|
|
||||||
|
|
||||||
# Голы тоже переводим в целые числа (после fillna(0) они стали дробными).
|
|
||||||
both[['ГЗ', 'ГП']] = both[['ГЗ', 'ГП']].astype(int)
|
|
||||||
|
|
||||||
# Суммируем всё по каждой команде.
|
|
||||||
# groupby('Команда').sum() - сгруппируй строки по названию команды и сложи числа.
|
|
||||||
table = both.groupby('Команда').sum()
|
|
||||||
|
|
||||||
# Производные показатели:
|
|
||||||
|
|
||||||
# И - количество игр = сумма всех исходов (каждый матч - ровно один из шести исходов)
|
|
||||||
table['И'] = table[flag_cols].sum(axis=1) # axis=1 - складывать вдоль строки
|
|
||||||
# О - очки по системе КХЛ: любая победа = 2, поражение в ОТ/буллитах = 1, в осн. время = 0
|
|
||||||
table['О'] = 2 * (table['В'] + table['ВО'] + table['ВБ']) + (table['ПБ'] + table['ПО'])
|
|
||||||
# Р - разница шайб (дополнительный критерий при равенстве)
|
|
||||||
table['Р'] = table['ГЗ'] - table['ГП']
|
|
||||||
|
|
||||||
'''
|
|
||||||
%О - процент набранных очков = очки / максимально возможные (2 за каждую игру).
|
|
||||||
По этому проценту КХЛ расставляет места, когда команды сыграли разное число игр.
|
|
||||||
Сайт КХЛ НЕ округляет, а отбрасывает знаки после второго (72.448 -> 72.44),
|
|
||||||
поэтому считаем в целых числах: умножаем на 10000 и делим нацело (//) на 2*И -
|
|
||||||
остаток (дробная часть) отбрасывается, затем делим на 100. Целочисленная
|
|
||||||
арифметика без float, поэтому ровные значения (57.00) не съезжают в 56.99.
|
|
||||||
'''
|
|
||||||
table['%О'] = (table['О'] * 10000 // (2 * table['И'])) / 100
|
|
||||||
# Подписываем каждой команде её конференцию. .map(словарь) проходит по индексу
|
|
||||||
# (названиям команд) и подставляет значение из словаря.
|
|
||||||
table['Конф'] = pd.Series(table.index, index=table.index).map(conf_map)
|
|
||||||
|
|
||||||
'''
|
|
||||||
Сортировка: по проценту очков, затем при равенстве - больше побед в основное время,
|
|
||||||
затем в овертайме, затем по буллитам, затем лучше разница шайб, затем больше забито.
|
|
||||||
'''
|
|
||||||
table = table.sort_values(
|
|
||||||
by=['%О', 'В', 'ВО', 'ВБ', 'Р', 'ГЗ'],
|
|
||||||
ascending=False,
|
|
||||||
)
|
|
||||||
return table
|
|
||||||
|
|
||||||
|
|
||||||
def show_table(table, title):
|
|
||||||
'''
|
|
||||||
Напечатать турнирную таблицу в консоль в виде текста.
|
|
||||||
|
|
||||||
Принимает: table - готовая (уже отсортированная) таблица команд;
|
|
||||||
title - заголовок над таблицей.
|
|
||||||
Ничего не возвращает - только печатает.
|
|
||||||
|
|
||||||
Что делает: оставляет нужные столбцы в порядке, как на сайте КХЛ, добавляет
|
|
||||||
слева колонку "Место" (1..N по порядку строк) и колонку "Команда"
|
|
||||||
(название берётся из индекса таблицы), затем выводит всё через to_string.
|
|
||||||
'''
|
|
||||||
# Колонки в том же порядке и с теми же подписями, что на сайте КХЛ.
|
|
||||||
cols = ['И', 'В', 'ВО', 'ВБ', 'ПБ', 'ПО', 'П', 'ГЗ', 'ГП', 'Р', 'О', '%О']
|
|
||||||
view = table[cols].copy() # берём только нужные столбцы (копия, чтобы не трогать оригинал)
|
|
||||||
# Место по порядку строк. np.arange(1, N+1) создаёт массив [1..N].
|
|
||||||
view.insert(0, 'Место', np.arange(1, len(view) + 1))
|
|
||||||
# Имя команды (индекс таблицы) ставим отдельным столбцом, чтобы оно было видно при выводе.
|
|
||||||
view.insert(1, 'Команда', view.index)
|
|
||||||
|
|
||||||
print('\n' + '=' * 80)
|
|
||||||
print(title)
|
|
||||||
print('=' * 80)
|
|
||||||
print(view.to_string(index=False))
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
'''
|
|
||||||
Точка входа. Связывает все шаги вместе:
|
|
||||||
читает путь к CSV из аргумента командной строки -> по имени файла определяет
|
|
||||||
сезон -> строит таблицу через build_standings -> печатает общую таблицу и две
|
|
||||||
таблицы по конференциям (Запад/Восток), отфильтрованные по столбцу 'Конф'.
|
|
||||||
Для сезонов с правилом посева победители дивизионов поднимаются на места 1-2.
|
|
||||||
'''
|
|
||||||
path = sys.argv[1] # получаем путь до csv
|
|
||||||
name = os.path.basename(path) # из khl_3/khl_*.csv берём только khl_*.csv
|
|
||||||
season = name.replace('khl_', '').replace('.csv', '')
|
|
||||||
conf_map = CONFERENCES[season]
|
|
||||||
div_map = DIVISIONS[season]
|
|
||||||
|
|
||||||
df = pd.read_csv(path)
|
|
||||||
table = build_standings(df, conf_map)
|
|
||||||
table['Див'] = pd.Series(table.index, index=table.index).map(div_map)
|
|
||||||
|
|
||||||
# Итоговая таблица чемпионата
|
|
||||||
show_table(table, 'Итоговая таблица чемпионата ' + season)
|
|
||||||
|
|
||||||
# Итоговые таблицы по конференциям (фильтруем по столбцу Конф)
|
|
||||||
west = table[table['Конф'] == 'Запад']
|
|
||||||
east = table[table['Конф'] == 'Восток']
|
|
||||||
if SEED_BY_DIVISION[season]:
|
|
||||||
west = seed_conference(west)
|
|
||||||
east = seed_conference(east)
|
|
||||||
|
|
||||||
show_table(west, 'Конференция Запад ' + season)
|
|
||||||
show_table(east, 'Конференция Восток ' + season)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Loading…
Reference in a new issue