Ciao, Habr. Abbiamo tenuto spontaneamente il nostro primo hackathon interno. Ho deciso di condividere con voi le mie difficoltà e le mie conclusioni sulla preparazione per questo evento in due settimane, così come i progetti che ne sono scaturiti.

La parte noiosa per chi è interessato al marketing
Iniziamo con una piccola storia.
Inizio aprile. Nel nostro ufficio si tiene il primo hackathon della MskDotNet Community. La battaglia per Tatooine è in pieno svolgimento, questa volta nella nostra galassia. Sabato. 20 squadre. Pizza. Tutto molto accogliente (). Un R2-D2 gonfiabile si aggira per la sala. Le squadre scrivono gli algoritmi più corretti per superare la gara più pericolosa sulla mappa. Posticipiamo l'inizio delle prime gare. Biscotti e caffè ci salvano. Noi, gli organizzatori, ci aspettavamo che molti se ne andassero dopo pranzo. Ma no. 12 ore di coding alle spalle. Finale. Qualcosa si rompe, qualcosa non si avvia. Ma tutti sono felici. La nostra squadra vince. Siamo doppiamente felici.
Condivido la gioia su Slack e mi viene in mente un'idea: «Dobbiamo organizzare il nostro hackathon». Scrivo al nostro CTO Sasha. Silenzio.
Mattina. Bevo un caffè in ufficio. Vedo Sasha avvicinarsi da dietro. «Lisa, è fantastico! Abbiamo una data importante il 21 aprile. Facciamolo!» Cosa?! Così in fretta? Cosa? Devo partire per Syktyvkar per uno stage a metà aprile. Ma che importa! Facciamo.
Mancano 2 settimane. Non sono mai stata l'organizzatrice principale di un hackathon. Anche se interno. Leggo articoli in merito. È una follia. Ci vogliono mesi. Servono diverse persone. Bisogna pensare a gadget, premi, regole, programma, coinvolgere tutti, capire l'obiettivo, budget. Potrei persino dover riflettere sul senso della vita. Di sicuro non ce la farò. E mentre tu leggi e ti prepari, è già passata una settimana. È tempo di smettere di leggere e iniziare a fare qualcosa.
Ecco la nostra checklist per organizzare un hackathon interno in 1 settimana.
- Piano: ti siedi con calma e scrivi un elenco di ciò che devi fare per l'hackathon. 30 minuti.
- Compito: i partecipanti propongono e scelgono i progetti che vogliono realizzare in Google Sheets. Compito secondario, 2 ore.
- Programma: scrivi rapidamente una ripartizione temporale considerando 3 pause e il finale. 20 minuti.
- Comandi: pubblichi un messaggio sul hackathon con il programma del CTO nei canali IT su Slack/email/etc. e crei un canale separato per l'hackathon. In questo canale tutti si dividono in squadre, e chi non si è ancora deciso lo fa nei primi 5 minuti dell'hackathon. Compito secondario, 2 ore.
- Vantaggi: pensi a del merchandise con due sviluppatori, lo dai al designer per il rendering, e ricevi il prodotto finito. Attività in background, 3 giorni.
- Hackathon: arrivi in ufficio, coordini tutti all'inizio, ti occupi delle tue cose, leggi Reddit, con aria importante comunichi ogni pausa riguardo la nuova pizza, fotografi il tramonto, annunci la finale, voti insieme e scegli il vincitore. 1 giorno.
- Sotto le stelle: certo, pensi costantemente che tutto vada per il verso giusto. Certo, non tutti vedranno il tuo messaggio e con alcuni è meglio parlarne di persona. Certo, se qualcuno ti aiuta, tutto diventa due volte più facile (mi ha aiutato la meravigliosa Alëna).
La parte meno noiosa riguardo alla data dell'hackathon
Perché il 21 aprile? Questa data è significativa per noi. Esattamente un anno fa, il 21 aprile, siamo crollati sotto il carico durante il primo fine settimana dopo l'inizio della Campagna Pubblicitaria Federale. Il giorno dopo, domenica, il nostro team era al lavoro dalle 8 del mattino. Allora abbiamo creato su Trello una bacheca chiamata sundayhackathon e è iniziata una settimana di lavoro a turni di 12 ore al giorno. La situazione era così critica che non avevamo nemmeno tempo per mangiare, e ci sono stati a supportarci ragazzi di altri team.

