Хабрахабр

Кодим–пицца

Привет, Хабр. Мы спонтанно провели первый внутренний хакатон. Решила поделиться с вами своими болями и выводами о подготовке к нему за 2 недели, а также проектами, которые получились.

Скучная часть для тех, кто интересуется маркетингом

Начну с маленькой истории.

В нашем в офисе проходит первый хакатон MskDotNet Community. Начало апреля. Суббота. Битва за Татуин в разгаре, в нашей галактике на этот раз. Пицца. 20 команд. Надувной R2-D2 маячит по залу. Всё очень душевно (пруфы). Сдвигаем запуск первых заездов. Команды пишут самые правильные алгоритмы, чтобы пройти самую опасную гонку на карте. Мы с организаторами ожидали, что в субботу многие уйдут после обеда. Печеньки и кофе спасают. 12 часов кодинга позади. Но нет. Что-то отваливается, что-то не запускается. Финал. Побеждает наша команда. Но все счастливы. Мы счастливы вдвойне.

Пишу нашему СТО Саше. Делюсь радостью в Slack и в голову приходит идея: «Надо сделать свой хакатон». Тишина.

Пью кофе в офисе. Утро. «Лиза, это же отлично! Вижу приближающегося из-за спины Сашу. Давай делать!» WTF!? У нас как раз 21 апреля важная дата. А? Так быстро? Мне нужно улетать в Сыктывкар на стажировку в середине апреля. Что? Давай. Да и чёрт с ним!

Я никогда не была единоличным организатором хакатона. Остаётся 2 недели. Читаю статьи на эту тему. Пусть и внутреннего. Нужно несколько месяцев. Жесть. Нужно продумать мерч, призы, условия, расписание, заинтересовать, понять цель, бюджеты. Нужно несколько человек. Я точно не успею. А может даже разобраться в смысле жизни. Самое время забить на статьи и начать что-то делать. И пока ты читал и готовился, уже неделя прошла.

Ловите наш чеклист проведения внутреннего хакатона за 1 неделю

  • План: спокойно садишься и пишешь список того, что необходимо сделать для хакатона. 30 минут.
  • Задача: участники сами предлагают и выбирают проекты, которые хотят создать в Google Sheets. Фоновая задача, 2 часа.
  • Расписание: на коленке пишешь короткую разбивку по времени с учётом 3 перерывов и финала. 20 минут.
  • Команды: публикуешь сообщение про хакатон с расписанием от СТО в IT-каналах в Slack/почте/etc и создаёшь отдельный канал для хакатона. В нём все разбиваются на команды, а неопределившиеся делают это в первые 5 минут хакатона. Фоновая задача, 2 часа.
  • Плюшки: придумываешь мерч с двумя разработчиками, отдаёшь дизайнеру в отрисовку, получаешь готовый. Фоновая задача, 3 дня.
  • Хакатон: приходишь в офис, координируешь всех в начале, занимаешься своими делами, читаешь Reddit, с важным видом сообщаешь каждый перерыв про свежую пиццу, фотографируешь закат, объявляешь о финале, вместе голосуете и выбираете победителя. 1 день.
  • Под звёздочкой: конечно, ты постоянно думаешь о том, чтобы всё прошло хорошо. Конечно, не все увидят твоё сообщение и с некоторыми лучше поговорить лично. Конечно, если тебе будет кто-то помогать, всё станет в 2 раза проще (мне помогала замечательная Алёна).

Менее скучная часть про дату хакатона

Почему 21 апреля? Этот день значим для нас. Ровно год назад, 21 апреля мы упали под нагрузкой во время первых выходных после старта Федеральной Рекламной Кампании. На следующий день, в воскресенье, наша команда была на работе с 8 утра. Тогда мы создали в Trello доску sundayhackathon и началась неделя посменной работы по 12 часов в день. Положение было настолько критичным, что нам некогда было даже есть и нас подкармливали ребята из других команд.

С тех пор, мы многое поменяли, но дату теперь точно не забудем. Более детальный рассказ вы можете прочитать на странице Фёдора Овчинникова (нашего СЕО).

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

Самая нескучная часть про проекты хакатона

Disclaimer: все описания писали сами ребята, так что авторство текста не моё.

Олег Лёрнинг (машин лёрнинг)

Дима Кочнев, Саша Андронов (@alexandronov)

