Интерактивный модуль голосования на Python

Как определить, что работа выполнена качественно, все требования соблюдены и клиенты довольны? Можно, конечно, спросить, но это не путь Джедая…

Интерактивный модуль голосования на Python

Первым делом нужно продумать инструмент распространения, мне понравилась идея отправления ссылок на почту. Что бы еще добавить? Хочу визуализировать ответы в режиме реального времени!

Приступаем к реализации.

Ну, с опросником все понятно — гугл-форма, однозначно. Заполняем, подключаем к гугл диску, прописываем варианты ответов.

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

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

Для реализации задумки необходимо подключиться к API сервисам Google Drive и Plotly и получить свои API key:

tls.set_credentials_file(username=’youre username', api_key='youre api key') token = 'youre token' #переменная для дальнейшего обновления гистограммы stream_ident = dict(token=token, maxpoints=60) s = py.Stream(stream_id=token)

На Google диске нам необходимо подключиться к файлу, для этого стоит изучить этот Jupyter Notebook.

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

Преобразуем скачанный excel файл в DataFrame, передаем значения для построения гистограммы в Bar (необходимо изначально обозначить размер передаваемых массивов).

command = list(data_set().keys()).sort() points = [0]*len(list(data_set().keys())) val=[0]*len(list(data_set().keys())) clr=[0]*len(list(data_set().keys())) #построение графиков trace = go.Bar(x=command, y=points, xaxis='x2', yaxis='y2', marker=dict(color=clr), name='Team', textfont=dict( family="Courier New, monospace", size=15, color="#003300"), text=val, textposition="outside", # stream=stream_id,) data=[trace] layout = go.Layout( xaxis2=dict( domain=[0,1], anchor='y2', categoryorder= 'category ascending', tickfont=dict(size=16, family="Courier New, monospace", color="#7f7f7f"), automargin=True), yaxis2=dict( domain=[0,1], rangemode='nonnegative', autorange=True, dtick=1, anchor='x2', categoryorder= 'category ascending', tickfont=dict(size=16, family="Courier New, monospace", color="#7f7f7f") )) fig = go.Figure(data=data, layout=layout) url = py.plot(fig, filename='simple-inset-stream', auto_open=False) webbrowser.open_new(url+'.embed')

Обратите внимание, что в конце url-адреса нужно добавить строку ‘.embed’, это необходимо для корректной визуализации графика. Вариант без использования embed вас не порадует – подписи по оси х не отобразятся полностью (угол наклона = 90), также этот параметр растягивает график по размеру окна браузера и т.д.

Пора переходить к самой интересной части. Так как я хочу видеть изменения графика в режиме реального времени, мне нужно использовать стриминг в plotly. C интервалом в 1 секунду, я буду читать файл с диска и передавать новые массивы данных в plot. В ходе настройки графика я решила выделить самый большой столбец диаграммы другим цветом. Сделать это оказалось достаточно просто (в параметр color мы можем передать массив значений, сформированный в соответствии с необходимым условием).

if __name__ == '__main__': s.open() while True: data_set() labels = list(data_set().keys()) values = [x-1 for x in list(data_set().values())] clrs = ["#009933" if x == max(values) else '#66FFFF' for x in values] s.write(dict(x=labels, y=values,text=values, marker=dict(color=clrs), type='bar')) s.close()

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

Интерактивный модуль голосования на Python

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

44
Начать дискуссию