Разработка информационной системы анализа турнирных результатов спортсменов

История возникновения и анализ передовых цифровых технологий. Системы оценивания участников на соревновании. Проектирование платформы для аналитики турнирных результатов. Разработка архитектуры и графического интерфейса. Реализация базы данных на сервере.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 14.07.2020
Размер файла 4,4 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

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

Рисунок 3.9 Прототип экрана со статистикой выступления спортсменов

На данном экране представлены лишь некоторые возможные показатели статистики:

· Среднее количество рейтинговых очков, идущих в общий зачет;

· Танец программы, который лучше всего оценивается судьями на соревновании;

· Наиболее частый раунд, до которого доходят спортсмены на соревнованиях определённой квалификации;

· График рейтинговых очков за последние турниры;

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

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

Рисунок 3.10 График последних турниров и рейтинговых очков спортсменов

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

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

3.7 Методы монетизации

Еще одним важным аспектом в проектировании системы является определение методов монетизации. В разрабатываемой системе предполагается два способа монетизации:

· Предоставление полного функционала по подписке;

· Промежуточная реклама для обычных пользователей;

Первый вариант монетизации подразумевает под собой реализацию в системе ограниченного функционала, который будет доступен всем пользователям сервиса, и более широкого функционала, доступного по подписке. К базовому функционалу можно отнести выведение удобных для восприятия таблиц с оценками каждого члена жюри на конкретном турнире и отслеживание динамики изменения позиции в общем рейтинге участников. Эти функции будут наиболее востребованы всеми пользователями, исходя из данных проведенного ранее анкетирования. Весь остальной функционал системы будет доступен только тем пользователям, которые оплатили подписку (месяц, 6 месяцев, 12 месяцев). Оплата подписки производится с помощью сервисов, предоставляющих проведение автоматизированных платежей - Яндекс.Касса, Free-Kassa, AnyPay и др. Данные сервисы включают в себя комиссию с проведения платежей, которую можно настроить на самого пользователя, который производит оплату. Этот способ взимания платежей можно реализовать на стороне клиента, который представлен веб-сайтом. Для мобильных платформ доступна оплата непосредственно через внутренние сервисы определенной платформы (Apple Pay для IOS и Google Pay для Android).

Вторым методом монетизации является предоставление пользователям полноэкранной промежуточной рекламы. Такие экраны с рекламой будут показываться пользователям каждый раз, когда они заходят в сервис аналитики. Одним из сервисов, предоставляемых возможность для реализации такого способа монетизации, является AdMob by Google [33]. Данный сервис обладает обширным количеством рекламодателей, качественной аналитикой для принятия решений и умными технологиями для повышения дохода. Помимо этого, AdMob предоставляет возможность для интегрирования автоматизированных решений, которые являются легко настраиваемыми и позволяют упростить решение повседневных задач.

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

Глава 4. Разработка прототипа

Для удобства визуализации представления функционала было разработано автоматизированное приложение на платформе Telegram в виде чат-бота с реализованным базовым функционалом проектируемой информационной системы. Выбор данной платформы обусловлен предоставление кроссплатформенного доступа со всех возможных мобильных и компьютерных операционных систем и простотой реализации.

Создание бота на платформе реализовано с помощью интерфейса Telegram через запрос к боту @BotFather на создание нового бота. Таким образом был создан бот, который можно найти в Telegram по названию @wdsf_statBot. При создании разработчику выдается уникальный токен, который потом используется на стороне платформы, чтобы определять от кого приходит запрос. Для взаимодействия с «Telegram Bot API» была использованная общедоступная библиотека «Telepot» [34], которая содержит удобный набор методов для реализации взаимодействия. Чтобы реализовать постоянный доступ к системе, использовался бесплатный хостинг pythonanywhere.com [8], который предоставляет возможность размещать программный код, разработанный на языке Python [10], на сервере в виде веб-сайта, который может принимать, обрабатывать запросы и отвечать пользователю. Все операции и функционал системы имплементированы непосредственно на самом хостинге, где реализована база данных MySQL [9], где хранится вся информация, полученная с официального источника.

Разработанная в итоге система является минимально жизнеспособным продуктом (MVP), обладающим минимальным, но достаточным для удовлетворения потребностей первых потребителей функционалом. Несмотря на удобство платформы Telegram, возможности данной системы весьма ограничены по сравнению с полноценной проектируемой системой, описанной в данном исследовании.

4.1 Подготовка сервера

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

На хостинге системы было реализовано веб-приложение с использованием микрофреймворка Flask [35]. Данное приложение представляет из себя страницу, которая предназначена для обработки запросов со стороны Telegram и произведение ответа пользователям.

Для обеспечения функционировании системы и взаимодействие с API Telegram были использованы следующие библиотеки:

· from flask - Flask, request, json - библиотеки flask для работы с запросами;

· telepot - методы взаимодействия с API Telegram;

· urllib3 - клиент для обработки HTTP запросов [36];

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

С точки зрения безопасности сервиса, помимо формирования токена доступа к API Telegram, был создан секретный код с помощью сервиса https://www.guidgenerator.com/, который включен в ссылку веб-приложения. Взаимодействие с Telegram реализовано с помощью механизма “webhook” - получение уведомлений об определённых событиях, происходящих на стороне клиента. На сервер отправляется определенный запрос, что означает для сервера необходимость его обработки. Данный подход является широко распространённым на сегодняшний день и применяется во многих больших сервисах.

