Archive pour le ‘science’ catégorie

Assume Nothing

4 avril 2012

Au milieu des années 90, j’ai acheté un livre de Michael Abrash, Programmation 486 et Pentium, qui présentait l’architecture de ces 2 processeurs, et tirait beaucoup de matière d’un autre de ses livres, « Zen of code optimisation », qui discutait de l’implémentation du code, et comment optimiser une programme, comment une programme pourrait être accéléré d’un facteur de 100 en repensant certaines parties, en « pensant autrement ».

En revanche, je crois que dans mon expérience, la seule règle qui revient très souvent c’est « Assume Nothing » : Ne prenez rien pour argent comptant, et si ce n’est pas une fois par jour que cette règle se vérifie, c’est une fois par semaine. Depuis 15 ans.

Quand vous codez quelque chose, vérifiez. Contrôlez vos erreurs. Contrôlez les données qui passent par votre programme. Ne prenez aucune donnée comme argent comptant tant qu’il n’ a pas été clairement identifié. Le contrôle d’erreur ralentit certes une programme, mais il vaut largement mieux avoir un erreur géré soit par un message, soit par un traitement « par défaut » que de foncer tête baissé, et se ramasser quand quelque chose va de travers.

Dernière exemple en date : J’affiche sur une page web des vins avec un classement d’étoiles : 0, 1, 2 ou 3. Cette valeur d’étoiles est stockée dans notre base de données, par vin, et il y a 4 logos générés, correspondant à chacune de ses valeurs.

Le code qui gère l’affichage de la page va chercher l’image du logo correspondant en calculant son nom, à partir de la valeur en base + « .jpg » :

   monImage = maValeur+".jpg"

Dans l’absolu, rien d’étonnant et ça va marcher… sauf quand la valeur dans « maValeur » ne correspond à rien de prévue : si le nom d’image reconstitué ne correspond pas à une image sur le site, une croix rouge s’affichera sur la page. Et oui, dans un vin, j’ai « -1″ étoiles. Sur un autre, j’ai tout simplement « Aucune ». Le développeur a prévue « 0.jpg », « 1.jpg », « 2.jpg » et « 3.jpg ». Et pour mon Aucune, ou mon -1 ? Est ce qu’il existe un « -1.jpg » ou « Aucune.jpg » – ou tout simplement « .jpg » si quelqu’un réussi à saisir une valeur vide… Eh bien non… Et s’il y a 2 valeurs d’étoile différentes pour le même vin ? Non, pas géré non plus.

Comment faire ? en vérifiant les valeurs. Ce n’est pas parce qu’on ne devrait trouver 1 valeur correspondant à 0, 1, 2 ou 3 qu’on va trouver forcément toujours l’une de ces valeurs, donc vous validez explicitement ce qui devrait s’y trouver, et vous devez gérer un cas de plus : Le cas qu’il y a un erreur et qu’il n’y a pas de correspondance. Vous gérez l’erreur :

   SI maValeur = 0, 1 , 2 ou 3 ALORS
      monImage = maValeur+".jpg"
   AUTREMENT
      monImage = "inconnu.jpg"
   FIN SI

Oui, ça implique de gérer un cas d’erreur avec un image nommé « inconnu.jpg », mais le travail est fait correctement et vous n’affichez pas des données ou liens fantaisistes, et vous gardez le contrôle sur votre application.

Est ce que c’est vraiment grave ? Ca dépends de son métier et de l’application. Dans mon exemple tiré d’un bout de code que je viens de rencontrer c’est dommage sur un site d’afficher une croix rouge sur une image car un développeur a voulu s’économiser 20 secondes, mais il n’y a pas mort d’homme. Parfois c’est plus grave , en temps, en argent et parfois même en vies.

