lundi 11 février 2013

CodeStory 2013 : l'addiction inattendue

Introduction

Qui ne connait pas CodeStory ? Voir cette page pour tout savoir, mais j'imagine que les développeurs passionnés, comme moi, connaissent, au moins de nom.

Pour ma part, j'avais suivi l'édition 2012 de loin. J'étais allé voir le sujet de pré-sélection, et je ne m'étais pas lancé dans l'aventure : je ne me sentais pas à la hauteur, et le sujet ne m'inspirait pas vu le peu de temps que je pouvais envisager d'y consacrer.

Pourquoi pas ? Pour voir ...

Cette année, lorsque j'ai vu passer l'annonce sur Twitter, par curiosité, je suis allé voir le sujet. Et là surprise, pas grand chose, à part qu'il faut implémenter et déployer un serveur WEB pour répondre à une seule requête "Quelle est ton adresse mail ?".


En plus, quelques semaines plus tôt, au coding-dojo du CARA, nous avions étudié le code Kittenmash de David Gageot, et je voulais tester Simple Framework que j'avais déjà noté dans mes tablettes depuis un bon moment.

Dernier facteur déclenchant, Nicolas Deloof propose via Twitter un hébergement sur CloudBees pour CodeStory.

J'avais donc là un sujet tout trouvé pour faire quelques expérimentations, et assouvir ma curiosité : mais qu'y a-t-il dans ce CodeStory après cette première requête ? Donc, 16 janvier, c'est parti pour la mise en place du squelette de mon application, avec une première implémentation minimale pour la première question.

C'est parti !

Après avoir un peu bataillé avec quelques mises au point pour mon déploiement, et la mise en place d'un script pour déployer au plus vite, en tout agilité bien sûr, ça y est, mon serveur reçoit la première requête et dans la foulée la seconde question "Es tu heureux de participer(OUI/NON)". Facile, j'implémente ma réponse "OUI" et je déploie. 

A peine le temps de chercher un café et une nouvelle question : "Es tu abonne a la mailing list(OUI/NON)". Arg, quelle liste ? Mince, j'ai pas l'info, je ne suis inscrit nulle part ... Et la requête se répète toutes les 10'. Je ne vais tout de même pas rester coincer à ce stade ? .... Je cherche, j'écris à David, je fouille sur twitter, ça parle d'une liste, je la trouve, Jean-Laurent me répond : ça y est, je suis inscrit : yes ! J'implémente un joli "OUI" et je déploie ...

En fin de journée (et oui, pas que ça à faire), je regarde les logs de mon serveur, et nouvelle question "Es tu pret a recevoir une enonce au format markdown par http post(OUI/NON)". OK, pas de problème, j'implémente encore un "OUI" ! 

Je me prépare pour aller me coucher mais voilà la nouvelle question "Est ce que tu reponds toujours oui(OUI/NON)". Ah les gars, vous êtes des rigolos, je me marre un bon coup et j'implémente cette fois un joli "NON" pour aller me coucher.

L'addiction

Mais non ! Voilà l'énoncé qui arrive pour "L'échoppe de monade sur Scalaskel". Quel délire cet énoncé, mais trop tard pour réfléchir et faut se coucher.

Mais la question suivante arrive : "As tu bien recu le premier enonce(OUI/NON)". OK je répond "OUI" et j'arrête, on verra demain ...

Arg, la première requête arrive avec la valeur "1". OK, pas encore besoin de réfléchir à l'algo, suffit de répondre "1 foo". Par contre, mon code n'est plus propre. Pas de problème, j'adore le CleanCode : je refactore, je structure, je met en place l'architecture pour traiter cet exercice, et je réponds simplement "1 foo", et je déploie ...

Il est 1h du matin, je me rends compte que je suis devenu addict à ce truc de fou, et je ne peux plus m'arrêter ! La requête suivante m'envoie la valeur "2", suffit de répondre "2 foo". Et la troisième enchaine avec la valeur "3".

OK, je vais pas implémenter des "if" pour toutes les valeurs possibles, à ce stade il me suffit de renvoyer le même nombre de foo que la valeur reçue. J'implémente, je déploie, et là, évidemment, sur le serveur, les requêtes s’enchaînent pour "3", "4", "5" .... mais ça bloque à "8", la réponse est évidemment plus complexe !

Bon, j'arrive enfin à décrocher, je m'endorre sur le clavier. Je vais me coucher, mais cet algo me travaille, je ne m’endors pas ... et après quelques minutes, je trouve une solution simple ... je ne vais quand même pas me relever ? Non, l'ordi est éteint ...

Ça déroule ! ...

Le lendemain, c'est samedi, pas trop beau temps, alors ... CodeStory ! J'implémente mon algo, je déploie et je surveille les logs : les requêtes s’enchaînent rapidement, avec des valeurs de plus en plus grandes, mon algo semble bon puisque les requêtes ne sont pas répétées, cool !

Puis c'est la surprise avec une requête "1 1" ... Quoi ? Comment ? "1 1" ? Ca veut dire quoi ? Le temps de me réveiller un peu (et oui, j'avais repris assez tôt le matin, arg), et je me souviens avoir vu passer sur Twitter "Je réponds quoi à '1 1' ?" puis, par le même auteur, "Ah oui, que j'suis bête !" ... Mince, serais-je bête, moi ? 