Таким образом, созданное веб-приложение принимает POST-запрос от Telegram, который содержит информацию об аккаунте пользователя, типе сообщения и его контенте. Обрабатывающая функция производит операции над запросом исходя из информации о пользователе, включая его текущее состояние, и содержании отправленного им сообщения. Хранение состояния пользователя в данном случае необходимо для обеспечения корректного функционирования системы и реализации сценариев взаимодействия внутри системы. Требования к системе подразумевают наличие таких сценариев, потому что ее функционал направлен на взаимодействие на различных уровнях системы, а не ограничивается пустым простым набором базовых команд, которые можно выполнять из главного меню.

4.2 Установка базы данных и ее заполнение

Удобство данного хостинга заключается в предоставлении качественной и понятной документации по реализации определенных функций. Для создания базы данных также существует документ, который описывает разработку и внедрение базы данных MySQL, которую впоследствии можно использовать внутри системы. Взаимодействие с базой данных реализовано с помощью библиотеки SQLAlchemy [37], которая отвечает требованиям CRUD и позволяет производить синхронизацию объектов Python с реляционной базой данных.

На основе описанной в данном исследовании логической модели базы данных была разработана и реализована физическая модель реляционной базы данных с мощью средств MySQL непосредственно на самом сервере. Помимо этого, для поддержания корректного функционирования базы данных с целью редактирования и внедрения новых сущностей или атрибутов необходимо настроить ее адаптивность к изменениям - миграции. Это необходимо для обеспечения перехода от одной структуры базы данных к другой без потери консистентности. Миграции были реализованы с помощью библиотеки «flask_migrate - Migrate» и создания виртуального окружения с помощью библиотеки «virtualenv» [38].

Стоит обратить внимание, что многие связи между таблицами в логической модели имеют отношение многие ко многим. Агрегатором в данном случае выступает таблица Round - тур, которая содержит оценки, полученные танцевальной парой в определенном турнире, за определенный танец, в конкретном туре и от конкретного члена судейской коллегии (рис 4.1).

Рисунок 4.1 Таблица Round

На рис. 4.1 представлена таблица Round, которая включает в себя информацию о первых 10 оценках, полученных парой с идентификационным номером 72 на турнире под идентификационным номером 1 от 10 различных судей соответственно. Естественно, данная таблица сама по себе не может принести полезную информацию обычному пользователю, потому что в ней хранятся ключи из других таблиц, с которыми она соединяется. Поэтому для выведения более информативного запроса следует соединить все внешние таблицы с этой. Полученный результат вместе с самим запросом представлен на рис. 4.2.

Рисунок 4.2 Запрос оценок пары в раунде турнира за один танец

Полученные результаты этого запроса уже содержат уже удобную для восприятия информацию. Например, теперь понятно, что паре под номером 120 на соревновании WDSF GrandSlam Standard Adult - Moscow за танец медленный вальс в третьем туре было поставлено 2 креста от судей Siret Siilak и Andrey Shamshurov. Эту таблицу можно использовать для дальнейшего анализа спортсменами, потому что представленный формат удобен для восприятия.

Для наполнения созданных таблиц базы данных были использованы данные о турнире WDSF GrandSlam Standard Adult - Moscow, информация о котором находится в открытом доступе на сайте международной федерации. Для извлечения данных с сайта была использована библиотека «bs4 - BeautifulSoup» [39]. Написанные скрипты «парсинга» (Приложение №2) позволили заполнить таблицы настоящими данными с этого турнира. Однако при считывании страниц возникла проблема, связанная с возможностями хостинга. Для бесплатных аккаунтов недоступна возможность запрашивать информацию с сайтов, которые не предоставляют общедоступный API с качественной документацией. Естественно, сайт федерации не содержит такого функционала в открытом доступе, поэтому в единичном случае данные были извлечены непосредственно через локальный Jupyter Notebook, а только потом перенесены на сервер и загружены в исходные таблицы базы данных.

Итак, с помощью средств Python на сервере реализована база данных с настоящими данными в таблицах, доступ к которым доступен через чат-бота Telegram.

4.3 Пользовательский интерфейс и функционал

Для реализации качественного взаимодействия пользователя необходимо сохранения его текущего состояния в боте, чтобы выводить ему правильный набор команд. При первом взаимодействии пользователю будет необходимо ввести свой MIN, идентифицирующего в базе данных как спортсмена федерации WDSF.

В главном меню пользователю будет доступно две кнопки - информация о спортсмене и о паре, в которой он состоит и кнопка с выведением турниров пары (рис 4.3).

Рисунок 4.3 Главное меню и вывод запроса информации о пользователе

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

Кнопка с содержанием турнира выводит пользователю сообщение с последним турниром, который сейчас присутствует в базе. В нем содержится информация о названии турнира, даты его проведения, номера пары, занятой позиции на турнире и количеством набранных рейтинговых очков. Так как параметр «рейтинговые очки» не доступен в базе данных в итоговом виде - он формируется из произведения базовых очков турнира и коэффициентом этого турнира. Полученный результат интерфейса изображен на рисунке 4.4.

Рисунок 4.4 Информация о последнем турнире

Также, выведенное пользователем сообщение содержит в себе inline-клавиатуру, с помощью которой можно выбирать нужный турнир. Стрелка вправо выводит следующий турнир, стрелка влево - предыдущий. Кнопка «ОК» позволяет пользователю выбрать текущий турнир, описание которого приведено в сообщении (рис 4.5).

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

Рисунок 4.5 Информация об оценках танцев в каждом туре

При нажатии кнопки Judge Marks пользователю выводится информация о том, сколько крестов поставил конкретный член судейской коллегии в каждом туре. Результат показан на рис. 4.6.

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

Также в меню выбранного соревнования пользователю доступна кнопка «Dance Statistics», которая выводит столбчатую диаграмму распределения количества крестов по танцам в каждом из туров. Для реализации построения графиков использовались библиотеки matplotlib [40] и pandas [41]. Итоговая диаграмма представлена на рисунке 4.7.