В итоге сделали очень простую и игрушечную – она распознаёт 10 пицц, примерно разобрались как всё устроено, насколько это возможно за день (~10 часов). Хотели сделать нейросетку, которая бы определяла что за пицца на фотографии без каких-либо знаний.

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

Инструменты, которые использовали:

  • imageai — удобная и простая библиотека для работы с машинным обучением и компьютерным зрением.
  • Модели попробовали две – ResNet50, Yolo.
  • Код писали, понятное дело, на питоне.

У нас было 11000 фоток, но среди них почти 3/4 оказались мусором, а в оставшихся – разные, неподходящие ракурсы. В итоге мы взяли готовую модель (которая просто умеет находить пиццу) и с её помощью отделили самый треш. Далее, в названии фотки было название пиццы — так мы разложили по папкам, но оказалось, что названия не совпадают с действительностью и тут уже пришлось руками подчистить. В итоге осталось около 500-600 фото, понятно, что это ничтожное количество, но тем не менее, этого оказалось достаточно, чтобы отделить 10 пицц одну от другой.

На ней обучали в 100 эпох, но было видно, что сеть перенасытилась уже после 50 эпох, из-за того, что был маленький датасет. Для обучения сетки взяли самую дешёвую виртуалку в Azure на NVIDIA Tesla K80.

Собственно — вся проблема в отсутствии хороших данных.

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

GUI for NOOBS (консолька для заказа пиццы)

Миша Кумачёв (Ceridan), Женя Биккинин, Женя Васильев

Мы собрали прототип консольного приложения для гиков, благодаря которому можно заказать пиццу через терминал или командную строку, или даже встроить в deploy pipeline и при успешном релизе доставлять пиццу в офис.

С последней задачей было связано несколько неприятных минут ближе к концу хакатона. Работа разбилась на несколько частей: разбирались, как устроен наш API для мобильных приложений, собирали свой собственный CLI с помощью oclif и настраивали публикацию собранного нами пакета. Мы потратили минут 40, чтобы понять, что же пошло не так, но в итоге всё магическим образом само заработало). У нас всё работало локально и даже работали старые опубликованные версии пакета, но новые (в которых было добавлено больше клёвых фич и смайликов) работать отказывались.

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

Как итог — мы всё-таки сделали это!

CourierGo

Антон Бружмелёв (автор), Ваня Зверев, Глеб Лесников (entropy), Андрей Сарафанов

Взяли идею «Приложение для курьера».

Предыстория про подготовку.

Изначально я прикинул, а какие вообще фичи могут быть в приложении? Возник примерно такой список функционала:

  • Приложение логинится в кассу доставки по коду.
  • В приложении сразу видны доступные заказы, заказы которые нужно брать.
  • Курьер отмечает заказ и берет в поездку.
  • Ему показывается расчетное время и успевает он или нет.
  • Клиенту показывает что курьер выехал.
  • Клиенту начинает показывать точку курьера на карте и расчетное время.
  • Курьер может написать клиенту в чат из приложения.
  • Клиент может написать курьеру в чат из приложения.
  • За пять минут до приезда клиенту приходит сообщение что курьер близко, будьте готовы.
  • Курьер отмечает в приложении, что он подъехал и ожидает.
  • Курьер звонит из приложения одним кликом и сообщает, что (поднимается, подошел и т.п.)
  • Клиент принимает заказ и вводит пинкод из приложения или СМС для подтверждения доставки.(как подпись) Чтобы курьер не мог завершить доставку заранее, если опаздывает.
  • Заказ отмечается в системе доставленным.

Плюс пара альтернативных сценариев:

  • Курьер может отметить заказ недоставленным и выбрать причину.
  • Курьер, при опоздании может выдать одной кнопкой электронный сертификат через СМС. Или сертификат приходит автоматом при несоблюдении срока доставки.

Ощущение перспективности и нужности данного проекта, конечно заряжало.

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

В итоге образовался следующий список того, что предстояло успеть сделать на хакатоне:

  • Логин в кассу доставки.
  • Отобразить текущее положение.
  • Отослать данные во внешнюю апи (координаты, взял заказ, доставил заказ).
  • Получить данные из внешнего апи (текущие заказы курьера).
  • Отослать эвент о том что взял заказ на доставку/доставил.
  • Отобразить текущее положение курьера на карте в сайте.