Puoi leggere una storia più dettagliata su (il nostro CEO). Da allora, abbiamo cambiato molto, ma non dimenticheremo mai questa data.
Quest'anno abbiamo deciso che questo evento meritasse di essere ricordato per le generazioni future e, seguendo le migliori tradizioni, abbiamo organizzato il primo hackathon interno nella storia di Dodo, che è durato 10 ore.
La parte più interessante riguardo ai progetti dell'hackathon
Disclaimer: tutte le descrizioni sono state scritte dai ragazzi, quindi la paternità del testo non è mia.
Oleg Learning (machine learning)
Dima Kochnev, Sasha Andronov (@alexandronov)
Volevamo creare una rete neurale capace di identificare che tipo di pizza c'era in una fotografia senza alcuna conoscenza pregressa. Alla fine, abbiamo realizzato qualcosa di molto semplice e giocattoloso: riconosce 10 tipi di pizza e abbiamo più o meno capito come funziona, per quanto sia possibile in un solo giorno (~10 ore).

In particolare, abbiamo compreso che l'industria è arrivata a un punto in cui un normale sviluppatore può utilizzare librerie pronte, leggere la documentazione e addestrare la propria rete neurale senza conoscenze approfondite dell'argomento. E sarà sufficiente per risolvere problemi reali.
Strumenti che abbiamo utilizzato:
- — una libreria comoda e semplice per lavorare con l'apprendimento automatico e la visione artificiale.
- Abbiamo provato due modelli: ResNet50 e Yolo.
- Il codice è stato scritto, ovviamente, in Python.
Avevamo 11.000 foto, ma quasi 3/4 di esse si sono rivelate scarti, mentre nelle rimanenti c'erano angolazioni varie e inadeguate. Alla fine, abbiamo utilizzato un modello predefinito (che sa semplicemente riconoscere la pizza) per separare i contenuti irrilevanti. Successivamente, nel nome della foto c'era il nome della pizza — così le abbiamo organizzate in cartelle, ma si è scoperto che i nomi non corrispondevano alla realtà ed è stato necessario fare una pulizia manuale. Alla fine, sono rimaste circa 500-600 foto. È evidente che si tratta di un numero esiguo, ma comunque è stato sufficiente per distinguere 10 pizze l'una dall'altra.
Per addestrare la rete, abbiamo utilizzato la macchina virtuale più economica disponibile su Azure con una NVIDIA Tesla K80. L'addestramento è stato eseguito per 100 epoche, ma era evidente che la rete era già saturata dopo 50 epoche, a causa delle ridotte dimensioni del dataset.
In sostanza, il problema principale è la mancanza di dati di qualità.

Forse abbiamo commesso qualche errore terminologico, ma è importante considerare che non abbiamo esperienza in questo campo.
GUI for NOOBS (console per ordinare la pizza)
Misha Kumachev (), Evgeny Bikkunin, Evgeny Vasiliev
Abbiamo creato un prototipo di un'applicazione console per veri appassionati, grazie alla quale è possibile ordinare la pizza tramite terminale o linea di comando, o addirittura integrarla nel pipeline di deploy per far consegnare la pizza in ufficio dopo un rilascio riuscito.

Il lavoro è stato suddiviso in diverse parti: abbiamo studiato come funziona la nostra API per le applicazioni mobili e costruito la nostra CLI con l'aiuto di , e abbiamo configurato la pubblicazione del pacchetto che abbiamo creato. Con quest'ultima attività abbiamo avuto alcuni momenti difficili verso la fine del hackathon. Tutto funzionava localmente e anche le vecchie versioni pubblicate del pacchetto funzionavano, ma le nuove (in cui erano state aggiunte più funzionalità e faccine divertenti) si rifiutavano di funzionare. Abbiamo impiegato circa 40 minuti per capire cosa fosse andato storto, ma alla fine, tutto ha magicamente iniziato a funzionare da solo.
Il nostro obiettivo massimo per l'hackathon era fare un vero ordine di pizza in ufficio tramite la nostra CLI. Abbiamo testato tutto una decina di volte su un ambiente di test, ma avevo comunque le mani tremanti mentre digitavo i comandi in produzione.

