Обработка данных в формате CSV

Вам предлагаются для обработки различные данные в формате CSV. Данные представляют собой текстовый файл, каждая строка которых содержит некоторое количество данных, разделённых одинаковым символом. Аббревиатура CSV обозначает Comma-Separated Values, однако в качестве разделителя будет использоваться другой символ.

В каждой задаче вы можете читать данные либо из файла data.csv, либо со стандартного ввода. Программа должна вывести результат либо в файл output.txt, либо на стандартный вывод.

CSV-данные на сайте data.mos.ru записаны в кодировке Windows-1251, но в тестирующей системе этот же файл будет сконвертирован в кодировку UTF-8.

Вы можете скачать файл с данными и сконвертировать его на своём компьютере из кодировки Windows-1251 в кодировку UTF-8, либо осуществлять перекодировку средствами языка Python при открытии файла, в этом случае в функцию open нужно передать параметр encoding="cp1251". При сдаче задачи в тестирующую систему этот параметр нужно убрать.

Кроме того, если вы используете в программе текстовые строки, записанные на русском языке, то сам файл с программой должен быть сохранён в кодировке UTF-8 (по умолчанию Wing IDE может сохранять файлы в кодировке CP-1251). Для этого в первой строке файла программы на языке Python следует установить кодировку самого файла с программой:

# -*- coding: utf-8 -*-

A: Ejudge: статистика по языкам программирования

Изучите файл с экспортом сданных решений в ejudge, контест проводится в формате личной олимпиады. Интересные для вас поля в этом файле:
User_Id — уникальный числовой идентификатор пользователя.
User_Login — уникальный логин пользователя (также можно использовать, как уникальный числовой идентификатор).
User_Inv — у скрытого пользователя в этом поле записан символ "I".
Lang — идентификатор языка программирования.
Score — Количество баллов, полученных за задачу.

Посчитайте общее число участников контеста, а также то, сколько участников использовало тот или иной язык программирования. Будем считать, что участник использует язык программирования, если он сдал хотя бы одно решение, набравшее больше 0 баллов. Скрытых пользователей учитывать не нужно.

Выведите общее число пользователей (Total) в первой строке, считаются только участники, сдавшие хотя бы одну задачу на ненулевой балл.

В последующий строках выведите все использованные языки программирования, после слова Total или названия языка программирования через двоеточие и пробел выведите число участников. Список упорядочите по убыванию числа участников, использующих данный язык программирования, при равных значениях — в лексикографическом порядка названия языка программирования.

Пример результата работы программы для данного файла:

Total: 19
python3: 19
g++: 5

B: Ejudge: результаты личной олимпиады

Вам понадобятся также следующие поля:
User_Name — имя пользователя в таблице результатов
Prob — идентификатор задачи (произвольная строка).

По каждой задаче пользователь получает балл, равный максимальному числу баллов из всех сабмитов по этой задаче. Сумма баллов, набранных участником, равна сумме баллов за все задачи.

Для каждого участника посчитайте сумму баллов, которые он набрал по всем задачам. Упорядочите участников по убыванию суммы баллов, при равной сумме баллов — в лексикографическом порядке поля User_Name. Выведите упорядоченный список: сначала имя пользователя, потом через двоеточие и пробел — его баллы.

Решения, имеющие статус Compilation error имеют значение поля Score равное -1, эти решения учитывать не нужно (их балл равен 0).

Eсли все решения участника набрали 0 баллов, то участник тоже участвовал в олимпиаде и его результат тоже нужно выводить.

Имена участников могут совпадать (привет Александрам Некрасовым), идентифицировать участников нужно по логину или id, но выводить нужно имена.

Пример результата работы программы для данного файла:

[9В] Порфирьев Антон: 400
[7Б] Сергиенко Дмитрий: 366
[9В] Павлек Николай: 363
[9Д] Миронов Сергей: 362
[9В] Смирнягин Артем: 359
[7Б] Бурков Илья: 358
[9В] Овчинников Андрей: 356
[9В] Фирсов Федор: 351
[9В] Севастьянова Александра: 331
[7Б] Орехов Савва: 330
[9В] Калабай Михаил: 330
[9В] Кирьяков Сергей: 330
[9В] Осипов Григорий: 330
[9В] Бархварт Максим: 321
[8В] Болгов Михаил: 320
[9В] Ингман Глеб: 320
[9В] Сутый Дмитрий: 320
[9В] Рылин Илья: 318
[8В] Черных Владимир: 308

