Привет, Хабр. Мы спонтанно провели первый внутренний хакатон. Решила поделиться с вами своими болями и выводами о подготовке к нему за 2 недели, а также проектами, которые получились.
Скучная часть для тех, кто интересуется маркетингом
Начну с маленькой истории.
Начало апреля. В нашем в офисе проходит первый хакатон MskDotNet Community. Битва за Татуин в разгаре, в нашей галактике на этот раз. Суббота. 20 команд. Пицца. Всё очень душевно (пруфы). Надувной R2-D2 маячит по залу. Команды пишут самые правильные алгоритмы, чтобы пройти самую опасную гонку на карте. Сдвигаем запуск первых заездов. Печеньки и кофе спасают. Мы с организаторами ожидали, что в субботу многие уйдут после обеда. Но нет. 12 часов кодинга позади. Финал. Что-то отваливается, что-то не запускается. Но все счастливы. Побеждает наша команда. Мы счастливы вдвойне.
Делюсь радостью в Slack и в голову приходит идея: «Надо сделать свой хакатон». Пишу нашему СТО Саше. Тишина.
Утро. Пью кофе в офисе. Вижу приближающегося из-за спины Сашу. «Лиза, это же отлично! У нас как раз 21 апреля важная дата. Давай делать!» WTF!? Так быстро? А? Что? Мне нужно улетать в Сыктывкар на стажировку в середине апреля. Да и чёрт с ним! Давай.
Остаётся 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 пицц одну от другой.
Для обучения сетки взяли самую дешёвую виртуалку в Azure на NVIDIA Tesla K80. На ней обучали в 100 эпох, но было видно, что сеть перенасытилась уже после 50 эпох, из-за того, что был маленький датасет.
Собственно — вся проблема в отсутствии хороших данных.
Мы, возможно, немного напутали в терминах, но надо учитывать, что у нас вообще нет опыта в работе со всеми этими делами.
GUI for NOOBS (консолька для заказа пиццы)
Миша Кумачёв (Ceridan), Женя Биккинин, Женя Васильев
Мы собрали прототип консольного приложения для гиков, благодаря которому можно заказать пиццу через терминал или командную строку, или даже встроить в deploy pipeline и при успешном релизе доставлять пиццу в офис.
Работа разбилась на несколько частей: разбирались, как устроен наш API для мобильных приложений, собирали свой собственный CLI с помощью oclif и настраивали публикацию собранного нами пакета. С последней задачей было связано несколько неприятных минут ближе к концу хакатона. У нас всё работало локально и даже работали старые опубликованные версии пакета, но новые (в которых было добавлено больше клёвых фич и смайликов) работать отказывались. Мы потратили минут 40, чтобы понять, что же пошло не так, но в итоге всё магическим образом само заработало).
Нашей программой максимум на хакатон был настоящий заказ пиццы в офис через нашу CLI. Мы десяток раз всё прогоняли на тестовом стенде, но у меня всё равно тряслись руки, когда я забивал команды на проде.
Как итог — мы всё-таки сделали это!
CourierGo
Антон Бружмелёв (автор), Ваня Зверев, Глеб Лесников (entropy), Андрей Сарафанов
Взяли идею «Приложение для курьера».
Предыстория про подготовку.Изначально я прикинул, а какие вообще фичи могут быть в приложении? Возник примерно такой список функционала:
Приложение логинится в кассу доставки по коду.
В приложении сразу видны доступные заказы, заказы которые нужно брать.
Курьер отмечает заказ и берет в поездку.
Ему показывается расчетное время и успевает он или нет.
Клиенту показывает что курьер выехал.
Клиенту начинает показывать точку курьера на карте и расчетное время.
Курьер может написать клиенту в чат из приложения.
Клиент может написать курьеру в чат из приложения.
За пять минут до приезда клиенту приходит сообщение что курьер близко, будьте готовы.
Курьер отмечает в приложении, что он подъехал и ожидает.
Курьер звонит из приложения одним кликом и сообщает, что (поднимается, подошел и т.п.)
Клиент принимает заказ и вводит пинкод из приложения или СМС для подтверждения доставки.(как подпись) Чтобы курьер не мог завершить доставку заранее, если опаздывает.
Заказ отмечается в системе доставленным.
Плюс пара альтернативных сценариев:
Курьер может отметить заказ недоставленным и выбрать причину.
Курьер, при опоздании может выдать одной кнопкой электронный сертификат через СМС. Или сертификат приходит автоматом при несоблюдении срока доставки.
Ощущение перспективности и нужности данного проекта, конечно заряжало.
На следующий день сходили с командой на обед и обсудили, как будет выглядеть минимальный функционал приложения.
В итоге образовался следующий список того, что предстояло успеть сделать на хакатоне:
Логин в кассу доставки.
Отобразить текущее положение.
Отослать данные во внешнюю апи (координаты, взял заказ, доставил заказ).
Получить данные из внешнего апи (текущие заказы курьера).
Отослать эвент о том что взял заказ на доставку/доставил.
Отобразить текущее положение курьера на карте в сайте.
Основная работа, как виделось, предстояла в создании бекенда, самого приложения(после обсуждений выбрали ReactNative для разработки приложения, точнее обвязку над ним — expo.io, позволяющую вообще не писать нативного кода). В плане бекенда изначально была надежда на Ваню Зверева, как опытного в работе с нашим шаблоном сервиса и k8s (какую работу на себя он и взял). ReactNative взяли потрогать я и Андрей Сарафанов.
Я решил пробовать сразу создать рабочий репозиторий для самого проекта. В 12 ночи я натолкнулся, на то, что в ReactNative плохо работает геолокация в бекграунде, если не писать нативный код, немного фрустрировался. Потом отпустило, когда понял что читаю документацию не expo.io фреймворка, а ReactNative. В итоге за вечер мне уже было понятно, как получить в expo.io текущее положение, и рисовать отдельные экраны (для логина, отображения заказа и т.п.).
С утра на хакатоне завлекли Глеба в свой сверхперспективный проект. Быстро накидали план того, что нужно сделать.
Совершили ошибку, когда в соответствии с шаблоном проекта пытались сделать общение не через HTTP, а через GRPC, так как никто не умел собирать GRPC-клиента для JavaScript. В итоге, потратив на это примерно полтора часа, бросили эту идею. Из-за этого ребята и на беке начали переделывать готовый сервер с GRPC на WebApi. Через пол часа, наконец-то, мы смогли настроить общение приложения с бекендом, о чудо. Но в это же время Глеб почти добивал деплой в k8s и плюс автодеплой по коммиту в мастер. 🙂
Как хранилище мы выбрали MySQL чтобы не рисковать хотя бы с базой (были мысли про CosmosDb).
В итоге:
Реализовали сохранение текущих координат курьера из приложения в базу.
Прикрутили RabbitMQ и подписались на сообщения о взятии курьером заказа, чтобы сразу же отображать заказ у курьера в приложении.
Начали сохранять себе в базу время о доставке заказа, после того как курьер нажимал кнопку в приложении. Не успели добавить отправку события обратно в реббит о том, что заказ доставлен.
Я сделал показ карты на странице currentorder на сайте с текущим положением курьера. Но этот функционал остался чуть-чуть недоделанным, так как на окружении не получилось настроить CORS для получения координат из нашего нового сервиса.
Мы хотели реализовать OpenID Connect провайдер, так как на данный момент у нас используется протокол аутентификации собственной разработки, и это создаёт ряд трудностей: кастомные клиентские библиотеки, неудобная работа со стороны внешних партнёров, возможно проблемы с безопасностью (всё таки OAuth2.0 и OpenID Connect в эталонной реализации можно считать безопасными, а вот насчёт нашего решения — я не уверен).
Мы сделали отдельный сервис, эмулирующий сервис хранения персональных данных, чтобы создать маленькую модель Country-Agnostic провайдера аутентификации, который ходил бы за персональными данными в отдельный сервис (это в перспективе дало бы возможность иметь один сервис, с помощью которого можно было бы залогиниться с учётной записью в любой стране, и при этом соответствовать GDPR и прочим ФЗ). Эту часть мы сделали, как и провайдер, и успешно их увязали друг с другом. Далее нужно было сделать API, который был бы защищён токенами, которые выдаёт провайдер, поддерживать их интроспекцию через провайдер и отдавать защищённые данные, если запрос удовлетворял бы политикам авторизации (проверяем, что пользователь аутентифицирован по схеме Bearer, в его токене содержится определённый scope + у самого пользователя есть пермишен, разрешающий выполнение вызова). Эта часть так же была выполнена. Последним компонентом был JavaScript клиент, которому выдавался бы токен, с помощью которого, тот вызывал бы защищённый API. Эту часть мы сделать не успели. То есть была готова вся функциональная часть, но не была готова фронт-эндная часть для демонстрации работоспособности всей системы.
Э-Э-Э (игруха)
Дима Афонченко, Саша Коновалов
Мы сделали мини-игрушку на юньке где резвые ручки накидывают колбаску на пиццу. В случае, если ты неправильно накинул колбаску, на экране появляется печальная надпись «Забраковано», а в случае, если вся колбаска накинута правильно, то появляется случайный факт о пицце.
Хотели сделать второй уровень с накидыванием томатов, но не успели.
Короткое продолжение: кто же победил?
Перед хакатоном мы общались с ребятами и я спрашивала, какой приз они хотели бы получить, если выиграют. Оказалось, что самым ценным призом будет «дорога в прод».
Поэтому, в скором времени ждите от нас анонс игры с ручками, накидывающими пеппероньки на пиццу.
Как мог заметить внимательный читатель, победила команда «Э-Э-Э (игруха)». Поздравляем ребят!
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.