Il risultato finale — ce l'abbiamo fatta davvero!

CourierGo
Anton Bruzmelëv (autore), Vanya Zverev, Gleb Lesnikov (), Andrey Sarafanov
Abbiamo preso spunto dall'idea "App per il corriere".
Storia di fondo sulla preparazione.Inizialmente, ho pensato a quali funzionalità potessero esserci nell'app. È emersa più o meno una lista di funzionalità:
- L'app si autentica nel sistema di consegna con un codice.
- Nell'app sono subito visibili gli ordini disponibili, gli ordini da prendere.
- Il corriere segna l'ordine e lo prende in carico.
- Gli viene mostrato il tempo stimato e se arriverà in tempo.
- Il cliente vede che il corriere è partito.
- Al cliente inizia a essere mostrata la posizione del corriere sulla mappa e il tempo stimato.
- Il corriere può scrivere al cliente in chat dall'app.
- Il cliente può scrivere al corriere in chat dall'app.
- Cinque minuti prima dell'arrivo, il cliente riceve un messaggio che il corriere è vicino, si prepari.
- Il corriere segna nell'app che è arrivato e sta aspettando.
- Il corriere chiama dall'app con un clic e comunica che (sta salendo, è arrivato, ecc.)
- Il cliente accetta l'ordine e inserisce il pin dall'app o SMS per confermare la consegna. (come una firma) In modo che il corriere non possa completare la consegna in anticipo, se è in ritardo.
- L'ordine viene segnato nel sistema come consegnato.
In aggiunta, un paio di scenari alternativi:
- Il corriere può segnare l'ordine come non consegnato e scegliere una motivazione.
- In caso di ritardo, il corriere può emettere un certificato elettronico tramite SMS con un solo clic. Oppure il certificato viene inviato automaticamente se non viene rispettato il termine di consegna.
La sensazione di opportunità e necessità di questo progetto, ovviamente, era motivante.
Il giorno successivo, siamo andati a pranzo con il team e abbiamo discusso di come sarebbe dovuta apparire la funzionalità minima dell'applicazione.
Di conseguenza, si è formato il seguente elenco di ciò che dovevamo completare durante l'hackathon:
- Login nel sistema di consegna.
- Visualizzare la posizione attuale.
- Inviare dati a un'API esterna (coordinate, ordine preso, ordine consegnato).
- Ricevere dati da un'API esterna (ordini attuali del corriere).
- Inviare un evento riguardante il ritiro dell'ordine per la consegna/ritiro effettuato.
- Visualizzare la posizione attuale del corriere sulla mappa nel sito.
Il lavoro principale, come si percepiva, sarebbe stato nella creazione del backend, dell'applicazione stessa (dopo discussioni abbiamo scelto ReactNative per lo sviluppo dell'app, più precisamente la sua interfaccia — , che consente di non scrivere affatto codice nativo). Per quanto riguarda il backend, inizialmente c'era speranza in Vanya Zverev, esperto nel lavorare con il nostro template di servizio e k8s (lavoro che ha preso su di sé). Io e Andrey Sarafanov ci siamo messi a provare ReactNative.
Ho deciso di provare subito a creare un repository di lavoro per il progetto. A mezzanotte mi sono reso conto che in ReactNative la geolocalizzazione funziona male in background, a meno che non si scriva codice nativo, il che mi ha un po' frustrato. Poi mi sono calmato, quando ho capito che stavo leggendo la documentazione di ReactNative invece di quella del framework expo.io. Alla fine della serata, mi era già chiaro come ottenere la posizione attuale in expo.io e disegnare diversi schermi (per il login, visualizzazione dell'ordine, ecc.).

La mattina del hackathon ho coinvolto Gleb nel nostro progetto super promettente. Abbiamo rapidamente abbozzato un piano di ciò che c'era da fare.