Deux exemples :

  • Un calculateur pouvait gérer un chiffre entre -32767 et +32767 pour gérer l’équilibre d’une machine. Que s’est il passé quand la valeur est passé à +32768 ? (max+1 ?) Et bien, le chiffre s’est inversé en négatif, tout simplement. Et l’équilibre en a fait autant. C’était installé où ce fameux calculateur ? A bord le premier tir d’Ariane 5 qui a été détruit quelques secondes après le lancement pour cause de perte de cap et d’équilibre.
  • Un appareil de radiothérapie devait se couper quand le cache de visée était en mouvement, et l’ordinateur définissait un mouvement en calculant le déplacement du moteur du cache, mais ce mouvement n’était calculé si le moteur de ce cache tournait dans un sens. S’il tournait dans l’autre sens, le rayonnement n’était pas coupé, et des personnes ont subies des irradiations, mortelles dans certains cas.

Que le code soit 3 lignes qui pilotent l’affichage des images sur un site web, ou 50 000 lignes qui pilotent une fusée, il suffit d’une simple non vérification pour que tout bascule, et le plupart de temps, passer 30 secondes de plus sur un sujet permet de neutraliser le problème.

Pour revenir à mon code, comment est-ce que j’aurais géré ce cas, en connaissant tout aussi bien les données que la personne ayant écrit le code à l’origine, et que les données sont potentiellement mauvaises ? :


   //Commençons par une valeur qui prévoit l'erreur
   monImage = "inconnu.jpg"
 
   SI maValeur est un tableau
      //Prendre le denrier élément du tableau
      maNouvelleValeur = maValeur[compter_elements(maValeur)-1]
      envoyer_email(admin, "Plusieurs étoiles pour un même vin")
      //Ecraser le tableau avec la nouvelle valeur détectée après avoir signalé l'incohérence
      maValeur = maNouvelleValeur
   FIN SI
 
   //Tenter de convertir en chiffre
   maValeur = convertir_numerique(maValeur)
   SI maValeur n'est pas explicitement en erreur
      SI maValeur = 0, 1 , 2 ou 3 ALORS
         Je suis bon. Ecraser la valeur dans monImage par la valeur que je viens de calculer
         monImage = maValeur+".jpg"
      AUTREMENT
         //J'ai trouvé un chiffre, mais pas celui prévu
         envoyer_email(admin, "Valeur erronée dans la quantité d'étoiles")
      FIN SI
   AUTREMENT
      //La valeur que j'ai trouvé n'était pas un chiffre
      envoyer_email(admin, "erreur de donnée dans les étoiles")
   FIN SI

Je part du principe que la donnée est erronée en prévoyant au départ une valeur par défaut qui sera explicitement validée si je trouve une valeur correcte.

Je vérifie qu’il n’y a pas de tableau de valeurs (plusieurs valeurs pour un même vin), et s’il y en a, on prends la dernière valeur connue pour en avoir au moins une : Je tente de corriger. On sait qu’il y a déjà une erreur et on le signale, mais nous pouvons peut être quand même pouvoir continuer avec une donnée qui serait peut être valide.

Je vérifie ensuite si la donnée est un chiffre, en le convertissant. S’il y a une erreur, nous remontons une alerte sans aller plus loin, autrement on continue.

Ensuite, si je continue, je vérifie que la donnée est dans la plage connue et prévue : si oui, je valide la donnée et je construit le nom de l’image, autrement, je remonte une alerte, et je garde l’image prévue au début.

Si rien ne passe, j’ai une image prévue par défaut (inconnu.jpg), si la donnée est correcte, le nom d’image sera modifiée par le nom correcte, et dans tous les autres cas de figures, je sais exactement ce qui s’est passé, pourquoi la donnée ne va pas, et l’erreur m’est remontée par email pour être corrigé. Et l’internaute verra toujours une image sur le site, et non pas une croix rouge pour signaler une image cassée.

En résumé, si vous traitez des valeurs, vérifiez. Toujours. Assume nothing!

Qu’est ce la radioactivité de fond ?

18 mars 2011

Avec tout ce qui se passe autour de l’accident des réacteurs de Fukushima suite au tremblement de terre et le tsunami qui l’a suivi, j’ai ressorti mon compteur Geiger pour établir des mesures de radioactivité quotidiennes, de chez moi à Chambourcy, juste pour voir. » En lire plus:Qu’est ce la radioactivité de fond ?