Du code commenté et documenté pour Noël

Il m’arrive assez souvent de pondre un article aux environs de Noël, voire le jour même, car c’est le moment où je suis en vacances. Comme plein de monde, en fait.

Comme promis le mois dernier, j’ai rangé et commenté le code de ma petite animation pour la vidéo-boulette de l’UTBM. C’est dans mon repository git, par ici : https://github.com/darkrecher/anim-tunnel-utbm

J’ai fini un autre mini-projet sur lequel j’avançais par intermittence depuis quelques mois : compléter un challenge de niveau « très difficile » sur le site CodinGame.

Il s’agit du challenge « Vox Codei – épisode 2 ». Des vilains carrés rouges se déplacent sur un quadrillage, il faut déterminer les coordonnées où placer des bombes pour les détruire.

Cliquez sur l’image pour accéder au challenge (il vous faut un compte CodinGame).

Boum !

J’en ai profité pour utiliser « aboard », ma librairie de code gérant des plateaux de jeux en 2D. Je vous en avais déjà parlé, fouillez dans mes anciens articles ou dans mes repo git si ça vous intéresse.

Petit conseil pour les jeux dans CodinGame

Que ce soit des challenges ou des combats de bots : respectez le rythme des échanges stdin/stdout entre votre code et le jeu. À chaque tour de jeu, récupérez bien les infos qui vous sont envoyées en appelant des fonctions « input() », même si vous n’en faites rien.

Dans Vox Codei, la situation du plateau de jeu, avec les positions des carrés rouges, vous est transmise à chaque tour. Et à chaque tour, vous devez renvoyer soit le texte « WAIT », soit les coordonnées d’une bombe à poser.

Les mouvements des carrés rouges sont assez simples. Au bout de quelques tours, il est possible de les extrapoler. Vous n’aurez donc plus besoin des infos transmises par le jeu. J’avais pris la décision de ne plus les lire, et de simplement renvoyer mon WAIT ou mes coordonnées.

Eh bien ça met le jeu dans les choux.

Comme vous ne récupérez rien, le jeu croit que vous en êtes resté au début. Il attend, et au bout d’un moment, considère que c’est votre code qui est dans les choux. Il y a en effet un temps limite d’exécution pour chaque tour. Le jeu arrête votre programme si celui-ci est dépassé, pour les cas où vous auriez envoyé du code pourri comportant une boucle infinie.

Vous êtes alors averti d’un message d’erreur indiquant, en substance : « Désolé gros con, on a killé ton process car on le suspectait de glander. Corrige ton code de merde. Respect et robustesse. » Sauf que votre code n’est pas spécialement lent, c’est juste qu’il n’exécute pas les input() permettant de vider régulièrement le buffer d’entrée-sortie entre vous et le jeu.

De la doc publiée mais pas publique

Ce mini-projet m’ayant pris un peu de temps, je me suis dit que ça méritait une petite documentation, que j’ai directement écrite dans le code. Ensuite, j’ai publié le tout sur CodinGame.

Le problème, c’est que seuls les gens ayant déjà résolu le challenge ont accès aux solutions publiées par les autres. Je me suis donc cassé le fondement à décrire et commenter un algo dont seules 258 personnes pourront profiter. Ce qu’elles ne feront pas forcément car rien ne dit que ça les intéressera.

Tant pis pour la gloire. Je me console en me disant que j’ai réussi une chose que seules 258 autres personnes dans le monde ont réussie.

Joyeux Noël quand même

Voici pour l’occasion Meagan Kerr et ses dents du bonheur.

 

Jouez avec un phrase-bizarre-otron

Coucou !

Petit article rapide.

J’ai participé à un concours de code, sur le thème : « réalisez un truc qui ressemble plus ou moins à de l’intelligence artificielle ».

J’ai créé un programme qui lit un roman et génère des phrases bizarres à partir de ça. Elles sont (presque) grammaticalement correctes, mais n’ont aucun sens.

Vous pouvez l’essayer ici : https://repl.it/talk/challenge/FrankenPhrase/10740