Рисунок 4.6 Количество крестов и их распределение по танцам

Рисунок 4.7 Столбчатая диаграмма оценок по турам

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

Таким образом, благодаря разработанному прототипу системы и представленному в данной работе функционалу уже можно извлекать весьма полезную информацию в удобном формате. Естественно, по сравнению с итоговой проектируемой системой возможности данной платформы сильно ограничены интерфейсом, однако ее доступность позволяет интегрировать некоторые требования к основной системе (удобные для восприятия графики, формирование запросов на выведение полезной информации и т.д.). Разработанный чат-бот Telegram будет полезен для спортсменов в мире танцевального спорта, потому что сервисов-аналогов с подобным представлением информации на сегодняшний день нет.

Заключение

В результате проведенного исследования удалось достигнуть поставленной цели: были определены требования и рекомендации по разработке и внедрению информационной системы анализа спортсменов на турнирах по танцевальному спорту и был разработан базовый прототип информационной системы с внедренным функционалом анализа и выведения информации.

Для достижения поставленной цели были выполнены следующие задачи:

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

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

3. Проанализированы и выдвинуты бизнес-требования к разрабатываемой системе, описаны пользовательские требования к системе с помощью пользовательских сценариев, а также были разобраны функциональные и нефункциональные требования. Помимо этого, были разработаны требования к системе на основе подхода классификации FURPS+;

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

5. Разработан прототип проектируемой системы в виде чат-бота на платформе Telegram с помощью клиент-серверного подхода для обеспечения непрерывного функционирования сервиса. Был разработан и внедрен базовый функционал согласно требованиям к системе и представлен интерфейс системы на стороне пользователя.

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

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

Список литературы

1. Холопова Л.А, Поткина Е.С., Развитие информационных технологий // Концепт. - 2014.

2. Абдрахманова Г.И., Гохберг Л.М., Внутренние затраты на развитие цифровой экономики // НИУ ВШЭ, 2019.

3. The 2020 State of IT. The Annual Report on IT Budgets and Tech Trends // Spiceworks

4. Восемь ключевых технологий для бизнеса // PWC.

5. Boell S.K., Cecez-Kecmanovic D., What is an Information System? Kauaii, Hawaii, USA, 2015.

6. Федеральный закон "Об информации, информационных технологиях и о защите информации" от 27.07.2006 N 149-ФЗ (последняя редакция).

7. Telegram Bot API Documentation // Telegram Official Website

8. PythonAnywhere PythonAnywhere Official Website

9. MySQL MySQL Official Website

10. Python documentation Python Official Website

11. Столетов А.И. Технический прогресс и общество // Молодой ученый. -- 2017. -- № 1 (135). -- С. 576-579.

12. Сысоева Е.А., Проблемы модернизации и перехода к инновационной экономике // Проблемы современной экономики, N 3 (67), 2018.

13. Романенко Е.В., Место Big data в современной социально-экономической жизни общества // Инновационная наука, 2016.

14. WebCanape // WebCanape Official Website

15. Полещук И.А., Системный подход и понятие системы // Киевский национальный университет имени Тараса Шевченко, г. Киев, Украина, 2015.

16. Структура и классификация информационных систем // Сибирский Государственный Университет Путей Сообщения - Информационные технологии

17. N. Gorla, T. Somers и B. Wong., Organizational impact of system quality, information quality, and service quality // Journal of Strategic Information Systems 19, стр 207-218, 2010.

18. William M.K. Trochim, Convergent & Discriminant Validity // Conjoint.ly Official Website

19. Регрессионный анализ в электронных таблицах // Международный журнал прикладных и фундаментальных исследований

20. Schwarz E.C., Hunter J.D., Advanced Theory and Practice in Sport Marketing. Hoboken: Taylor and Francis, 2012.

21. М.Л. Попов, Г.М. Ибрагимова, Е.А. Геркина. Спортивные организации и их потребности в информационном обеспечении // Казанский (Приволжский) федеральный университет, 2016.

22. Wu, M.-C., A Study on the Willingness to Use Information System of Sport Event Based on Information System Success Model // The Journal of Human Resource and Adult, 2013.

23. Сomplete Skating System rules set // WDSF official website

24. Judging Systems // WDSF official website

25. Wiegers K., Beatty J. Software Requirements: Third Edition // Microsoft Press. 2013.

26. I. Jacobson, I. Spence, K. Bittner, USE-CASE 2.0 The Guide to Succeeding with Use Cases // Ivar Jacobson International, 2011.

27. P. Eeles, Capturing Architectural Requirements // Rational Services Organization, 2001.

28. Bob Violino, Machine learning: When to use each method and technique. // InfoWorld, 2018.

29. H.S. Oluwatosin, Client-Server Model // IOSR Journal of Computer Engineering, 2014.

30. D. Namiot, M. Sneps-Sneppe, On Micro-services Architecture // International Journal of Open Information Technologies, 2014.

31. Masse M. REST API Design Rulebook // O'Reilly Media. 2011.

32. Н.Р. Булахов, Основы реляционных баз данных // Вестник науки и образования, 2019.

33. AdMob by Google // Google AdMob Official Website

34. Telepot Documentation // Telepot Official Website.

35. Flask Documentation // Flask Official Website

36. Urlib3 Documentation // Urlib3 Official Website

37. SQLAlchemy Documentation // SQLAlchemy Official Website

38. Virtualenv Documentation // Virtualenv Official Website

39. Beautiful Soup Documentation // Crummy Official Website

40. Matplotlib Documentation // Matplotlib Official Website

41. Pandas Documentation // Pandas Official Website

Приложение 1

Полный опрос студентов

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

Приложение 2

