Здравейте, Хабр. Ние спонтанно проведохме първия вътрешен хакатон. Реших да споделя с вас мойте тревоги и изводи относно подготовката за него за 2 седмици, както и проектите, които се получиха.

Скучната част за тези, които се интересуват от маркетинг
Ще започна с малка история.
Началото на април. В нашия офис се провежда първият хакатон на MskDotNet Community. Битката за Татуин е в разгара си в нашата галактика. Събота. 20 отбора. Пица. Всичко е много сърдечно (). Надуваемият R2-D2 се мъчи в залата. Отборите пишат най-правилните алгоритми, за да преминат най-опасното състезание на картата. Забавяме старта на първите стартове. Бисквити и кафе спасяват. С организаторите очаквахме, че в събота много отбори ще напуснат след обяд. Но не. 12 часа кодиране зад гърба. Финал. Нещо се разпада, нещо не се стартира. Но всички са щастливи. Побеждава нашият отбор. Ние сме щастливи двойно.
Споделям радостта в Slack и в главата ми идва идеята: 'Трябва да направим свой собствен хакатон.' Пиша на нашия CTO Саша. Тишина.
Сутрин. Пия кафе в офиса. Виждам Саша, който приближава отзад. 'Лиза, това е страхотно! Имаме важна дати на 21 април. Да го направим!' WTF!? Така бързо? А? Какво? Трябва да замина за Сыктывкар на стажировка в средата на април. Да и какво от това! Давай.
Остават 2 седмици. Никога не съм била единоличен организатор на хакатон. Нека и да е вътрешен. Чета статии на тази тема. Ужас. Нужно е няколко месеца. Нужно е няколко човека. Трябва да измислям мърч, награди, условия, график, да заинтересувам, да разбера целта, бюджети. А може би дори да разбера смисъла на живота. Определено няма да успея. И докато четеш и се подготвяш, вече е изминала седмица. Най-доброто време е да забравиш за статиите и да започнеш да правиш нещо.
Хванете нашия чеклист за провеждане на вътрешен хакатон за 1 седмица
- План: спокойно сядаш и пишеш списък с нещата, които трябва да направиш за хакатона. 30 минути.
- Задача: участниците сами предлагат и избират проекти, които искат да създадат в Google Sheets. Фонова задача, 2 часа.
- График: на коляно пишеш кратко разбиване по време, включващо 3 почивки и финал. 20 минути.
- Отбори: публикуваш съобщение за хакатона с графика от CTO в IT каналите в Slack/имейл/и т.н. и създаваш отделен канал за хакатона. В него всички се разделят на отбори, а неопределените правят това в първите 5 минути на хакатона. Фонова задача, 2 часа.
- Допълнителни предимства: създаваш мърч с двама разработчици, предаваш на дизайнера за рисуване, получаваш готовия продукт. Фоново задание, 3 дни.
- Хакатон: идваш в офиса, координираш всички в началото, занимаваш се със свои неща, четеш Reddit, с важен вид известяваш за свежа пица на всяка пауза, снимаш залеза, обявяваш финала, заедно гласувате и избирате победителя. 1 ден.
- Под звездичката: разбира се, постоянно мислиш за това как всичко да мине добре. Разбира се, не всички ще видят съобщението ти и с някои е по-добре да говориш лично. Разбира се, ако имаш някой, който да ти помага, всичко ще стане два пъти по-лесно (невероятната Алена ми помогна).
По-малко скучната част за датата на хакатона
Защо 21 април? Този ден е значим за нас. Точно една година по-рано, на 21 април, паднахме под натоварване по време на първите уикенди след старта на Федералната Рекламна Кампания. На следващия ден, в неделя, екипът ни беше на работа от 8 сутринта. Тогава създадохме в Trello дъската sundayhackathon и започнахме седмица на сменна работа по 12 часа на ден. Положението беше толкова критично, че нямаше време да ядем и ни подхранваха момчетата от другите екипи.

По-подробния разказ може да прочетете на (нашия CEO). От тогава много се промени, но датата вече определено няма да я забравим.
Тази година решихме, че събитието трябва да остане в паметта на поколенията и в най-добрите традиции организирахме първия в историята на Додо вътрешен хакатон, който продължи 10 часа.
Най-нескучната част за проектите на хакатона
Отказ от отговорност: всички описания са написани от самите момчета, така че авторството на текста не е мое.
Олег Лърнинг (машинно обучение)
Дима Кочнев, Саша Андронов (@alexandronov)
Искаха да направят невронна мрежа, която да определя каква пица е на снимката без каквито и да било знания. В крайна сметка направиха много проста и играчка – тя разпознава 10 пици, приблизително разбрахме как всичко е устроено, доколкото е възможно за един ден (~10 часа).