Comme romans, j’ai mis :

  • En français :
    • 20 000 Lieues Sous Les Mers
    • Les Trois Mousquetaires
  • En anglais
    • Frankenstein
    • The Story of Nuclear Energy, de Isaac Asimov.
  • Plus, ceux que vous voulez, si vous prenez le temps de les uploader, tout en lisant la doc d’utilisation.

Ça fait parfois des phrases marrantes :

« Quelques explications, un coup de pintadines, je vous souhaiter que les oubliettes. »

« Que Votre Éminence, qui, et, le jeune femme que dit Aramis, traversant la reine. »

ou parfois des choses poétiques :

« C’était alors la conversation sur son sein des monocentres, plus facile. »

« La surface de latitude nord, je passerai sous nos yeux une grande dépense du fleuve de toi. »

Si vous avez le temps, inscrivez-vous sur le site et laissez-moi un petit upvote.

La méthode de génération est super simple : c’est juste des statistiques par rapport aux fréquences d’apparition des mots. Par exemple, le mot « géantes » apparaît plus souvent à côté du mot « fesses » que du mot « tripoter ».

Pas d’analyse sémantique, on ne cherche pas à identifier les verbes, les sujets, ou autres. Pas de réseaux de neurones non plus. En fait je sais même pas si ce que j’ai fait peut être considéré comme de l’I.A. ou même du machine learning.

En tout cas, c’est assez rigolo. Ça donne des textes surréalistes, un peu à la André Breton.

André Breton me fait penser aux bretons me fait penser aux bretonnes me fait penser à une vidéo intitulée « Dominique la grosse bretonne ».

Voilà.

 

Solution alzheimerienne des tours de Hanoï

Comme promis, voici le deuxième article du mois. Ça fait un certain nombre de fois que je publie des articles courts, donc je voulais me rattraper.

Par contre, j’ai jamais promis que ce deuxième article serait intéressant.

Il s’agit céans d’un petit bout de code en python, résolvant le problème des tours de Hanoï de manière alzheimerienne.

Je vous en avais parlé il y a quelques années.

La manière alzheimerienne impose de ne pas se souvenir des coups joués précédemment, et de ne pas partir dans des trips de récursivité sous acide.

Le coup à jouer est déduit uniquement de la situation courante, c’est à dire la position des disques. Vous pouvez donc appliquer cet algorithme même si vous êtes atteint de la maladie d’Alzheimer. Ha ha ha.

J’ai pris le temps de remettre le code au propre, en PEP-8, avec des commentaires corrects. Le tout est sur mon github.

Explication de l’algorithme

Elle est dans la docstring du fichier python. Je vous la remets ici.

Il faut d’abord déterminer le nombre de « coupures » dans l’ordre des disques.

Lorsque deux disques de taille N-1 et N sont empilés sur un même poteau, il n’y a pas de coupure entre eux. Lorsqu’ils sont sur deux poteaux différents, on compte une coupure.

De plus, lorsque le gros disque du bas n’est pas sur le poteau de fin, on compte également une coupure.

Exemple :

  • Le disque 1 (le plus petit) est sur le poteau de départ.
  • Les disques 2 et 3 sont sur le poteau intermédiaire.
  • Le disque 4 (le plus gros) est aussi sur le poteau de départ.

 

      |           |           |
      |           |           |
      |           |           |
     +++        -----         |
  ---------    +++++++        |
  .................................

 

On compte les coupures en partant du plus gros disque vers le plus petit (mais on aurait pu compter dans l’autre sens).

  • Le 4 n’est pas sur le poteau de fin. +1 coupure
  • Le 4 et le 3 ne sont pas sur le même poteau. +1 coupure
  • Le 3 et le 2 sont sur le même poteau. OK
  • Le 2 et le 1 ne sont pas sur le même poteau. +1 coupure

Total : 3 coupures.

Cette dame s’appelle Miss Twin Towers, soit l’équivalent de deux tiers d’un jeu de tour de Hanoï

Si le nombre de coupures est impair, il faut déplacer le disque 1 (le petit).