Основная работа, как виделось, предстояла в создании бекенда, самого приложения(после обсуждений выбрали ReactNative для разработки приложения, точнее обвязку над ним — expo.io, позволяющую вообще не писать нативного кода). В плане бекенда изначально была надежда на Ваню Зверева, как опытного в работе с нашим шаблоном сервиса и k8s (какую работу на себя он и взял). ReactNative взяли потрогать я и Андрей Сарафанов.

В 12 ночи я натолкнулся, на то, что в ReactNative плохо работает геолокация в бекграунде, если не писать нативный код, немного фрустрировался. Я решил пробовать сразу создать рабочий репозиторий для самого проекта. В итоге за вечер мне уже было понятно, как получить в expo.io текущее положение, и рисовать отдельные экраны (для логина, отображения заказа и т.п.).
Потом отпустило, когда понял что читаю документацию не expo.io фреймворка, а ReactNative.

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

В итоге, потратив на это примерно полтора часа, бросили эту идею. Совершили ошибку, когда в соответствии с шаблоном проекта пытались сделать общение не через HTTP, а через GRPC, так как никто не умел собирать GRPC-клиента для JavaScript. Через пол часа, наконец-то, мы смогли настроить общение приложения с бекендом, о чудо. Из-за этого ребята и на беке начали переделывать готовый сервер с GRPC на WebApi. 🙂 Но в это же время Глеб почти добивал деплой в k8s и плюс автодеплой по коммиту в мастер.

Как хранилище мы выбрали MySQL чтобы не рисковать хотя бы с базой (были мысли про CosmosDb).

В итоге:

  • Реализовали сохранение текущих координат курьера из приложения в базу.
  • Прикрутили RabbitMQ и подписались на сообщения о взятии курьером заказа, чтобы сразу же отображать заказ у курьера в приложении.
  • Начали сохранять себе в базу время о доставке заказа, после того как курьер нажимал кнопку в приложении. Не успели добавить отправку события обратно в реббит о том, что заказ доставлен.
  • Я сделал показ карты на странице currentorder на сайте с текущим положением курьера. Но этот функционал остался чуть-чуть недоделанным, так как на окружении не получилось настроить CORS для получения координат из нашего нового сервиса.

M87

Рома Букин, Гоша Полевой (georgepolevoy), Артём Трофимушкин

0 и OpenID Connect в эталонной реализации можно считать безопасными, а вот насчёт нашего решения — я не уверен). Мы хотели реализовать OpenID Connect провайдер, так как на данный момент у нас используется протокол аутентификации собственной разработки, и это создаёт ряд трудностей: кастомные клиентские библиотеки, неудобная работа со стороны внешних партнёров, возможно проблемы с безопасностью (всё таки OAuth2.

Эту часть мы сделали, как и провайдер, и успешно их увязали друг с другом. Мы сделали отдельный сервис, эмулирующий сервис хранения персональных данных, чтобы создать маленькую модель Country-Agnostic провайдера аутентификации, который ходил бы за персональными данными в отдельный сервис (это в перспективе дало бы возможность иметь один сервис, с помощью которого можно было бы залогиниться с учётной записью в любой стране, и при этом соответствовать GDPR и прочим ФЗ). Эта часть так же была выполнена. Далее нужно было сделать API, который был бы защищён токенами, которые выдаёт провайдер, поддерживать их интроспекцию через провайдер и отдавать защищённые данные, если запрос удовлетворял бы политикам авторизации (проверяем, что пользователь аутентифицирован по схеме Bearer, в его токене содержится определённый scope + у самого пользователя есть пермишен, разрешающий выполнение вызова). Эту часть мы сделать не успели. Последним компонентом был JavaScript клиент, которому выдавался бы токен, с помощью которого, тот вызывал бы защищённый API. То есть была готова вся функциональная часть, но не была готова фронт-эндная часть для демонстрации работоспособности всей системы.

Э-Э-Э (игруха)

Дима Афонченко, Саша Коновалов

В случае, если ты неправильно накинул колбаску, на экране появляется печальная надпись «Забраковано», а в случае, если вся колбаска накинута правильно, то появляется случайный факт о пицце. Мы сделали мини-игрушку на юньке где резвые ручки накидывают колбаску на пиццу.

Хотели сделать второй уровень с накидыванием томатов, но не успели.

Короткое продолжение: кто же победил?

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

Поэтому, в скором времени ждите от нас анонс игры с ручками, накидывающими пеппероньки на пиццу.

Поздравляем ребят! Как мог заметить внимательный читатель, победила команда «Э-Э-Э (игруха)».

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть