Автоматизация, Программирование

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

Время прочтения: 4 мин.

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

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

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

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

Самое интересное – это визуализация, но стандартный инструмент от 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()

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

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

Советуем почитать