Реализация основного функционала

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

Скрипт для формирования JSON объекта с оценками на определенном турнире:

marks_page = requests.get #извлечение информации с сайта

soup = BeautifulSoup(marks_page.text,'html.parser') #обработка с помощью библиотеки

marks2 = soup.find_all('tbody', attrs={'class':'marks'}) #поиск необходимых полей

#скрипт для формирования словаря с оценками каждой пары в каждом раунде

all_marks = {}

arr_w,arr_tg,arr_vw,arr_sf,arr_qs = [],[],[],[],[]

arr_w2,arr_tg2,arr_vw2,arr_sf2,arr_qs2 = [],[],[],[],[]

arr_w3,arr_tg3,arr_vw3,arr_sf3,arr_qs3 = [],[],[],[],[]

arr_w4,arr_tg4,arr_vw4,arr_sf4,arr_qs4 = [],[],[],[],[]

for i in range(len(marks2)):

if 'number' in str(marks2[i]):

if 'round' in str(marks2[i+68]):

for j in range(12):

arr_w.append(marks2[i+2+j].text)

arr_tg.append(marks2[i+15+j].text)

arr_vw.append(marks2[i+14*2+j].text)

arr_sf.append(marks2[i+14*3-1+j].text)

arr_qs.append(marks2[i+14*4-2+j].text)

arr_w2.append(marks2[i+69+j].text)

arr_tg2.append(marks2[i+69+13+j].text)

arr_vw2.append(marks2[i+69+13*2+j].text)

arr_sf2.append(marks2[i+69+13*3+j].text)

arr_qs2.append(marks2[i+69+13*4+j].text)

all_marks[marks2[i].text] = {

'r1': {

'w1':arr_w[0],'w2'

:arr_w[1],'w3':arr_w[2],'w4':arr_w[3],'w5':arr_w[4],'w6':arr_w[5],'w7':arr_w[6],'w8':arr_w[7],'w9':arr_w[8],'w10':arr_w[9],'w11':arr_w[10],'w12':arr_w[11],

'tg1':arr_tg[0],'tg2':arr_tg[1],'tg3':arr_tg[2],'tg4':arr_tg[3],'tg5':arr_tg[4],'tg6':arr_tg[5],'tg7':arr_tg[6],'tg8':arr_tg[7],'tg9':arr_tg[8],'tg10':arr_tg[9],'tg11':arr_tg[10],'tg12':arr_tg[11],

'vw1':arr_vw[0],'vw2':arr_vw[1],'vw3':arr_vw[2],'vw4':arr_vw[3],'vw5':arr_vw[4],'vw6':arr_vw[5],'vw7':arr_vw[6],'vw8':arr_vw[7],'vw9':arr_vw[8],'vw10':arr_vw[9],'vw11':arr_vw[10],'vw12':arr_vw[11],

'sf1':arr_sf[0],'sf2':arr_sf[1],'sf3':arr_sf[2],'sf4':arr_sf[3],'sf5':arr_sf[4],'sf6':arr_sf[5],'sf7':arr_sf[6],'sf8':arr_sf[7],'sf9':arr_sf[8],'sf10':arr_sf[9],'sf11':arr_sf[10],'sf12':arr_sf[11],

'qs1':arr_qs[0],'qs2':arr_qs[1],'qs3':arr_qs[2],'qs4':arr_qs[3],'qs5':arr_qs[4],'qs6':arr_qs[5],'qs7':arr_qs[6],'qs8':arr_qs[7],'qs9':arr_qs[8],'qs10':arr_qs[9],'qs11':arr_qs[10],'qs12':arr_qs[11]

},

'r2': {

'w1':arr_w2[0

],'w2':arr_w2[1],'w3':arr_w2[2],'w4':arr_w2[3],'w5':arr_w2[4],'w6':arr_w2[5],'w7':arr_w2[6],'w8':arr_w2[7],'w9':arr_w2[8],'w10':arr_w2[9],'w11':arr_w2[10],'w12':arr_w2[11],

'tg1':arr_tg2[0],'tg2':arr_tg2[1],'tg3':arr_tg2[2],'tg4':arr_tg2[3],'tg5':arr_tg2[4],'tg6':arr_tg2[5],'tg7':arr_tg2[6],'tg8':arr_tg2[7],'tg9':arr_tg2[8],'tg10':arr_tg2[9],'tg11':arr_tg2[10],'tg12':arr_tg2[11],

'vw1':arr_vw2[0],'vw2':arr_vw2[1],'vw3':arr_vw2[2],'vw4':arr_vw2[3],'vw5':arr_vw2[4],'vw6':arr_vw2[5],'vw7':arr_vw2[6],'vw8':arr_vw2[7],'vw9':arr_vw2[8],'vw10':arr_vw2[9],'vw11':arr_vw2[10],'vw12':arr_vw2[11],

'sf1':arr_sf2[0],'sf2':arr_sf2[1],'sf3':arr_sf2[2],'sf4':arr_sf2[3],'sf5':arr_sf2[4],'sf6':arr_sf2[5],'sf7':arr_sf2[6],'sf8':arr_sf2[7],'sf9':arr_sf2[8],'sf10':arr_sf2[9],'sf11':arr_sf2[10],'sf12':arr_sf2[11],

'qs1':arr_qs2[0],'qs2':arr_qs2[1],'qs3':arr_qs2[2],'qs4':arr_qs2[3],'qs5':arr_qs2[4],'qs6':arr_qs2[5],'qs7':arr_qs2[6],'qs8':arr_qs2[7],'qs9':arr_qs2[8],'qs10':arr_qs2[9],'qs11':arr_qs2[10],'qs12':arr_qs2[11]

}

}

if 'round' in str(marks2[i+68+67]):