Pour déterminer son poteau de destination :

Si le nombre total de disque est pair, le petit disque doit se déplacer vers l’avant :

poteau de départ -> poteau intermédiaire -> poteau de fin -> poteau de départ -> etc.

Si le nombre total de disque est impair, il doit se déplacer vers l’arrière :

poteau de fin -> poteau intermédiaire -> poteau de départ -> poteau de fin -> etc.

Si le nombre de coupures est pair, il faut déplacer un disque autre que le petit disque. Dans ce cas, il n’y a toujours qu’un seul mouvement possible.

Parmi les deux poteaux ne contenant pas le petit disque, l’un d’eux est vide. Il faut alors déplacer un disque du poteau non vide vers le poteau vide.

Parmi les deux poteaux ne contenant pas le petit disque, aucun n’est vide. Il faut prendre le plus petit disque parmi ces deux poteaux, et le déplacer vers l’autre.

Lorsque le nombre de coupures vaut 0, le jeu est terminé. Tous les disques sont sur le poteau de fin, dans le bon ordre.

Il faudrait une vraie démonstration mathématique pour prouver que cet algo fonctionne, mais je ne sais pas la faire. Ça semble fonctionner quel que soit le nombre de disques.

Les tours c’est fun

Pour finir, voici une image d’un vieux jeu que j’avais beaucoup aimé : Mystic Towers. Je n’ai pu profiter que de la version shareware, mais c’était quand même chouette

Oh, et il semblerait qu’on arrive déjà à la fin du mois. Il faut que je démarre un nouvel article. Diantre.

Un truc fait ailleurs mais le voilà ici

 

J’ai écrit un texte quelque part. Mais il est associé à mon nom du monde du travail. (Ça fait beaucoup de fois de suite une combinaison des lettres « m », « n », « o », mais osef).

Cependant, j’aime bien ce texte et je trouve qu’il mériterait d’apparaître sur ce blog.

Alors j’ai fait une bidouille à l’arrache. J’ai balancé le texte dans pastebin. Et je vous en donne le lien : https://pastebin.com/rXgMFx0q .

La mise en forme, les images et une grande partie des liens ont été perdus en route. Désolé.

La lecture est un peu fastidieuse, du fait que c’est du texte brut. Bon courage. En même temps, j’ai pas l’impression que grand monde lise ce blog, alors on n’est plus à ça près. Je viens de me rendre compte que ça fait presque 10 ans que je blablate dans ce coin paumé de la « blogosphère ». Faudra que je trouve un moyen débile de faire une rétrospective pour les 10 ans, mais de manière plus originale que « ce blog a 10 ans, youpi, blablabla ».

Pour en revenir à ce texte. Il est évident qu’en fouinant un peu, on retrouvera l’endroit originel de sa publication, et vice-versa : les personnes connaissant cet endroit originel pourraient tomber sur ce blog. Je ne me fais pas d’illusion, le lien entre mon nom du monde du travail et le nom « Réchèr » est déjà connu de plusieurs personnes, et tôt ou tard, il deviendra plus ou moins public. En attendant, j’essaye de faire durer l’anonymat le plus longtemps possible.

Si vous souhaitez garder l’anonymat, la première chose à faire est de ne pas laisser trainer des photos de votre visage un peu partout :

 

Pru-Pra-Prok sur github

Wouwi-zouwi m’sieurs-dames et tous les autres.

J’ai mis mon dessin animé sur github. Vous vous en souvenez peut-être, c’était ce truc là :

C’est par ici : https://github.com/darkrecher/pru-pra-prok

Rien de nouveau par rapport à la version initiale (qui date de plus de 10 ans). Mais j’ai tout de même pris le temps de le recompiler avec gcc sous MingW32, et de documenter le tout de la manière la plus détaillée possible, afin d’offrir à d’autres personnes la possibilité de modifier, mâchonner, recompiler, créer ses propres dessins animés, etc.

