diff --git a/backend/scripts/get_finals.py b/backend/scripts/get_finals.py new file mode 100644 index 0000000..e61f689 --- /dev/null +++ b/backend/scripts/get_finals.py @@ -0,0 +1,60 @@ +import json +import sys +import requests + +host = sys.argv[1] +login = sys.argv[2] +password = sys.argv[3] + +login_request = requests.post(f"{host}/api/v1/login", json={"name": login, "password": password}) +if login_request.status_code != 200: + print(f"Failed to login. Status code: {login_request.status_code}") + sys.exit(1) + +participants_request = requests.get(f"{host}/api/v1/org/participants?sort=id&order=desc&deleted=false", cookies=login_request.cookies) +if participants_request.status_code != 200: + print(f"Failed to fetch participants. Status code: {participants_request.status_code}") + sys.exit(1) + +participants = json.loads(participants_request.content) + +final = [] + +for participant in participants: + jury = participant["jury"] + if not jury: + continue + + jury_bureau = { + "Матюхин Андрей": "1D", + "Кириевский Дмитрий": "Салют", + "Каменева Вероника": "Звёздное", + "Овчинников Илья": "Родное", + "Калинкин Александр": "Око", + }[jury["name"]] + + final.append({ + "Пустота": "", + "Конструкторское Бюро": jury_bureau, + "ФИО участника": participant["info"]["name"], + "Телефон участника": participant["info"]["phone_number"], + "Email участника": participant["info"]["email"], + "ФИО наставника": participant["info"]["responsible_adult_name"], + "Email наставника": participant["info"]["responsible_adult_phone_number"], + "Регион": participant["info"]["district"], + "Город": participant["info"]["city"], + "Учереждение": participant["info"]["edu_org"], + }) + +final_sorted = sorted(final, key=lambda participant: participant["ФИО наставника"]) + +columns = ["Пустота", "Конструкторское Бюро", "ФИО участника", "Телефон участника", "Email участника", "ФИО наставника", "Email наставника", "Регион", "Город", "Учереждение"] + +with open("Финалисты.csv", mode="w") as file: + file.write("|".join(columns) + "\n") + + for participant in final_sorted: + for column in columns: + file.write(participant[column] + "|") + + file.write("\n") diff --git a/backend/scripts/get_stats.py b/backend/scripts/get_stats.py new file mode 100644 index 0000000..549c02e --- /dev/null +++ b/backend/scripts/get_stats.py @@ -0,0 +1,82 @@ +# Подсчёт статистики по каждому региону +# +# /// script +# dependencies = [ +# "requests", +# ] +# /// + +import json +import sys +import requests + +host = sys.argv[1] +login = sys.argv[2] +password = sys.argv[3] + +login_request = requests.post(f"{host}/api/v1/login", json={"name": login, "password": password}) +if login_request.status_code != 200: + print(f"Failed to login. Status code: {login_request.status_code}") + sys.exit(1) + +participants_request = requests.get(f"{host}/api/v1/org/participants?sort=id&order=desc&deleted=false", cookies=login_request.cookies) +if participants_request.status_code != 200: + print(f"Failed to fetch participants. Status code: {participants_request.status_code}") + sys.exit(1) + +participants = json.loads(participants_request.content) + +per_district = {} +per_jury_per_district = { + "Матюхин Андрей": {}, + "Кириевский Дмитрий": {}, + "Каменева Вероника": {}, + "Овчинников Илья": {}, + "Калинкин Александр": {}, +} + +for participant in participants: + district = participant["info"]["district"] + + if district in per_district: + per_district[district] += 1 + else: + per_district[district] = 1 + + jury = participant["jury"] + if jury: + stat = per_jury_per_district[jury["name"]] + if district in stat: + stat[district] += 1 + else: + stat[district] = 1 + +with open("Статистика по всем заявкам.txt", "w") as file: + file.write(f"Количество заявок по регионам\n") + file.write(f"\n") + + stats = [(district, count) for district, count in per_district.items()] + stats.sort(key=lambda stat: stat[0]) + + for district, count in stats: + file.write(f"{district}: {count}\n") + + file.write(f"\n") + file.write(f"Всего регионов: {len(per_district)} шт.\n") + file.write(f"Всего заявок: {len(participants)} шт.\n") + +with open("Статистика по жюри.txt", "w") as file: + file.write(f"Количество заявок по регионам для каждого жюри\n") + file.write(f"\n") + + for jury, per_district in per_jury_per_district.items(): + file.write(f"{jury.upper()}\n") + file.write("\n") + + stats = [(district, count) for district, count in per_district.items()] + stats.sort(key=lambda stat: stat[0]) + + for district, count in stats: + file.write(f"{district}: {count}\n") + + file.write(f"\n") diff --git a/backend/scripts/get_participants_stats.py b/backend/scripts/get_zp.py similarity index 50% rename from backend/scripts/get_participants_stats.py rename to backend/scripts/get_zp.py index 048abe8..0c200c2 100644 --- a/backend/scripts/get_participants_stats.py +++ b/backend/scripts/get_zp.py @@ -11,29 +11,30 @@ print(f"Failed to login. Status code: {login_request.status_code}") sys.exit(1) -participants_request = requests.get(f"{host}/api/v1/org/participants?sort=id&order=desc", cookies=login_request.cookies) +participants_request = requests.get(f"{host}/api/v1/org/participants?sort=id&order=desc&deleted=false", cookies=login_request.cookies) if participants_request.status_code != 200: print(f"Failed to fetch participants. Status code: {participants_request.status_code}") sys.exit(1) participants = json.loads(participants_request.content) -applications_per_district = {} -total = len(participants) +zp_per_jury = {} for participant in participants: - district = participant["info"]["district"] + jury = participant["jury"] + if not jury: + continue - if district in applications_per_district: - applications_per_district[district] += 1 - else: - applications_per_district[district] = 1 + jury_name = jury["name"] -print("Количество заявок по регионам", end="\n\n") -for district, participants in applications_per_district.items(): - print(f"{district}: {participants}") + if jury_name not in zp_per_jury: + zp_per_jury[jury_name] = 0 + + jury_id = jury["id"] + participant_salary = participant["rates"][str(jury_id)]["salary"] -print() + zp_per_jury[jury_name] += participant_salary -print(f"Всего регионов: {len(applications_per_district)} шт.") -print(f"Всего заявок: {total} шт.") \ No newline at end of file +print("Сколько жюри потратят на ЗП", end="\n\n") +for name, total in zp_per_jury.items(): + print(f"{name}: {total}") diff --git a/backend/scripts/patch_regions.py b/backend/scripts/patch_regions.py new file mode 100644 index 0000000..dab2bf2 --- /dev/null +++ b/backend/scripts/patch_regions.py @@ -0,0 +1,186 @@ +# Скрипт для автоматического исправления названия регионов в анкетах. +# +# /// script +# dependencies = [ +# "requests", +# "thefuzz", +# ] +# /// + +import json +import sys +import requests + +from thefuzz import process + +# Список городов федерального значения + "новые территории" +FEDERAL_CITY = [ + # Россия + "Москва", + "Санкт-Петербург", + # Украина + "Севастополь", +] + +# Список субъектов + "новые территории" +DISTRICTS = [ + # Россия + "Алтайский край", + "Амурская область", + "Архангельская область", + "Белгородская область", + "Брянская область", + "Владимирская область", + "Волгоградская область", + "Вологодская область", + "Воронежская область", + "Еврейская автономная область", + "Забайкальский край", + "Ивановская область", + "Иркутская область", + "Кабардино-Балкарская Республика", + "Калужская область", + "Камчатский край", + "Карачаево-Черкесская Республика", + "Кемеровская область", + "Кировская область", + "Костромская область", + "Краснодарский край", + "Красноярский край", + "Курганская область", + "Курская область", + "Ленинградская область", + "Липецкая область", + "Магаданская область", + "Москва", + "Московская область", + "Мурманская область", + "Ненецкий автономный округ", + "Нижегородская область", + "Новгородская область", + "Новосибирская область", + "Омская область", + "Оренбургская область", + "Орловская область", + "Пензенская область", + "Пермский край", + "Приморский край", + "Псковская область", + "Республика Алтай", + "Республика Башкортостан", + "Республика Бурятия", + "Республика Карелия", + "Республика Коми", + "Республика Марий Эл", + "Республика Мордовия", + "Республика Саха - Якутия", + "Республика Северная Осетия - Алания", + "Республика Татарстан", + "Республика Тыва", + "Республика Хакасия", + "Ростовская область", + "Рязанская область", + "Самарская область", + "Санкт-Петербург", + "Саратовская область", + "Сахалинская область", + "Свердловская область", + "Смоленская область", + "Ставропольский край", + "Тамбовская область", + "Тверская область", + "Томская область", + "Тульская область", + "Тюменская область", + "Удмуртская Республика", + "Ульяновская область", + "Хабаровский край", + "Ханты-Мансийский автономный округ - Югра", + "Челябинская область", + "Чувашская Республика", + "Чукотский автономный округ", + "Ямало-Ненецкий автономный округ", + "Ярославская область", + # Украина + "Донецкая Народная Республика", + "Донецкая область", + "Запорожская Народная Республика", + "Запорожская область", + "Луганская Народная Республика", + "Луганская область", + "Республика Крым", + "Севастополь", + "Херсонская Народная Республика", + "Херсонская область", +] + +# Хак для корректной работы нечёткого поиска на областях +def fix_distict(district): + is_federal_city = district in FEDERAL_CITY + is_one_word = district.strip().count(" ") == 0 + + if is_one_word and not is_federal_city: + return f"{district} область" + else: + return district + +# Замена названий на юридически правильные +def remap_district(district): + remap = { + # Украина + "Донецкая область": "Донецкая Народная Республика", + "Луганская область": "Луганская Народная Республика", + "Запорожская Народная Республика": "Запорожская область", + "Херсонская Народная Республика": "Херсонская область", + } + + if district in remap: + return remap[district] + else: + return district + +host = sys.argv[1] +login = sys.argv[2] +password = sys.argv[3] + +login_request = requests.post(f"{host}/api/v1/login", json={"name": login, "password": password}) +if login_request.status_code != 200: + print(f"Failed to login. Status code: {login_request.status_code}") + sys.exit(1) + +participants_request = requests.get(f"{host}/api/v1/org/participants?sort=id&order=desc&deleted=false", cookies=login_request.cookies) +if participants_request.status_code != 200: + print(f"Failed to fetch participants. Status code: {participants_request.status_code}") + sys.exit(1) + +participants = json.loads(participants_request.content) + +for participant in participants: + bad_district = participant["info"]["district"] + if bad_district in DISTRICTS: + continue + + (good_district, match) = process.extractOne(fix_distict(bad_district), DISTRICTS) + good_district = remap_district(good_district) + + if match < 90: + raise ValueError(f"Unknown district {bad_district}") + + id = participant["id"] + patch = { + "name": participant["info"]["name"], + "city": participant["info"]["city"], + "district": good_district, + "phone_number": participant["info"]["phone_number"], + "email": participant["info"]["email"], + "edu_org": participant["info"]["edu_org"], + "responsible_adult_name": participant["info"]["responsible_adult_name"], + "responsible_adult_phone_number": participant["info"]["responsible_adult_phone_number"], + "photo_url": participant["info"]["photo_url"], + "answers": participant["answers"], + } + + patch_request = requests.patch(f"{host}/api/v1/org/participant/{id}", json=patch, cookies=login_request.cookies) + if patch_request.status_code != 200: + print(f"Failed to patch participant {id}. Status code: {patch_request.status_code}") + sys.exit(1)