for j in range(12):

arr_w.append(marks2[i+2+j].text)

arr_tg.append(marks2[i+15+j].text)

arr_vw.append(marks2[i+14*2+j].text)

arr_sf.append(marks2[i+14*3-1+j].text)

arr_qs.append(marks2[i+14*4-2+j].text)

arr_w2.append(marks2[i+69+j].text)

arr_tg2.append(marks2[i+69+13+j].text)

arr_vw2.append(marks2[i+69+13*2+j].text)

arr_sf2.append(marks2[i+69+13*3+j].text)

arr_qs2.append(marks2[i+69+13*4+j].text)

arr_w3.append(marks2[i+69+67+j].text)

arr_tg3.append(marks2[i+69+67+13+j].text)

arr_vw3.append(marks2[i+69+67+13*2+j].text)

arr_sf3.append(marks2[i+69+67+13*3+j].text)

arr_qs3.append(marks2[i+69+67+13*4+j].text)

all_marks[marks2[i].text] = {

'r1': {

'w1':arr_w[0],'w2':arr_w[1],'w3':arr_w[2],'w4':arr_w[3],'w5':arr_w[4],'w6':arr_w[5],'w7':arr_w[6],'w8':arr_w[7],'w9':arr_w[8],'w10':arr_w[9],'w11':arr_w[10],'w12':arr_w[11],

'tg1':arr_tg[0],'tg2':arr_tg[1],'tg3':arr_tg[2],'tg4':arr_tg[3],'tg5':arr_tg[4],'tg6':arr_tg[5],'tg7':arr_tg[6],'tg8':arr_tg[7],'tg9':arr_tg[8],'tg10':arr_tg[9],'tg11':arr_tg[10],'tg12':arr_tg[11],

'vw1':arr_vw[0],'vw2':arr_vw[1],'vw3':arr_vw[2],'vw4':arr_vw[3],'vw5':arr_vw[4],'vw6':arr_vw[5],'vw7':arr_vw[6],'vw8':arr_vw[7],'vw9':arr_vw[8],'vw10':arr_vw[9],'vw11':arr_vw[10],'vw12':arr_vw[11],

'sf1':arr_sf[0],'sf2':arr_sf[1],

'sf3':arr_sf[2],'sf4':arr_sf[3],'sf5':arr_sf[4],'sf6':arr_sf[5],'sf7':arr_sf[6],'sf8':arr_sf[7],'sf9':arr_sf[8],'sf10':arr_sf[9],'sf11':arr_sf[10],'sf12':arr_sf[11],

'qs1':arr_qs[0],'qs2':arr_qs[1],'qs3':arr_qs[2],'qs4':arr_qs[3],'qs5':arr_qs[4],'qs6':arr_qs[5],'qs7':arr_qs[6],'qs8':arr_qs[7],'qs9':arr_qs[8],'qs10':arr_qs[9],'qs11':arr_qs[10],'qs12':arr_qs[11]

},

'r2': {

'w1':arr_w2[0],'w2':arr_w2[1],'w3':arr_w2[2],'w4':arr_w2[3],'w5':arr_w2[4],'w6':arr_w2[5],'w7':arr_w2[6],'w8':arr_w2[7],'w9':arr_w2[8],'w10':arr_w2[9],'w11':arr_w2[10],'w12':arr_w2[11],

'tg1':arr_tg2[0],'tg2':arr_tg2[1],'tg3':arr_tg2[2],'tg4':arr_tg2[3],'tg5':arr_tg2[4],'tg6':arr_tg2[5],'tg7':arr_tg2[6],'tg8':arr_tg2[7],'tg9':arr_tg2[8],'tg10':arr_tg2[9],'tg11':arr_tg2[10],'tg12':arr_tg2[11],

'vw1':arr_vw2[0],'vw2':arr_vw2[1],'vw3':arr_vw2[2],'vw4':arr_vw2[3],'vw5':arr_vw2[4],'vw6':arr_vw2[5],'vw7':arr_vw2[6],'vw8':arr_vw2[7],'vw9':arr_vw2[8],'vw10':arr_vw2[9],'vw11':arr_vw2[10],'vw12':arr_vw2[11],

'sf1':arr_sf2[0],'sf2':arr_sf2[1],'sf3':arr_sf2[2],'sf4':arr_sf2[3],'sf5':arr_sf2[4],'sf6':arr_sf2[5],'sf7':arr_sf2[6],'sf8':arr_sf2[7],'sf9':arr_sf2[8],'sf10':arr_sf2[9],'sf11':arr_sf2[10],'sf12':arr_sf2[11],

'qs1':arr_qs2[0],'qs2':arr_qs2[1],'qs3':arr_qs2[2],'qs4':arr_qs2[3],'qs5':arr_qs2[4],'qs6':arr_qs2[5],'qs7':arr_qs2[6],'qs8':arr_qs2[7],'qs9':arr_qs2[8],'qs10':arr_qs2[9],'qs11':arr_qs2[10],'qs12':arr_qs2[11]

},

'r3':{

'w1':arr_w3[0],'w2':arr_w3[1],'w3':arr_w3[2],'w4':arr_w3[3],'w5':arr_w3[4],'w6':arr_w3[5],'w7':arr_w3[6],'w8':arr_w3[7],'w9':arr_w3[8],'w10':arr_w3[9],'w11':arr_w3[10],'w12':arr_w3[11],

'tg1':arr_tg3[0],'tg2':arr_tg3[1],'tg3':arr_tg3[2],'tg4':arr_tg3[3],'tg5':arr_tg3[4],'tg6':arr_tg3[5],'tg7':arr_tg3[6],'tg8':arr_tg3[7],'tg9':arr_tg3[8],'tg10':arr_tg3[9],'tg11':arr_tg3[10],'tg12':arr_tg3[11],

'vw1':arr_vw3[0],'vw2':arr_vw3[1],'vw3':arr_vw3[2],'vw4':arr_vw3[3],'vw5':arr_vw3[4],'vw6':arr_vw3[5],'vw7':arr_vw3[6],'vw8':arr_vw3[7],'vw9':arr_vw3[8],'vw10':arr_vw3[9],'vw11':arr_vw3[10],'vw12':arr_vw3[11],

'sf1':arr_sf3[0],'sf2':arr_sf3[1],'sf3':arr_sf3[2],'sf4':arr_sf3[3],'sf5':arr_sf3[4],'sf6':arr_sf3[5],'sf7':arr_sf3[6],'sf8':arr_sf3[7],'sf9':arr_sf3[8],'sf10':arr_sf3[9],'sf11':arr_sf3[10],'sf12':arr_sf3[11],

'qs1':arr_qs3[0],'qs2':arr_qs3[1],'qs3':arr_qs3[2],'qs4':arr_qs3[3],'qs5':arr_qs3[4],'qs6':arr_qs3[5],'qs7':arr_qs3[6],'qs8':arr_qs3[7],'qs9':arr_qs3[8],'qs10':arr_qs3[9],'qs11':arr_qs3[10],'qs12':arr_qs3[11]

}

}