J’ai toujours été agacé par les gens qui libèrent leur code source sans y ajouter la documentation nécessaire à son exploitation. « Huuurrrrr duuuurrrrr. Tu fais makefile et ça marche ». J’essaye donc de ne pas faire comme eux.

Après, ça vaut ce que ça vaut. On trouvera facilement des logiciels d’animations infiniment meilleur que ce truc (rien que Scratch, par exemple).

La githubisation de ce projet fait partie de mon grand plan « vidage de fonds de tiroir de tous mes vieux bouts de code ». C’est bientôt terminé, il ne me reste plus qu’un pack de mini-projets. Ensuite je pourrais passer à autre chose. Soyez assurés que vous serez les premiers informés de la suite des événements.

Pour finir cet article, je propose de glisser du domaine des dessins animés vers celui du cinéma, avec cette image du film Dikkenek.

(Tiens, ça me fait penser au catalogue des 3 Belges dans les copains des Tilleuls … Aucun lien, désolé).

Unités, encodage et caractères spéciaux

Vous vous souvenez de ce prof de physique, au collège, qui n’avait pas tenu compte de vos réponses à un contrôle parce que vous n’aviez pas indiqué les unités ?

Vous aviez écrit « 63 » au lieu de « 63 grammes », « 2,83 » au lieu de « 2,83 mètres », etc. Ça vous avait valu un 5/20.

C’était un gros con ce prof.

Sauf qu’il avait raison.

C’était effectivement un gros con, concernant un tas d’aspects de sa personnalité. Mais pour cette histoire d’unité il avait raison.

En informatique, on a un problème équivalent avec les encodages et les caractères spéciaux.

C’est des centimètres ou des inches ?

L’encodage

Vous connaissez peut-être déjà. Il s’agit de la correspondance entre un caractère et la suite de nombre utilisée pour le représenter. Les ordinateurs ne savent rien faire d’autres que gérer des valeurs numériques. Une image, une application, des clics de souris, une connexion internet, les barrettes de RAM, tout ça c’est que des nombres. Il peut y en avoir énormément, et on ne fait pas toujours la même chose avec. Mais c’est des nombres.

Voici quelques exemples.

  • Le caractère é (e accent aigu) :
    • est représenté par la suite de nombres (195, 169) dans l’encodage ‘UTF-8’,
    • est représenté par le nombre unique 233 en ‘Latin-1’,
    • ne peut pas être représenté en ‘ASCII’,
  • la lettre A majuscule:
    • est représentée par le nombre unique 65, en UTF-8, Latin-1 et ASCII
    • est représentée par le nombre unique 193 en ‘EBCDIC’ (un encodage bizarre utilisé par IBM).