OK, l'explication arrive vite, la requête reçu est "?q=1+1" que mon implémentation décode en "1 1" (le + est utilisé pour les espaces dans les requêtes). Bon, ben j'implémente la réponse en dure, donc "2". Ca passe, et je reçois la suivante "2+2". Dans la même logique d'approche agile, itérative et minimaliste, j'implémente la réponse "4" avec un "if". Et une nouvelle requête arrive "3+3".

C'est le moment de réfléchir et de faire mieux que des "if". Après une première idée et des tests non motivant d'utilisation de javax.script.ScriptEngine, j'ai rapidement l'idée d'utiliser Groovy que je n'ai jamais pratiqué mais je sens que ça pourrait être pas mal. Effectivement, GroovyShell permet d'évaluer une expression. Quelques validation avec les tests unitaires (que j'utilise depuis le début, évidemment mais non précisé) et je deploie cette solution.

Je dois avouer avoir eu ensuite un grand plaisir à voir passer rapidement des requêtes de plus en plus compliquées et ma solution qui répondait juste ! A part quelques mises au point (entre "," et "."), je suis rapidement arrivé au bout de cet exercice. J'ai également eu apparemment un peu de chance, sur les très grands nombres, puisque Groovy a une implémentation qui les supporte bien.

... puis ça se complique !

Après une question détente ("As tu passe une bonne nuit malgre les bugs de l etape precedente(PAS_TOP/BOF/QUELS_BUGS)"), je reçois l'énoncé du second exercice : "Location d’astronef sur Jajascript". 

Le sujet n'est pas si compliqué, je commence à penser à un algo simple, mais les tweets qui passent et les résultats (qui stagnent) sur http://status.code-story.net/ me laisse présager quelques difficultés.

Après un bon refactoring pour faire évoluer l'architecture et répondre à ces nouvelles requêtes, je commence comme pour les autres exercices : le plus simplement ! La première requête donne 1 voyage, la réponse est donc simple avec ce voyage. La seconde requête donne 2 voyages, la réponse est simple, c'est la somme des 2 voyages. C'est donc à partir de la 3e requête que j'ai implémenté mon algorithme.

Une fois déployé, je suis content, ça répond à un bon nombre de requêtes qui sont de plus en plus grosses puis .... ça se bloque. Petite analyse de la situation : mon serveur met trop de temps à répondre ! Aïe, c'est bien ce que je pensais, ces histoires de "performances" vont se jouer ici !

Après une première amélioration de mon algo, je réponds à 1 requête supplémentaire mais pas plus. 

C'est la fin 

C'est l'heure du bilan car j'ai consacré à Code Story 2013 largement le temps initialement prévu, c'est-à-dire pas beaucoup (ou du moins pas trop). Et puis, je voulais juste "voir" et au final, je me suis bien marré ! Sans compter que du côté classement, je suis dans la première moitié, mon honneur est sauve.

Je tenterai quelques optimisations mineures, qui n'apporteront pas grand chose, et je resterai un peu frustré tout de même d'être obligé de jeter l'éponge à ce stade, pour une histoire d'algo sur lequel je ne peux pas me pencher plus pour trouver une bonne solution.

Conclusion

Je me suis lancé dans cette aventure sans rien en attendre de particulier, juste par curiosité, parce que le sujet initial était simple, et par un concours de circonstances.

Au final, je me suis éclaté en passant de bon moment de coding.

J'ai particulièrement bien aimé le côté "découverte" de ce qu'il fallait faire, au fur et à mesure, sans explications, mais toujours avec des éléments très intuitifs.

Et en agiliste pratiquant, j'ai également bien apprécié cette approche ne permettant pas de savoir ce qu'il faudrait faire par le suite, forçant à des implémentations simples pour commencer, mais nécessitant régulièrement des refactorings pour faire évoluer l'architecture de sa solution.

La surprise !

Début février, j'avais croisé David Gageot lors de #iutagile, je lui avais fait un petit retour de ma participation, et il m'avait dit qu'une cinquantaine de personnes serait retenues pour la finale à Paris. Je ne comptais pas être sélectionné, ça n'était pas du tout dans mes objectifs, et d'ailleurs, je n'avais rien reçu, et je n'étais pas dans la liste que j'avais vu passer ...

Mais ce matin, surprise dans les mails, message de Jean-Laurent de Morlhon : "Tu as été sélectionné pour la phase finale de CodeStory 2013". J'avoue être très surpris, à la fois content mais un peu stressé à l'idée de me retrouver en final avec des personnes ayant atteint un score de 35/35, et surtout une note de performance de 10000/10000, je me suis arrêté à 5/10000 ;-). Mais bon, pourquoi pas, surtout pour aller chez Google, si je me trouve un binôme "Java, CleanCode et solutions simples" qui, comme moi, irait à cette soirée pour se marrer et passer un bon moment ...

A suivre ? .....

2 commentaires:

  1. Sympa ce petit retour sur ta participation à CodeStory ! Je connaissais de nom et avais assisté à une séance lors de Devoxx 2012 (qui m'avait beaucoup impressionné d'ailleurs !).

    RépondreSupprimer
    Réponses
    1. Merci Rémi. Et pour l'instant, je suis déjà impressionné à l'idée d'aller à Paris chez Google et me retrouver avec des mecs qui ont fait 10000/10000 ...

      Supprimer