Abbiamo commesso un errore tentando di comunicare non tramite HTTP ma tramite GRPC, poiché nessuno sapeva come assemblare un client GRPC per JavaScript. Dopo aver speso circa un'ora e mezza, abbiamo abbandonato questa idea. A causa di ciò, il team ha iniziato a rifare il server da GRPC a WebApi. Dopo mezz'ora, finalmente, siamo riusciti a configurare la comunicazione tra l'applicazione e il backend, che meraviglia. Ma nello stesso tempo, Gleb stava quasi completando il deployment in k8s e l'autodeployment al commit nel master. 🙂
Come database, abbiamo scelto MySQL per non rischiare almeno con la base (c'erano idee su CosmosDb).

In sintesi:
- Abbiamo implementato il salvataggio delle coordinate attuali del corriere dall'app in database.
- Abbiamo integrato RabbitMQ e ci siamo iscritti ai messaggi riguardanti l'accettazione dell'ordine da parte del corriere, per visualizzare immediatamente l'ordine nell'app del corriere.
- Abbiamo iniziato a salvare nel database il tempo di consegna dell'ordine, dopo che il corriere premeva il pulsante nell'app. Non siamo riusciti ad aggiungere l'invio dell'evento di ritorno a RabbitMQ che segnala che l'ordine è stato consegnato.
- Ho implementato una visualizzazione della mappa nella pagina currentorder del sito, mostrando la posizione attuale del corriere. Tuttavia, questa funzionalità è rimasta leggermente incompleta, poiché non siamo riusciti a configurare il CORS per ottenere le coordinate dal nostro nuovo servizio.
M87
Roma Bukin, Gosha Polevoy (), Artyom Trofimushkin
Volevamo implementare un provider OpenID Connect, poiché attualmente utilizziamo un protocollo di autenticazione di nostra creazione, il che comporta diverse difficoltà: librerie client personalizzate, lavoro poco pratico da parte dei partner esterni e possibili problemi di sicurezza (dopo tutto, OAuth2.0 e OpenID Connect nella loro implementazione standard possono essere considerati sicuri, mentre riguardo alla nostra soluzione — non ne sono sicuro).

Abbiamo creato un servizio dedicato che emula un servizio di archiviazione dei dati personali, per sviluppare un modello di provider di autenticazione senza confini nazionali, in grado di richiedere dati personali da un servizio separato. Questo, nel lungo termine, permetterebbe di avere un unico servizio tramite il quale sarebbe possibile effettuare il login con un account in qualsiasi paese, rispettando nel contempo il GDPR e altre leggi locali. Questa parte è stata completata, così come il provider, e abbiamo riuscito a collegarli con successo. Successivamente, era necessario realizzare un API protetto con token emessi dal provider, supportando l'introspezione tramite il provider e restituendo dati protetti se la richiesta soddisfacesse le politiche di autorizzazione (verifichiamo che l'utente sia autenticato tramite lo schema Bearer, il suo token contiene un determinato scope e l'utente stesso possiede un permesso che consente l'esecuzione della chiamata). Anche questa parte è stata completata. L'ultimo componente era un client JavaScript, al quale sarebbe stato fornito un token, che utilizzava per richiamare l'API protetta. Questa parte non è stata completata. In altre parole, tutta la parte funzionale era pronta, ma non era stata ancora ultimata la parte front-end per dimostrare il funzionamento dell'intero sistema.
E-E-E (gioco)
Dima Afonchenko, Sasha Konovalov
Abbiamo realizzato un mini-gioco dove le mani agili lanciano la salsiccia sulla pizza. Se lanci la salsiccia nel modo sbagliato, sullo schermo appare la triste scritta "Scartata", mentre se la salsiccia è lanciata correttamente, appare un fatto casuale sulla pizza.

Volevamo creare un secondo livello con i pomodori, ma non siamo riusciti in tempo.

Breve continuazione: chi ha vinto?
Prima del hackathon, abbiamo parlato con i ragazzi e io chiedevo quale premio avrebbero voluto ricevere in caso di vittoria. Si è scoperto che il premio più prezioso sarebbe stato "il passaggio alla produzione".

Pertanto, a breve aspettate da noi l'annuncio di un gioco con le mani che lanciano peperoni sulla pizza.
Come potrebbe notare un attento lettore, ha vinto il team "E-E-E (gioco)". Congratulazioni ragazzi!
Solo gli utenti registrati possono partecipare al sondaggio. , per favore.
Quale progetto ti è piaciuto di più?
Oleg Learning (machine learning)
GUI per NOOBS
CourierGo
M87
E-E-E
Hanno votato 5 utenti. 3 utenti si sono astenuti.
Fonte: habr.com