En détail, c’est un peu plus compliqué que ça, car l’encodage et le jeu de caractères sont deux notions différentes, je n’ai pas parlé du Byte Order Mark, et il existe plusieurs sortes d’EBCDIC (https:// en.wikipedia.org/wiki/EBCDIC). Mais on ne va pas se prendre la tête avec ça.

Donc une chaîne de caractères toute seule, ça ne veut rien dire et si vous ne connaissez pas son encodage, vous ne pouvez pas la manipuler avec certitude.

C’est ça qui fait que les accents sont parfois tout pourris dans une page web ou un fichier Excel. Le texte est dans un certain encodage, l’application qui le manipule croit que c’en est un autre, et paf pastèque.

Vous pouvez décider que « fuck les accents », et obligez vos utilisateurs à n’utiliser que les caractères ASCII. Mais il faut avoir conscience que cela implique « fuck tous les alphabets non latins » : « fuck les russes, les chinois, les arabes, les hébreux, les mathématiciens et les gens qui écrivent avec des smileys ».

À tout cela s’ajoute une autre couche de confusion possible.

Les caractères spéciaux

Alors voilà. Vous avez créé un site web ou une application dans laquelle l’utilisateur peut saisir du texte (par exemple pour ajouter un commentaire, décrire son chien, etc). Vous maîtrisez parfaitement ce que vous avez développé, et connaissez donc l’encodage dans lequel la chaîne de caractère a été saisie. Super ! Tout est OK ? On peut arrêter de se poser des questions ?

Que diantre nenni !

Il faudra peut-être appliquer une transformation pour protéger ou interpréter certains caractères spéciaux.

Vous voulez enregistrer cette chaîne dans une base de données ? Attention aux injections SQL, vous devez protéger les simple-quotes en les remplaçant par deux simple-quotes à la suite. (Les requêtes paramétrées permettent de le faire automatiquement).

Vous voulez la réafficher dans une page HTML ? Attention aux failles XSS et aux balises HTML. Vous devez protéger les caractères ‘<‘ et ‘>’ en les remplaçant par les HTML entities. Et comme les HTML entities s’écrivent avec le caractère ‘&’, il faut lui aussi le remplacer par son HTML entity.

C’est une URL ? Pensez à la convertir en ‘url-encoding’ : remplacer les espaces par des %20, etc.

C’est une ligne de commande ? Il va peut-être falloir protéger les antislashes en les doublant. Ou pas. Ça dépend de ce que vous avez décidé, mais il sera de bon ton de prévenir l’utilisateur des opérations appliquées.

C’est un chemin vers un fichier ? Très bien, vous n’aurez peut-être pas de conversion à faire. Mais si vous utilisez ce chemin dans une ligne de commande, n’oubliez pas de l’entourer par des guillemets, au cas où il comporterait des espaces. Vous connaissez, bien sûr, l’encodage de votre système de fichiers ?

Autres choses

Cette histoire d’unités et de vilains profs de physique est transposable à d’autres types de données : les dates.

Je ne parle même pas du format de représentation. « 02/03/14 23:45:56 », vous savez déjà que ça ne veut rien dire. Le ’02’ c’est le jour où c’est le mois ? (Au passage, merci les anglais de faire, une fois de plus, à l’envers de tout le monde). Le ’14’, c’est 1914 ou 2014 ?

Évitons ces pièges stupides, et indiquons les dates au format ISO 8601 : 2014-03-02 23:45:56. Voilà, et maintenant, plus d’ambigüité !

Perdu ! Elle est bien votre date, mais c’est quel fuseau horaire ? C’est l’heure d’été ou l’heure d’hiver ? Au fait, vous saviez que les américains effectuaient le changement d’heure, mais pas exactement au même moment dans l’année par rapport à nous ? Et les leaps seconds, on les prend en compte ou pas ?

La solution à cette histoire de date est de tout gérer avec des timestamps, et de convertir vers/à partir d’autres formats uniquement lors des entrées-sorties de ces dates dans votre programme. Le timestamp définit un nombre de secondes depuis 1970-01-01 00:00 UTC.

À partir de ce nombre de secondes, on peut retrouver toute la date. De plus, les opérations de calcul avec les intervalles sont grandement simplifiées. Par contre, ça met en incubation des bugs encore plus rigolos que celui de l’an 2000 (https:// fr.wikipedia.org/wiki/Bug_de_l’an_2038).

Quel bazar ces données ! Au moins, avec les nombres on n’est pas embêtés. Quoi que… Si vous faites de la programmation bas niveau (ce qui signifie « proche de la machine », et non pas « programmation pour les gros teubés »), un monde de normes et de notations peut vous jaillir à la figure. Comment vous représentez les nombres à virgules ? flottantes ou virtuels ? IEEE 754 ou autre chose ? Vos entiers, vous les voulez signés ou non signés ? Avec du complément à deux ou autrement ?

Même pour la donnée la plus simple possible : des nombres entiers positifs, vous devrez peut-être vous poser des questions : big-endian ou little-endian ? Des bits de contrôle ? de parité ?

Il y a encore un tas d’autres choses où le lien entre la donnée et la méta-donnée est indispensable. Vous avez récupéré un fichier, super, mais c’est pour en faire quoi ? C’est une image ? Un texte ? Autre chose ? Et sous quel format ? Et si vous tombez sur une vieille cassette vidéo, c’est du PAL ou du Secam ?

Tout ça pour dire qu’il faut faire attention aux données qu’on manipule, depuis la plus simple variable string jusqu’aux tera-octets de base de données. Il y a plein de programmeurs qui n’en ont pas toujours conscience, ça met le bazar, et je voulais vous sensibiliser sur ce sujet, tel le gros con de prof de physique que je ne suis pas.

Ce sera tout pour aujourd’hui

J’essaie de faire un article de blog par mois, et là ça a été un peu juste. Comme d’hab’, c’est la faute au monde réel, mais aussi à Dead Cells, le nouveau jeu de la Motion Twin. J’aime beaucoup, il y a énormément d’idées intéressantes, et une ambiance mignonne-glauque assez bien travaillée.

Du coup je vous laisse, je vais essayer de dégommer des Slashers au corps à corps.

Vive la liberté d’expressionotron

Voilà déjà quelques temps que mon twitter bot expressionotron a dépassé le nombre hallucinogénatoirement élevé de 30 followers. On en est même à 36.

Comme promis dans cet article, j’ai libéré le code source de cette incommensurable œuvre.

C’est sur mon compte github : tout bien documenté, avec la config de mise en production, la doc de conception, etc. J’aime la doc.

bande dessinée de Gaston Lagaffe documentation

Au départ, j’avais prévu de ne libérer que le code source, sans les listes de morceaux de phrases utilisés pour créer les expressions. Sauf que je me suis vautré et j’ai tout balancé d’un coup dans github. J’aurais pu supprimer les listes après coup, mais ça aurait toujours été possible de les retrouver en fouillant les logs. J’aurais également pu effacer tout le repository et repartir de zéro, mais j’avais la flemme.

De plus, je n’avais pas envie de maintenir une version publique sans les morceaux de phrases et une version privée avec. Donc, ça suffit les bêtises, on libère tout, c’est beaucoup plus simple. Ça n’en est que mieux pour vous. (À condition d’admettre le postulat initial que ça vous intéresse).

Pour la suite

L’expressionotron continue sa quête de célébrité. La prochaine étape sera d’accorder les adjectifs avec les noms. En effet, actuellement, tous les adjectifs sont au masculin, alors qu’il y a quelques noms féminins. Ce qui peut provoquer quelques incohérences grammaticales, tel que :

Ça corrode de la prostate néo-myxomateux au point godwin !! CXI !!1!

Pour diminuer le risque de faute, j’ai intégré assez peu de noms féminins. Il serait maintenant louable de corriger ce problème et d’implémenter l’accord nom-adjectif, afin de pouvoir se permettre d’ajouter des noms de tous genres.

Pour 40 followers, je me lance dans cette tâche.

Suis-je un vilain ?

D’aucuns et d’aucunes diront que mon expressionotron est sexiste, puisque je l’ai créé par défaut au masculin, et que ce n’est que bien plus tard que je songe à féminiser ses composants. Ouais c’est possible.

Je vais me permettre de poser la question : le masculin et le féminin, est-ce que c’est pareil que l’homme et la femme ?

Il existe des langages (l’anglais par exemple), dans lesquels le masculin et le féminin a moins d’importance : chaque nom d’objet est neutre (« it ») et les adjectifs sont invariables. Quelles sont les différentes manières, à travers le monde et les âges, de prendre en charge le féminin et le masculin dans une langue ? A-t-on absolument besoin d’y intégrer cette notion ? Comment est-ce pris en compte dans le langage des signes ? Est-ce qu’on se touche les seins ou les testicules à chaque fois qu’on veut accorder un adjectif ?

Je sais pas. Il faudrait peut-être chercher les réponses auprès des langages épicènes, dont nous parlerons peut-être dans un autre article.

De toutes façons, ce blog lui-même est sexiste, vu le type de photo incorporé à chaque article.

tumblr_o6utq94hzd1uaiz32o1_1280

Mais c’est comme ça. C’est vraiment ces images là que j’ai envie de vous montrer, que vous soyez une femme, un homme, ou entre les deux, ou totalement autre. J’espère que ça vous plaît.