if 'round' in str(marks2[i+68+67*2]):

for j in range(12):

arr_w.append(marks2[i+2+j].text)

arr_tg.append(marks2[i+15+j].text)

arr_vw.append(marks2[i+14*2+j].text)

arr_sf.append(marks2[i+14*3-1+j].text)

arr_qs.append(marks2[i+14*4-2+j].text)

arr_w2.append(marks2[i+69+j].text)

arr_tg2.append(marks2[i+69+13+j].text)

arr_vw2.append(marks2[i+69+13*2+j].text)

arr_sf2.append(marks2[i+69+13*3+j].text)

arr_qs2.append(marks2[i+69+13*4+j].text)

arr_w3.append(marks2[i+69+67+j].text)

arr_tg3.append(marks2[i+69+67+13+j].text)

arr_vw3.append(marks2[i+69+67+13*2+j].text)

arr_sf3.append(marks2[i+69+67+13*3+j].text)

arr_qs3.append(marks2[i+69+67+13*4+j].text)

arr_w4.append(marks2[i+69+67*2+j].text)

arr_tg4.append(marks2[i+69+67*2+13+j].text)

arr_vw4.append(marks2[i+69+67*2+13*2+j].text)

arr_sf4.append(marks2[i+69+67*2+13*3+j].text)

arr_qs4.append(marks2[i+69+67*2+13*4+j].text)