C: Ejudge: результаты командной олимпиады

Изучите файл с экспортом сданных решений в ejudge, контест проводится в формате командной олимпиады. Интересные для вас поля в этом файле:
Stat_Short — равен OK, если решение прошло все тесты.
Dur — время сдачи в секундах решения от начала тура. Также вместо поля Dur можно использовать поля Dur_Hour и Dur_Min, равных количеству прошедших с начала тура часов и минут.

По правилам командной олимпиады команды ранжируются по убьванию числа решённых задач. При равном числе решённых задач команды ранжируются по возрастанию штрафного времени. Штрафное время по задаче равно времени, в которой было сдано решение этой задачи на OK, измеряемое в минутах от начала тура, плюс 20 штрафных минут за каждую неудачную попытку сдать решение этой задачи. Например, если команда сделала 2 неудачные попытки по задаче, и после этого сдала решение на OK через 1 час 5 минут 30 секунд после начала тура, то команда получает \(65 + 2\times 20=105\) штрафных минут. Значение поля Dur у удачной попытки будет равно \(1\times 3600 + 5\times 60 + 30=3930\), Dur_Hour будет равно 1, Dur_Min будет равно 5.

Штрафные баллы не начисляются за задачи, которые в итоге не были сданы на OK, а также штрафные баллы не начисляются за решения, отправленные после того, как был получен OK по данной задаче. Также в Москве на школьных соревнованиях не учитываются решения, имеющие статус “Ошибка компиляции”, у них значение поля Stat_Short равно CE.

Выведите таблицу результатов командной олимпиады в формате название команды, затем через двоеточие и пробел — число решённых задач и, через пробел, штрафные баллы. Список должен быть упорядочен по убыванию числа решённых задач, затем по возрастанию штрафного балла, затем по названию команды.

Пример результата работы программы для данного файла:

42: Борис, (Гурциева B', Белова B', Воробьева B'): 9 785
28: Ядреный Хренодер (Смирнов B', Капленков C, Подопросветов C): 9 1023
39: Easy Win (Самбуров B', Оспенников B', Чахвадзе B'): 8 917
34: No money — no honey (Неверова C, Олемская C, Федорова C): 7 496
35: #Альтернатива# (Копаева C, Плюшкин C, Мустафин C): 7 669
26: Новогодний дуб (Винокуров C', Гусев C', Соколов C'): 7 726
31: ОАО «Мозгострах» (Карбушев B', Привалихин B', Труфанов B'): 7 838
36: Нет идей (Фадеева C', Серикова C', Власова C'): 7 857
38: nyan pony (Сидоров B', Зверева B', Николаев B'): 7 863
41: Дружба — это магия (Сахабиев C', Хайруллин C', Поляков C'): 7 1004
30: Трое на кухне (Воронцова B', Савон B', Иглина B'): 6 375
44: Лама (Жуковская C, Цаплин B', Русина C): 6 464
27: 12348 (Начкин C', Алехина C', Якунчева C'): 6 555
37: Чапельник (Чистопольская C, Минеева B', Дженжер C): 6 573
33: Cone Forest (Алфёров C, Шалимова С, Казаков C): 6 587
32: Тётки (с) (Романова C', Ерохина C', Ерохина C'): 6 815
29: python++ (Кириллов C, Амиров C, Аникушин C): 6 1025
43: Двое против всех (Морозов C', Анопренко C'): 5 190
40: PENTAGRAM (Янцевич C, Соломатин C, Амиров C): 4 444

D: Городской Wi-Fi

Изучите данные о городском Wi-Fi, ссылка на архив с данными.

CSV-данные на сайте data.mos.ru записаны в кодировке Windows-1251, но в тестирующей системе этот же файл будет сконвертирован в кодировку UTF-8.

Вы можете скачать файл с данными и сконвертировать его на своём компьютере из кодировки Windows-1251 в кодировку UTF-8, либо осуществлять перекодировку средствами языка Python при открытии файла, в этом случае в функцию open нужно передать параметр encoding="cp1251". При сдаче задачи в тестирующую систему этот параметр нужно убрать.

Также обратите внимание, что все значения полей в этом файле заключены в кавычки.

Посчитайте для каждого района Москвы количество точек доступа в этом районе. Упорядочите список по убыванию количества точек доступа, при равном значении — в лексикографическом порядке названия района. Выведите полученный список, отделяя название района от числа точек доступа двоеточием и пробелом.

Начальная часть ответа выглядит так:

Тверской район: 480
район Хамовники: 386
Пресненский район: 349
Басманный район: 343
район Замоскворечье: 308

E: Призёры регионального этапа всероссийской олимпиады в 2017/2018 году

В следующих задачах мы будем изучать интересные сведения, которые можно скачать с сайта data.mos.ru.

В этой задаче нужно обработать набор данных “Победители олимпиад” из раздела “Образование”. Прямая ссылка на zip-архив с данными.

Вам необходимо посчитать для каждой московской школы количество победителей и призёров регионального этапа всероссийской олимпиады школьников в 2017/18 году (региональный этап — это третий этап всероссийской олимпиады).

Необходимо вывести список всех школы Москвы в формате: краткое название школы, затем через двоеточие и пробел количество победителей регионального этапа из этой школы, количество призёров регионального этапа, через пробел.

Список упорядочен по убыванию суммарного числа победителей и призёров, затем по числу победителей, затем по названию школы.

Начало списка выглядит так:

НИУ ВШЭ. лицей: 27 189
Московский государственный университет имени М.В. Ломоносова, МГУ имени М.В. Ломоносова, Московский университет или МГУ: 38 176
ГБОУ школа № 179: 33 164
ГБОУ школа № 1535: 32 157
ГБОУ лицей «Вторая школа»: 33 151

F: Предметы московской олимпиады

Определите, по каким предметам проводится московская олимпиада. Для каждого предмета выведите его название, и сколько лет (начиная с 2012/2013 учебного года) проводится олимпиада по этому предмету.

Выведите список предметов в алфавитном порядке, затем через двоеточие и пробел, количество лет проведения.

Начало списка выглядит так:

Биология: 6
География: 6
Изобразительное искусство: 6
Иностранный язык (испанский язык): 3

G: «Качество» призёров регионального этапа

Посчитайте для каждой школы коэффициент “качества” призёров регионального этапа: отношение числа победителей и призёров заключительного этапа этой школы к числу победителей и призёров регионального этапа. Учитывается только 2017/2018 учебный год, только те школы, в которых ненулевое число победителей и призёров регионального этапа и ненулевое число победителей и призеров заключительного этапа.

Упорядочите полученный список по отношению числа победителей и призёров заключительного этапа к числу победителей и призеров регионального этапа, при равном значении — в лексикографическом порядке краткого названия школы. Выведите краткое название школы, затем двоеточие и пробел, затем разделяя пробелами число победителей и призёров регионального этапа, число победителей и призёров заключительного этапа, отношение.

Понятно, что при такой оценке “качества” порядок школ окажется довольно странным. Вот начало полученного списка:

ГБОУ «Школа № 2100»: 1 1 1.0
ГБОУ школа № 2072: 1 1 1.0
ГБОУ школа № 2088: 1 1 1.0
ГБОУ школа № 875: 1 1 1.0
ГБОУ школа № 1324: 4 3 0.75

H: Мужские имена - убрать лишние концы строк

Изучите набор данных “Сведения о наиболее популярных мужских именах среди новорожденных” из раздела “справочная информация”. Архив с данными.

В этом файле собрана статистика с января 2015 по сентябрь 2018 года, для каждого месяца приведено 100 наиболее популярных мужских имён.

Этот файл плохо пригоден для обработки, поэтому задача будет решаться в несколько шагов. Прежде всего обратите внимание, что в некоторых записях после имени идёт символ конца строки до закрывающей кавычки. Устраните эту проблему. Больше никакой корректировки данных делать не нужно.

Для каждого имени посчитайте суммарное число новорождённых по этим данным. Упорядочите список имен по убыванию числа детей, а при равных значениях — по имени в лексикографическом порядке.

Выведите полученный список в формате: имя, через двоеточие и пробел — количество детей.

I: Мужские имена - убрать дубликаты

Обратите внимание на то, что некоторые записи содержат такое “имя”, как “Даниил, Данила, Данил”. То есть в некоторых случаях эти имена считаются раздельно, а в некоторых — вместе, и в этом случае невозможно установить статистику по каждому из этих имён. Давайте считать, что все три варианта имени “Даниил”, “Данила”, “Данил” являются одним и тем же именем “Даниил”, которое указано первым в списке.

Вам необходимо установить все случаи, когда в именах встречаются запятые. Если в имени встречается запятая, то это означает, что перечислены разные варианты одного и того же имени. Канонической формой считается форма, которая указана первой. Во всех данных необходимо осуществить замену всех вариантов имени на каноническую форму (в том числе тех вариантов, где имена перечислены через запятую). Необходимо осуществить замену дублирующихся имён на каноническую форму и посчитать статистику после этого.

J: Мужские имена - wat?!

Ввиду того, что первые сдавшие это задание уже всем рассказали, это задание больше не принимается.

Найдите странное имя, которое начинается со строчной буквы. Вероятно, это ошибка человека, который не умеет копировать данные между разными файлами и источниками данных, и вбивал информацию руками. Исправьте эту ошибку, учтите это в программе, которая обрабатывает данные.

K: Мужские имена - среднее значение

Посчитайте для каждого имени среднее число раз, которое это имя даётся новорожденному в месяц.

При этом поскольку за каждый месяц дана статистика только по 100 именам, то по многим именам, которые не каждый месяц попадают в Top-100, есть данные не по всем месяцам. По таким именам нужно считать среднее, как число детей, делённое на количество месяцев, по котором есть статистика.

Обратите внимание, что в результате дублирования одной формы написания имени, может быть так, что в одном месяце одно и то же имя в разных формах повторяется несколько раз.

Результат деления округлите до целого числа вниз. Выведите полученный список в таком же формате, как в предыдущих задачах.

L: Мужские имена - динамика по времени

Посчитайте, как меняется популярность имени со временем. Сравните среднемесячную частоту появления каждого имени в 2015 и в 2018 году и посчитайте разницу — насколько изменилось среднемесячное число новорождённых с этим именем в 2018 году по сравнению с 2015 годом.

Необходимо учитывать только те имена, которые встречались хотя бы раз в 2015 и 2018 году. Среднемесячное число появлений имени считается, как в предыдущей задаче (среднее по месяцам, с учётом того, что данные по конкретному имени есть не по всем месяцам, деление с округлением вниз, обратите внимание, что за 2018 год данные приведены только за 9 месяцев).

Выведите для каждого имени его среднемесячное число появлений в 2015 году, в 2018 году, разницу этих величин. Упорядочите список по убыванию разницы, при равном значении — по имени.

Начало списка выглядит так:

Лев: 80 108 28
Мирон: 36 61 25
Марк: 100 118 18
Мухаммад: 15 27 12
Амир: 27 37 10

M: Призёры регионального этапа всероссийской олимпиады за три года

Определите школы, в которых было наибольшее число победителей и призёров регионального этапа всероссийской олимпиады за три последних учебных года (начиная с 2015/2016 учебного года). Вам нужно найти пять школ, в которых за три года число победителей и призёров было наибольшим.

Сложность этой задачи в том, что названия некоторых школ за это время изменились. Вам необходимо установить, как менялись названия у разных школ за это время.

Программа должна вывести пять строк, формат вывода аналогичен предыдущей задаче. Название школы должно быть выведено таким, каким оно было в 2017/2018 учебном году. Выводимое число победителей и призёров должно быть равно числу победителей и призёров за три учебных года: 2015/2016, 2016/2017, 2017/2018. Список должен быть упорядочен по убыванию суммы победителей и призёров.

Вам нужно сначала установить, как менялись названия школ. Таблицу переименования школ можно непосредственно указать в исходном коде решения, однако количество победителей и призёров должно считаться автоматически на основании исходных данных.

Первая строка полученного списка должна выглядеть так:

Московский государственный университет имени М.В. Ломоносова, МГУ имени М.В. Ломоносова, Московский университет или МГУ: 84 537

N: Ближайшая точка доступа к школе

Найдите ближайшую к школе № 179 точку доступа городского Wi-Fi. Программа должна вывести в первой строке адрес этой точки доступа, во второй строке — расстояние до этой точки доступа в метрах.

Для данных на data.mos.ru программа должна вывести следующий результат:

город Москва, Камергерский переулок, дом 4, строение 1
68.41241881965709

Возможно, что программа будет находить не эту точку доступа, а какую-то другую, но тоже близко расположенную (например, в Георгиевском переулке или на Большой Дмитровке).