11 марта 2018 г. в 23:59
Немного графиков про графики

Многие помнят о графиках, показывающих фальсификации на российских выборах 2011-2012-х годов, так вот, после просмотра замечательного эфира программы Облако про математику выборов, с Сергеем Шпилькиным в гостях, мне захотелось это повторить, но только в пределах своей, Белгородской области.

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

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

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

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

При выборе технологий возник большой вопрос: так как посмотреть статистику по своему городу может быть интересно многим, но при этом недостаточно интересно, чтобы устанавливать приложение, необходимо делать web приложение. А раз web, то писать тонны джаваскрипта? Нет уж, увольте.

К счастью, нашёл библиотеку Dash для Python, который позволяет html страницу и логику описать на Python, а страница будет сама сформирована, с использованием ReactJS. Страница составляется из готовых блоков, если их не хватает, можно и свои добавить. Dash предоставляет реактивный декоратор для управления данными страницы в стиле событий: например, меняется значение в поле, это приводит к вызову привязанной функции, которая какой-то вычисленный результат возвращает, скажем, в заголовок. В итоге, из собственноручно написанного js кода там присутствует только всплывающее окно с помощью по использованию сервиса.

Также следовало выбрать, какую базу данных использовать. Пока мы живём не в Северной Корее, в каждых выборах меняются кандидаты, а как следствие, и столбцы в базе данных. Создавать по собственной таблице в MySQL для каждых выборов? Возможно, и имело смысл, пренебрежа и повторением названием названий городов, номеров и адресов УИКов в каждой таблице, или как-то хитро их выносить в отдельную таблицу и всё это не менее хитро объёдинять при выводе, но решил попробовать NoSQL решение MongoDB, о которой так много слышал восторженных гласов, о чём и не жадею.

Как минимум, в случае использования MySQL пришлось бы искать хороший ORM, ведь вручную работать с БД не особо хочется, а MongoDB предоставляет интерфейс управления, до которому любому ORM ещё расти и расти. Но вообще понравился подход, в котором не нужно заморачиваться со столбцами, и приводить структуру к третьей нормальной форме - напротив, здесь рекомендуется дублирование информации в каких-то случаях, где благодаря этому удобнее работать с базой данных.

Вобщем так я за полтора месяца создал сервис, который делает всё, что я хотел - можно посмотреть результаты на участках любой территори для любых (пока доступны 3) выборах, формируются 3 наиболее важных графика зависимости различных параметров от явки и даже показываются адреса УИКов. Адреса я парсил не сам, а воспользовался готовой базой данных, которую выкачали ребята с GIS-Lab. Исходники я выложил на gitlab, только там слегка устаревшая версия - обновлю в ближайшее время, нужно исправить метод хранения данных о результатах выборов, т.к. вручную я это сделал и web приложение с этим работает, а парсер пока сохраняет в устаревшем виде.

На днях выложил сервис на сервере, по адресу cikinfo.modos189.ru, а сегодня я накатил обновление, где внес изменения в дизайне, чтобы всё выглядело понятно и красиво, исправил небольшие баги и добавил окно с помощью по использованию сайта, ибо по первым тестам заметил, что стороннему человеку сперва не совсем понятно, как всем этим пользоваться.

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

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

Жаль только, что пакет unattended-upgrades, который должен был бороться со злом, решил примкнуть к нему и удалил мне один из пакетов php, который был ответственен за графику, из-за чего мой блог некоторое время лежал, но уже всё работает и я не волнуюсь, что сервис без проблем выдержит и тысячи одновременных подключений.

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

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

Также я опубликовал подробную статью с анализом выборов на хабре, рекомендую заглянуть и туда, чекнуть комментарии, они весьма полезные: Анализ результатов президентских выборов 2018 года. На федеральном и региональном уровне