all_marks[marks2[i].text] = {

'r1': {

'w1':arr_w[0],'w2':arr_w[1],'w3':arr_w[2],'w4':arr_w[3],'w5':arr_w[4],'w6':arr_w[5],'w7':arr_w[6],'w8':arr_w[7],'w9':arr_w[8],'w10':arr_w[9],'w11':arr_w[10],'w12':arr_w[11],

'tg1':arr_tg[0],'tg2':arr_tg[1],'tg3':arr_tg[2],'tg4':arr_tg[3],'tg5':arr_tg[4],'tg6':arr_tg[5],'tg7':arr_tg[6],'tg8':arr_tg[7],'tg9':arr_tg[8],'tg10':arr_tg[9],'tg11':arr_tg[10],'tg12':arr_tg[11],

'vw1':arr_vw[0],'vw2':arr_vw[1],'vw3':arr_vw[2],'vw4':arr_vw[3],'vw5':arr_vw[4],'vw6':arr_vw[5],'vw7':arr_vw[6],'vw8':arr_vw[7],'vw9':arr_vw[8],'vw10':arr_vw[9],'vw11':arr_vw[10],'vw12':arr_vw[11],

'sf1':arr_sf[0],'sf2':arr_sf[1],'sf3':arr_sf[2],'sf4':arr_sf[3],'sf5':arr_sf[4],'sf6':arr_sf[5],'sf7':arr_sf[6],'sf8':arr_sf[7],'sf9':arr_sf[8],'sf10':arr_sf[9],'sf11':arr_sf[10],'sf12':arr_sf[11],

'qs1':arr_qs[0],'qs2':arr_qs[1],'qs3':arr_qs[2],'qs4':arr_qs[3],'qs5':arr_qs[4],'qs6':arr_qs[5],'qs7':arr_qs[6],'qs8':arr_qs[7],'qs9':arr_qs[8],'qs10':arr_qs[9],'qs11':arr_qs[10],'qs12':arr_qs[11]

},

'r2': {

'w1':arr_w2[0],'w2':arr_w2[1],'w3':arr_w2[2],'w4':arr_w2[3],'w5':arr_w2[4],'w6':arr_w2[5],'w7':arr_w2[6],'w8':arr_w2[7],'w9':arr_w2[8],'w10':arr_w2[9],'w11':arr_w2[10],'w12':arr_w2[11],

'tg1':arr_tg2[0],'tg2':arr_tg2[1],'tg3':arr_tg2[2],'tg4':arr_tg2[3],'tg5':arr_tg2[4],'tg6':arr_tg2[5],'tg7':arr_tg2[6],'tg8':arr_tg2[7],'tg9':arr_tg2[8],'tg10':arr_tg2[9],'tg11':arr_tg2[10],'tg12':arr_tg2[11],

'vw1':arr_vw2[0],'vw2':arr_vw2[1],'vw3':arr_vw2[2],'vw4':arr_vw2[3],'vw5':arr_vw2[4],'vw6':arr_vw2[5],'vw7':arr_vw2[6],'vw8':arr_vw2[7],'vw9':arr_vw2[8],'vw10':arr_vw2[9],'vw11':arr_vw2[10],'vw12':arr_vw2[11],

'sf1':arr_sf2[0],'sf2':arr_sf2[1],'sf3':arr_sf2[2],'sf4':arr_sf2[3],'sf5':arr_sf2[4],'sf6':arr_sf2[5],'sf7':arr_sf2[6],'sf8':arr_sf2[7],'sf9':arr_sf2[8],'sf10':arr_sf2[9],'sf11':arr_sf2[10],'sf12':arr_sf2[11],

'qs1':arr_qs2[0],'qs2':arr_qs2[1],'qs3':arr_qs2[2],'qs4':arr_qs2[3],'qs5':arr_qs2[4],'qs6':arr_qs2[5],'qs7':arr_qs2[6],'qs8':arr_qs2[7],'qs9':arr_qs2[8],'qs10':arr_qs2[9],'qs11':arr_qs2[10],'qs12':arr_qs2[11]

},

'r3':{

'w1':arr_w3[0],'w2':arr_w3[1],'w3':arr_w3[2],'w4':arr_w3[3],'w5':arr_w3[4],'w6':arr_w3[5],'w7':arr_w3[6],'w8':arr_w3[7],'w9':arr_w3[8],'w10':arr_w3[9],'w11':arr_w3[10],'w12':arr_w3[11],

'tg1':arr_tg3[0],'tg2':arr_tg3[1],'tg3':arr_tg3[2],'tg4':arr_tg3[3],'tg5':arr_tg3[4],'tg6':arr_tg3[5],'tg7':arr_tg3[6],'tg8':arr_tg3[7],'tg9':arr_tg3[8],'tg10':arr_tg3[9],'tg11':arr_tg3[10],'tg12':arr_tg3[11],

'vw1':arr_vw3[0],'vw2':arr_vw3[1],'vw3':arr_vw3[2],'vw4':arr_vw3[3],'vw5':arr_vw3[4],'vw6':arr_vw3[5],'vw7':arr_vw3[6],'vw8':arr_vw3[7],'vw9':arr_vw3[8],'vw10':arr_vw3[9],'vw11':arr_vw3[10],'vw12':arr_vw3[11],

'sf1':arr_sf3[0],'sf2':arr_sf3[1],'sf3':arr_sf3[2],'sf4':arr_sf3[3],'sf5':arr_sf3[4],'sf6':arr_sf3[5],'sf7':arr_sf3[6],'sf8':arr_sf3[7],'sf9':arr_sf3[8],'sf10':arr_sf3[9],'sf11':arr_sf3[10],'sf12':arr_sf3[11],

'qs1':arr_qs3[0],'qs2':arr_qs3[1],'qs3':arr_qs3[2],'qs4':arr_qs3[3],'qs5':arr_qs3[4],'qs6':arr_qs3[5],'qs7':arr_qs3[6],'qs8':arr_qs3[7],'qs9':arr_qs3[8],'qs10':arr_qs3[9],'qs11':arr_qs3[10],'qs12':arr_qs3[11]

},

'r4':{

'w1':arr_w4[0],'w2':arr_w4[1],'w3':arr_w4[2],'w4':arr_w4[3],'w5':arr_w4[4],'w6':arr_w4[5],'w7':arr_w4[6],'w8':arr_w4[7],'w9':arr_w4[8],'w10':arr_w4[9],'w11':arr_w4[10],'w12':arr_w4[11],

'tg1':arr_tg4[0],'tg2':arr_tg4[1],'tg3':arr_tg4[2],'tg4':arr_tg4[3],'tg5':arr_tg4[4],'tg6':arr_tg4[5],'tg7':arr_tg4[6],'tg8':arr_tg4[7],'tg9':arr_tg4[8],'tg10':arr_tg4[9],'tg11':arr_tg4[10],'tg12':arr_tg4[11],

'vw1':arr_vw4[0],'vw2':arr_vw4[1],'vw3':arr_vw4[2],'vw4':arr_vw4[3],'vw5':arr_vw4[4],'vw6':arr_vw4[5],'vw7':arr_vw4[6],'vw8':arr_vw4[7],'vw9':arr_vw4[8],'vw10':arr_vw4[9],'vw11':arr_vw4[10],'vw12':arr_vw4[11],

'sf1':arr_sf4[0],'sf2':arr_sf4[1],'sf3':arr_sf4[2],'sf4':arr_sf4[3],'sf5':arr_sf4[4],'sf6':arr_sf4[5],'sf7':arr_sf4[6],'sf8':arr_sf4[7],'sf9':arr_sf4[8],'sf10':arr_sf4[9],'sf11':arr_sf4[10],'sf12':arr_sf4[11],

'qs1':arr_qs4[0],'qs2':arr_qs4[1],'qs3':arr_qs4[2],'qs4':arr_qs4[3],'qs5':arr_qs4[4],'qs6':arr_qs4[5],'qs7':arr_qs4[6],'qs8':arr_qs4[7],'qs9':arr_qs4[8],'qs10':arr_qs4[9],'qs11':arr_qs4[10],'qs12':arr_qs4[11]

}

}

else:

for j in range(12):

arr_w.append(marks2[i+2+j].text)

arr_tg.append(marks2[i+15+j].text)

arr_vw.append(marks2[i+14*2+j].text)

arr_sf.append(marks2[i+14*3-1+j].text)

arr_qs.append(marks2[i+14*4-2+j].text)