По-конкретно, разбрахме, че индустрията е достигнала ниво, при което обикновен разработчик може да вземе готови библиотеки, да прочете документацията и да обучи своята невронна мрежа без дълбоки познания по темата. И тя ще работи достатъчно добре за решаване на реални задачи.
Инструменти, които използвахме:
- — удобна и проста библиотека за работа с машинно обучение и компютърно зрение.
- Изпробвахме две модели – ResNet50 и Yolo.
- Кодът е написан, разбира се, на Python.
Събрахме 11000 снимки, но почти 3/4 от тях се оказаха боклук, а в останалите имаше различни неподходящи ъгли. В крайна сметка използвахме готова модел (който просто може да открива пица) и с негова помощ отделихме най-лошото. След това, в името на снимката имаше името на пицата – така разпределихме по папки, но се оказа, че имената не съвпадат с реалността и тук вече трябваше да почистим на ръка. В крайна сметка останаха около 500-600 снимки; разбира се, че това е нищожно количество, но все пак, това беше достатъчно, за да разграничим 10 пици една от друга.
За обучението на мрежата взехме най-евтината виртуалка в Azure с NVIDIA Tesla K80. На нея тренирахме в 100 епохи, но беше видимо, че мрежата е пренаситена още след 50 епохи, поради малкия датасет.
Собствено казано – целият проблем е в липсата на добри данни.

Може би малко объркахме термините, но трябва да се има предвид, че нямаме никакъв опит в работа с всичките тези неща.
GUI for NOOBS (конзола за поръчка на пица)
Миша Кумачёв (), Женя Биккинин, Женя Василев
Създадохме прототип на конзолно приложение за гикове, с помощта на което може да се поръча пица през терминала или командния ред, или дори да се вгради в процеса на разполагане и при успешен релиз да се достави пица в офиса.

Работата се раздели на няколко части: разучавахме как е структуриран нашият API за мобилни приложения, изграждахме собствен CLI с помощта на и настройвахме публикуването на нашия пакет. С последната задача свързана бяха няколко неприятни минути към края на хакатона. Всичко работеше локално, дори работеха старите публикувани версии на пакета, но новите (в които бяха добавени повече готини функции и емоджита) отказваха да работят. Похарчихме около 40 минути, за да разберем какво е станало, но в крайна сметка странно всичко работи само по себе си).
Нашата главна цел на хакатона беше истинска поръчка на пица в офиса чрез нашия CLI. Десетина пъти всичко преминахме на тестов стенд, но все пак ръцете ми трепереха, когато набирах командите на продукцията.

В крайна сметка – все пак успяхме!

CourierGo
Антон Бружмелёв (автор), Ваня Зверев, Глеб Лесников (), Андрей Сарафанов
Взехме идеята за "Приложение за куриери".
Предистория за подготовката.Първоначално помислих какви функции могат да бъдат в приложението. Получи се приблизително следният списък с функционалности:
- Приложението логва в системата за доставки с код.
- В приложението веднага се виждат наличните поръчки, поръчките, които трябва да се вземат.
- Куриерът маркира поръчката и я взима за изпълнение.
- Показва му се приблизителното време за пристигане и дали ще успее или не.
- На клиента му се показва, че куриерът е тръгнал.
- Клиентът започва да вижда местоположението на куриера на картата и приблизителното време.
- Куриерът може да пише на клиента в чата през приложението.
- Клиентът може да пише на куриера в чата през приложението.
- Пет минути преди пристигането клиентът получава съобщение, че куриерът е близо, бъдете готови.
- Куриерът маркира в приложението, че е пристигнал и чака.
- Куриерът може да се обади от приложението с едно кликване и да съобщи, че (идва, пристигна и т.н.)
- Клиентът приема поръчката и въвежда пинкод от приложението или SMS за потвърждение на доставката. (като подпис) За да не може куриерът да завърши доставката предварително, ако закъснява.
- Поръчката се маркира в системата като доставена.
Плюс няколко алтернативни сценария:
- Куриерът може да маркира поръчката като недоставена и да избере причина.
- Куриерът, при закъснение, може с едно натискане да издаде електронен сертификат чрез SMS. Или сертификатът идва автоматично при неспазване на срока за доставка.
Чувството за перспективността и необходимостта от този проект, разбира се, зареждаше.
На следващия ден отидохме с екипа на обяд и обсъдихме как ще изглежда минималният функционал на приложението.
В крайна сметка се оформи следният списък с това, което трябваше да успеем да направим на хакатона:
- Вход в системата за доставки.
- Показване на текущото местоположение.
- Изпращане на данни към външно API (координати, взета поръчка, доставена поръчка).
- Получаване на данни от външно API (текущи поръчки на куриера).
- Изпращане на събитие, че е взета поръчката за доставка/доставена.
- Показване на текущото местоположение на куриера на картата на сайта.
Основната работа, както изглеждаше, беше в създаването на бекенда, самото приложение (след обсъждания избрахме ReactNative за разработка на приложението, по-точно обвивка над него — , което позволява изобщо да не се пише роден код). Първоначално имаше надежда за бекенда на Ваня Зверев, като опитен работник с нашия шаблон на услугата и k8s (каква работа той пое). ReactNative поехме малко да проучим с Андрей Сарафанов.
Реших да опитам веднага да създам работен репозитори за самия проект. В 12 часа през нощта попаднах на проблем с геолокацията в ReactNative, когато е активен фон, ако не се пише роден код, малко се фрустрирах. След това се успокоих, когато осъзнах, че чета документацията на expo.io фреймворка, а не на ReactNative. В крайна сметка, за вечерта вече разбрах как да получа текущото си местоположение в expo.io и да рисувам отделни екрани (за вход, показване на поръчка и т.н.).