all_marks[marks2[i].text] = {

'r1' : {

'w1':arr_w[0],'w2':arr_w[1],'w3':arr_w[2],'w4':arr_w[3],'w5':arr_w[4],'w6':arr_w[5],'w7':arr_w[6],'w8':arr_w[7],'w9':arr_w[8],'w10':arr_w[9],'w11':arr_w[10],'w12':arr_w[11],

'tg1':arr_tg[0],'tg2':arr_tg[1],'tg3':arr_tg[2],'tg4':arr_tg[3],'tg5':arr_tg[4],'tg6':arr_tg[5],'tg7':arr_tg[6],'tg8':arr_tg[7],'tg9':arr_tg[8],'tg10':arr_tg[9],'tg11':arr_tg[10],'tg12':arr_tg[11],

'vw1':arr_vw[0],'vw2':arr_vw[1],'vw3':arr_vw[2],'vw4':arr_vw[3],'vw5':arr_vw[4],'vw6':arr_vw[5],'vw7':arr_vw[6],'vw8':arr_vw[7],'vw9':arr_vw[8],'vw10':arr_vw[9],'vw11':arr_vw[10],'vw12':arr_vw[11],

'sf1':arr_sf[0],'sf2':arr_sf[1],'sf3':arr_sf[2],'sf4':arr_sf[3],'sf5':arr_sf[4],'sf6':arr_sf[5],'sf7':arr_sf[6],'sf8':arr_sf[7],'sf9':arr_sf[8],'sf10':arr_sf[9],'sf11':arr_sf[10],'sf12':arr_sf[11],

'qs1':arr_qs[0],'qs2':arr_qs[1],'qs3':arr_qs[2],'qs4':arr_qs[3],'qs5':arr_qs[4],'qs6':arr_qs[5],'qs7':arr_qs[6],'qs8':arr_qs[7],'qs9':arr_qs[8],'qs10':arr_qs[9],'qs11':arr_qs[10],'qs12':arr_qs[11]

}

}

arr_w,arr_tg,arr_vw,arr_sf,arr_qs = [],[],[],[],[]

arr_w2,arr_tg2,arr_vw2,arr_sf2,arr_qs2 = [],[],[],[],[]

arr_w3,arr_tg3,arr_vw3,arr_sf3,arr_qs3 = [],[],[],[],[]

arr_w4,arr_tg4,arr_vw4,arr_sf4,arr_qs4 = [],[],[],[],[]

Код для формирования запроса по выводу информации о количестве крестов в каждом туре по танцам выбранного турнира:

chat_id = update["callback_query"]['message']["chat"]["id"]

user_str = update['callback_query']['message']['chat']['username']

user = User.query.filter(User.username==str(user_str)).first()

data = update["callback_query"]['data']

message_id = update["callback_query"]['message']['message_id']

userID = user.id

q=db.session.query(User,Couple.id.label('CoupleID'),Judge.id.label('JudgeID'),Dance.id.label('DanceID'),Dance.name.label('DanceNAME'),Round.round,Round.score).filter(User.id == userID).filter(Round.id_comp == id_comp).join(User, User.couple_id==Couple.id).join(Round,Couple.id == Round.id_couple).join (Dance,Dance.id == Round.id_dance).join(Judge,Judge.id == Round.id_judge).subquery()

q1 = db.session.query(q.c.round,q.c.DanceNAME,func.sum(case([(q.c.score == True, 1)], else_=0)).label('TotalMarks')).group_by(q.c.round,q.c.DanceID).all()

q2 = db.session.query(q.c.round,q.c.DanceNAME,func.sum(case([(q.c.score == True, 1)], else_=0)).label('TotalMarks')).group_by(q.c.round).all()

mes = ''

rr = 1

for i in q1:

if rr == i.round:

mes +='\n{0}\nR{1} TOTAL = {2} \n{3}'.format(separator,rr,q2[rr-1].TotalMarks, separator)

rr+=1

mes+='\n'+str('R{0} {1}: {2}'.format(i.round,i.DanceNAME, i.TotalMarks))

Код для просмотра распределения оценок между судьями в конкретном туре данного соревнования.

id_comp = int(user.status.split('_')[1])

q=db.session.query(User,Couple.id.label('CoupleID'),Judge.id.label('JudgeID'),Judge.name.label('JudgeNAME'),Dance.id.label('DanceID'),Dance.name.label('DanceNAME'),Round.round,Round.score).filter(User.id == userID).filter (Round.id_comp == id_comp).join(User,User.couple_id==Couple.id). join(Round,Couple.id == Round.id_couple).join(Dance,Dance.id == Round.id_dance).join(Judge,Judge.id == Round.id_judge).subquery()

q22 = db.session.query(q.c.round,q.c.JudgeID,q.c.score).all()

mes = 'TOTAL JUDGE MARKS PER ROUND'

rr = 1

for i in q1:

if rr == i.round:

mes +='\n{0}\nRound {1}\n'.format(separator,rr,separator)

rr+=1

marks_x = ''

for k in q22:

if i.round == k.round and i.JudgeID == k.JudgeID:

if k.score == True:

marks_x+='X'

else:

marks_x+='-'

mes+='\n'+str('{0}. {1}: {2} |{3}|'.format(i.JudgeID,i.JudgeNAME, i.TotalMarks,marks_x))

bot.editMessageText(msg_identifier = (chat_id, message_id), text = mes)

Код для выведения диаграммы распределения оценок участников по танцам в каждом туре турнира.

df = pd.DataFrame(my_marks)

figure = df.plot(kind='bar',figsize=(16,9), fontsize=20, rot=0);

figure.figure.savefig('/home/wdsfStat/photo_to_send.png')

doc = open('/home/wdsfStat/photo_to_send.png','rb')

bot.sendPhoto(chat_id, doc)

Размещено на Allbest.ru

...

Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.