Сутринта на хакатона привлечехме Глеб в нашия суперперспективен проект. Бързо очертахме какво трябва да се направи.

Събрахме грешка, когато в съответствие с шаблона на проекта се опитахме да осъществим комуникация не чрез HTTP, а чрез GRPC, тъй като никой не умееше да сглобява GRPC-клиент за JavaScript. В крайна сметка, след като прекарахме около един час и половина, се отказахме от тази идея. Поради това, момчетата на бекенда започнаха да прекрояват готовия сървър от GRPC на WebApi. След половин час най-накрая успяхме да настроим комуникацията между приложението и бекенда, о чудо. Но по това време Глеб почти завърши внедряването в k8s и добави автоматично внедряване при комит в мастер. 🙂
Избрахме MySQL за хранилище, за да не рискуваме поне с базата (имахме идеи за CosmosDb).

В крайна сметка:
- Реализирахме запазването на текущите координати на куриера от приложението в базата.
- Включихме RabbitMQ и се абонирахме за съобщения за вземането на поръчката от куриера, за да покажем веднага поръчката в приложението на куриера.
- Започнахме да запазваме в базата времето за доставка на поръчката, след като куриерът натисне бутона в приложението. Не успяхме да добавим изпращането на събитие обратно в RabbitMQ, че поръчката е доставена.
- Направих показ на картата на страницата currentorder на сайта с текущото положение на куриера. Но тази функционалност остана малко недовършена, тъй като не успяхме да настроим CORS за получаване на координатите от нашия нов сервис.
M87
Рома Букин, Гоша Полевой (), Артём Трофимушкин
Искахме да реализираме OpenID Connect доставчик, тъй като в момента използваме протокол за удостоверяване, разработен от нас, и това създава редица трудности: кастомни клиентски библиотеки, неудобна работа от страна на външни партньори, възможни проблеми с безопасността (все пак OAuth2.0 и OpenID Connect в еталонната си реализация могат да се считат за безопасни, а за нашето решение — не съм сигурен).

Създадохме отделен сервиз, който емулира услуга за съхранение на лични данни, за да изградим малка модел на Country-Agnostic доставчик на удостоверяване, който да поисква лични данни от отделен сервис (това в перспектива би дало възможност за съществуването на един сервис, чрез който можеш да се логнеш с акаунт от всяка страна и да отговаряш на GDPR и други законодателства). Тази част я направихме, както и доставчика, и успешно ги свързахме помежду им. След това беше необходимо да направим API, което да бъде защитено с токени, издавани от доставчика, да поддържа тяхната интроспекция през доставчика, и да предоставя защитени данни, ако запитването отговаря на политиките за разрешение (проверяваме дали потребителят е удостоверен по схемата Bearer, в неговия токен съдържа определен обхват + самият потребител има разрешение, което позволява извършването на извикването). Тази част също беше извършена. Последният компонент беше JavaScript клиент, на който се издаваше токен, с който той да извиква защитеното API. Тази част не успяхме да направим. Тоест, всички функционални части бяха готови, но не беше готова фронтенд част за демонстриране на работата на цялата система.
Е-Е-Е (играчка)
Дима Афонченко, Саша Коновалов
Направихме мини-играчка на юнк, където весели ръчички подхвърлят колбаска на пица. В случай, че неправилно подхвърлиш колбаската, на екрана се появява тъжно съобщение «Отказано», а при правилно подхвърляне на цялата колбаска, се появява случайно факти за пицата.

Искахме да направим второ ниво с подхвърляне на домати, но не успяхме.

Кратко продължение: кой спечели?
Преди хакатона разговаряхме с момчетата и питах каква награда биха искали да получат, ако спечелят. Оказа се, че най-ценната награда ще бъде «пътят до прод».

Затова, в близко бъдеще очаквайте от нас анонс на игра с ръчички, които слагат пеперони на пицата.
Както може да забележи внимателният читател, спечели отборът "Е-Е-Е (игруха)". Поздравления на момчетата!
Само регистрирани потребители могат да участват в анкетата. , моля.
Кой проект ви хареса най-много?
Олег Лърнинг (машинно обучение)
GUI за НОВАЦИ
CourierGo
M87
Е-Е-Е
Гласували са 5 потребители. 3 потребители се въздържаха.
Източник: habr.com
