Certaines situations exceptionnelles peuvent être prévisibles, mais arrivent une fois sur cent. Sans ordinateur, un être humain qui suit une procédure les remarque souvent spontanément, et adapte son comportement en conséquence.
Un ordinateur, lui, suit bêtement la règle, et l’applique dans des cas qu’un gamin de quatre ans trouverait débiles. D’où les classiques des débuts de l’informatisation administrative, comme les factures à 0,00 franc, ou les dossiers d’inscription à l’école envoyés à de vieilles dames de 106 ans. Les sociétés qui transforment des humains en téléopérateurs-perroquets assimilés à des machines sans initiative génèrent le même genre de bugs, juste avec de la viande en guise de matériel.
Je me méfie comme de la peste des spécifications écrites par des gens qui raisonnent « en règle générale » (à peu près la totalité de la population). Or, pour un développeur, il n’y a pas une règle générale et son 0,0001% d’exception, mais bien deux cas à traiter. Si le deuxième, exceptionnel, est renvoyé à un humain, cela me convient ; encore faut-il anticiper et détecter cette exception, prévenir cet humain, et donner à celui-ci le droit et le moyen matériel de passer « en manuel ». Notre civilisation pèche de plus en plus sur ce point.
Donc par déformation professionnelle, je dois devenir vicieux et mettre en doute les choses les mieux établies. Prenons quelques exemples. Demandez-vous si les règles suivantes sont vraiment universelles :
- Toutes les années ont 365 jours.
Non, il y a les années bissextiles. Je sais, c’est facile. Mais il faut y penser réellement quand on calcule, par exemple, un taux annuel à partir de quantités journalières, et la formule devient subtilement plus compliquée qu’une bête multiplication. L’impact n’est pas négligeable (une journée de travail en plus, c’est 0,5% d’heures travaillées en plus sur l’année, et 5% en plus en février) et des comparaisons entre années doivent en tenir compte.
Cela fait aussi un cas à ajouter au jeu de test...
- Toutes les années divisibles par 4 sont bissextiles.
Ça c’était au temps du calendrier julien. En calendrier grégorien, les années divisibles par 100 (1800, 1900...) ne sont pas bissextiles.
Pour les informaticiens versés dans les dates lointaines et étrangères, il faut faire attention : selon les pays, le passage au calendrier actuel s’est étalé de 1582 à 1929.
- Toutes les années divisibles par 4 non divisibles par 100 sont bissextiles.
Depuis l’an 2000, on sait que non : par exception à l’exception qui veut que les années divisibles par 100 ne soient pas bissextiles, les années divisibles par 400 sont bissextiles. Il reste à espérer que les logiciels retouchés pour l’an 2000 ne l’ont pas été avec une simple exception pour 2000, sinon ceux encore en activité en 2400 nous sauteront à nouveau à la face.
- Toutes les années divisibles par 4 non divisibles par 100 sont bissextiles, et aussi celles divisibles par 400.
Le 1er avril 1999, le site des éditions allemandes Heise annonçait la découverte de documents d’époque révélant que lors de la mise en place du calendrier grégorien et de la règle de la divisibilité par 100 ou 400, il avait été aussi précisé que les années divisibles par 1000 ne seraient pas non plus bissextiles, même si elles étaient divisibles par 400 (cas de l’an 2000), avec l’exception de 5è niveau des années divisibles par 4000, qui seraient bien bissextiles.
Cette règle flanquait par terre une bonne partie du travail effectué pour corriger le bug de l’an 2000, et l’industrie entière a préféré prendre cette histoire comme un poisson plutôt que reprendre de zéro le travail. Je vous laisse vous faire votre avis. :-)
- L’année commence en janvier et finit en décembre.
Ne pensent cela que ceux qui n’ont pas travaillé avec des comptables. Les années fiscales et civiles n’ont pas forcément grand rapport, il y a un décalage de plusieurs mois.
- Il y a 12 mois dans l’année (calendrier grégorien).
Pour le commun des mortels en Occident, oui.
Pour un système de gestion financière de collectivité locale française, il peut y en avoir 14 :
- les 12 mois habituels ;
- un pseudo-mois nommé par exemple « Décembre N-1 » rattaché à l’année N mais comprenant par exemple toutes les décisions prises à la fin de l’année civile antérieure (on vote en décembre le budget de l’année prochaine) ;
- un pseudo-mois « Journée complémentaire » qui regroupe toutes les opérations qui doivent être rattachées à cette même année N, mais qui pour des raisons pratiques sont effectuées en réalité au début de l’année suivante.
Pour une entreprise qui change sa référence d'année fiscale (par exemple de mars à mars au lieu de janvier à janvier), une année de transition est démesurément longue ou raccourcie.
Je suis sûr qu’il y a dans le monde une flopée d’exemples d’astuces de ce genre propres à un métier, une administration, une entreprise, un service, qui flanquent en l’air nombre d’algorithmes un peu naïfs.
- En Occident, les mois sont janvier, février, mars, avril...
J’ai des ancêtres nés en ventôse de l’an V de la République...
Un logiciel traitant de cadastres, de généalogie, d’actes juridiques... peut avoir besoin de ces données remontant à deux siècles. Le recalcul permanent en calendrier grégorien est source d’erreurs, et il vaut mieux aussi stocker la date originelle pour comparer avec les documents originaux. (Bon, soyons réaliste, un champ « commentaire » pourrait suffire en pratique.)
- Il n’y a pas de 30 février ni de 31 juin.
Dans le calendrier grégorien occidental récent, non.
Dans un champ rempli par les utilisateurs, et non contrôlé, on peut avoir n’importe quoi.
L’exemple type est le « flexfield » d’Oracle Applications (l’ERP). En gros, c’est un champ optionnel avec filtre paramétrable qui s’ajoute aux champs habituels d’un écran, et que peut remplir l’utilisateur. L’endroit idéal pour stocker une information non prévue dans le logiciel original, par exemple un code, un texte... ou une date de départ ou d’arrivée ou de rappel ou de Dieu sait quoi.
J’ai vu cent fois le cas de dates totalement corrompues dans ces champs : la valeur est stockée dans une colonne dédiée prévue pour cela (genre SEGMENT1
, SEGMENT2
, ... SEGMENT20
), qui est forcément une chaîne (type Oracle VARCHAR2
). Si cela ne porte pas à conséquence pour stocker un nombre (sauf pour le symbole décimal), les ambiguïtés pour une date sont énormes :
- L’utilisateur peut remplir un peu n’importe quoi s’il est mal luné.
- Il n’est pas à l’abri d’une faute de frappe et on obtient une année 202.
- Le symbole de délimitation n’est pas clair.
- Si des Américains sont impliqués, il y a le risque de voir des dates au format MM/JJ/AAAA... (et le pire est que pour les jours inférieurs à 13, vous ne pourrez pas détecter une erreur.)
- Les années de champs remplis avant l’an 2000, voire après, risquent d’être sur deux chiffres.
- Si des données sont importées d’autres systèmes, ou écrites par un programme directement en base (ça se fait, sous Oracle Appli...), en contournant les filtres éventuellement en place pour éviter les cas précédents, un développeur imprudent risque de stocker dans le format par défaut de sa session, qui ne sera pas forcément celui prévu par une autre session (DD/MM/YYYY
n’est pas la même chose que DD-MON-RR HH24:MI:SS
). S’il n’y a pas ambiguïté pour un humain, l’ordinateur ne trouvera pas tout seul le bon format.
Une autre erreur est de caser les dates sous forme de chiffres (!). On peut donc tomber sur un 20051232
pour le 32 décembre 2005. Oui, ça peut arriver quand on fait des calculs sous forme DateB = DateA + 1
comme il est si pratique avec un vrai champ DATE de base de données qui est fait pour ça, et que la routine de calcul est boguée.
Bref, je me méfie toujours des dates non stockées sous forme de champ de type DATE
(et même : la faute de frappe qui oublie un chiffre à l’année reste possible si l’interface humaine n’est pas blindée...).
- Il n’y a pas eu réellement de 30 février (bis).
Oui, moi aussi je l’ai cru.
Dans leur chaotique transition au calendrier grégorien au XVIIIè siècle, les Suédois ont réussi à créer un 30 février. Un calendrier révolutionnaire soviétique rapidement abandonné aurait eu des mois de 30 jours. Dans des modèles mathématiques, on arrondit parfois les mois à 30 jours (mais peut-on encore les nommer avec les noms habituels auxquels ils ne correspondent plus ?).
Voir l’article de Wikipédia pour les détails.
(Ajout du 1er janvier 2012) Et puis tant qu’on y est dans les bizarreries : les Samoa, ayant changé deux fois de fuseau horaire et franchi deux fois la ligne de changement de date, ont eu deux 4 juillet 1892, mais pas de 30 décembre 2011. Ce genre de bizarrerie disparaît si toutes les dates sont stockées et calculées en Temps universel, mais quel développeur en prend la peine dans les applications où les fuseaux horaires ne jouent habituellement pas ?
- Il y a 52 semaines dans une année.
Comme il y a bien toujours sept jours dans la semaine depuis des temps immémoriaux, et en laissant de côté les cas des années de transition entre les calendriers julien et grégorien, on peut calculer qu’il y a 365/7= 52,14 semaines dans l’année. Donc le 31 décembre peut tomber dans un début de 53è semaine. Quoi qu’on fasse, on n’aura jamais un nombre entier de semaines dans une année.
Il y a un moyen normalisé de calculer le numéro de la semaine, c’est la semaine ISO. Le 1er janvier peut tomber la semaine 01 de l’année en cours, ou 52 ou 53 de l’année précédente. Le système ISO prévoit donc carrément des années différentes de longueur variable avec un nombre entier de semaines, mais ce n’est pas du tout entré dans les mœurs. En conséquence, un tableau qui affiche année civile/trimestre/mois/semaine ISO commencera à 2008/1/janvier/1 et finira à 2008/4/décembre/1. D’où deux semaines 1 dans l’année (civile) 2008...
Ce qui est rigolo, c’est que j’ai vu des différences dans le calcul de la semaine entre le monde entier et Outlook, ou entre deux versions de Business Objects (6.5 et XIR2). Je n’ai pas pu creuser, c’est peut-être lié aux paramétrages locaux.
- Il y a toujours 24 heures dans une journée.
...Sauf deux fois dans l’année lors des transitions entre heure d’hiver et heure d’été... Donc de 23 à 25 heures. Et il faut éventuellement prévoir le gag d’avoir un événement à 2h59 (heure d’été) suivi d’un autre à 2h01 (heure d’hiver).
- Une heure comprend toujours 3600 secondes.
Plutôt entre 3599 et 3601 : presque chaque année, des secondes sont enlevées ou rajoutées en fin d’année pour recaler le temps universel et la rotation de la Terre (tout de même la référence finale). Si dans un ERP on néglige le problème (le développeur est déjà heureux si tous les serveurs sont synchrones à la seconde près entre eux), les calculs de trajectoires de satellites doivent en tenir compte.
D’ailleurs le calcul temporel en orbite doit être assez folklorique puisqu’il faut même tenir compte d’éventuelles corrections relativistes (les détails sordides sont là et là).
- Le numéro de Sécurité Sociale identifie un individu de manière unique.
Non, il y a même une possibilité de doublon entre des gens nés à cent ans d’intervalle au même endroit. Voir Wikipédia pour les détails et le passionnant historique. D’ailleurs il est possible de changer de numéro de Sécu (par exemple pour un transexuel ou quelqu’un né dans l’Algérie française).
Noter aussi qu’il existe des gens n’en possédant pas : étrangers, enfants... De plus, en Europe, le numéro de Sécurité Sociale est considéré comme une donnée personnelle, à diffusion restreinte et il n’est donc pas censé se retrouver n’importe où, doit être anonymisé, etc.
C’est un exemple fascinant à verser au dossier du débat « clé primaire arbitraire vs. clé primaire fonctionnelle. » (J’en causerai un jour. Ajout postérieur : C’est fait !)
- Les numéros des départements français ont deux chiffres.
...Sauf dans les DOM-TOMs ! Guadeloupe : 971 , St Pierre & Miquelon : 975
...Et vous avez tout faux si vous croyez que c’est du numérique (Corse : 2A et 2B).
De manière plus générale, la géographie offre une montagne d’aberrations diverses à toute personne cherchant à y établir des règles. Rien que la transposition des lois votées à Paris par l’assemblée de Tahiti, ou leur compatibilité avec la loi alsacienne, donne du travail à maints juristes.
- Un enfant a biologiquement un et un seul père et une et une seule mère.
Évidemment non.
Depuis quelques années il existe des mères porteuses, ce qui est autorisé dans certains pays. On peut choisir de prendre en compte la mère porteuse, ou celle qui a fourni l’ADN (qui peut d’ailleurs être une autre que celle qui va élever l’enfant), mais ce choix doit être conscient.
Comme dans le cas des enfants adoptés, où la filiation est modifiée par l’adoption. Selon le cadre et le but du logiciel développé (généalogie, études génétiques...) il faudra trancher, et se demander ce que l’on fait dans certains cas tordus du genre des enfants clonés (ça arrivera), ou pour un transexuel (devenu homme) qui accouche d’un enfant (biologiquement c’est juste une femme qui a un enfant, mais civilement il est le père). Je prédis l’enfer informatique à cette famille, aucun logiciel n’est prévu pour gérer ce genre de cas.
- Il n’y a que deux sexes.
En fait, cela dépend de ce que vous voulez faire de l’information. En tête du numéro Sécu peuvent apparaître 3, 7 ou 8 pour les transexuels et autres statuts provisoires. Pour un simple libellé de courrier, il y a trois possibilités traditionnelles (M., Mme, Mlle).
Dans une application pour un zoo ou un laboratoire de biologie, il faudra tenir compte des bestioles capables de changer de sexe à volonté. Sans compter les hermaphrodites comme les escargots, ou les espèces où le concept de sexe n’existe pas.
- Tout le monde a un nom et un ou plusieurs prénoms.
J’ai rencontré pendant mes études un Indonésien qui n’avait qu’un nom. Je ne sais pas comment il avait rempli sa demande de visa.
- 12 > 2
Si vous manipulez des nombres, déclarés comme nombres auprès de l’ordinateur, oui.
Si vous manipulez des nombres stockés sous forme de chaînes de caractère (cela arrive tous les jours...), l’ordre lexicographique prend le pas et vous aurez tout ce qui commence par « 1 » qui sera trié avant (donc inférieur à) « 2 » : « 1 », « 10 », « 12561265463 »,..., « 2 », « 2564536 », ..., « 3 »,... Une conversion explicite en nombre peut être nécessaire suivant l’outil et le langage.
Je suis preneur de toute autre « règle générale qui ne l’est pas » à ajouter à cette liste !
17 réactions
1 De Palats - 07/04/2008, 21:51
Moi un truc qui m'amuse toujours, c'est les fuseaux horaires. Pourquoi note-t-on toujours (enfin, dans de nombreux formats informatiques), quelque chose du type "UTC+0100" et pas betement "UTC+01" hein ? Ben en fait, il ne faut pas oublier qu'un fuseau horaire n'est pas nécessairement entier, comme par exemple le Népal qui est à UTC + 5h45 ( fr.wikipedia.org/wiki/Né... ) (et c'est pas le seul). "Dommage."
2 De Balise - 07/04/2008, 22:01
J'y pense sur tes histoires de "deux sexes"... au pif, "équivalence sexe féminin / deux chromosomes X"... un seul chromosome X (syndrome de Turner) => fille, deux chromosomes X ET un chromosome Y (Klinefelter) => garçon :)
3 De Le webmestre - 07/04/2008, 22:42
@Palats : Et bien je me serais fait avoir aussi, je connaissais des fuseaux à +xh30, mais +xh45... !!
@Balise : Dieu merci, on entre encore rarement les chromosomes dans les applis de gestion...
4 De Urbinou - 08/04/2008, 09:22
"Le numéro de Sécurité Sociale identifie un individu de manière unique."
Je constate avec plaisir que notre n° national en Belgique est plus intelligent :)
Il est structuré AAMMJJ-nnn-kk où kk est le modulo 97 de ce qui précède. Et dans notre développement d'accueil d'enfants, je fus surpris que le contrôle soit négatif lorsque des enfants nés en 2000 et au delà étaient encodés. Je me suis alors aperçu que, même si la forme ne change pas, le calcul de contrôle se fait avec un 2 en préfixe pour ne pas le confondre avec quelqu'un né en 1900. Cela a bien sûr impliqué d'envoyer l'année complète de naissance à la routine de contrôle dans toutes les applications... Et en plus, avec seulement un "2" en préfixe, rebelote en 2100 ! Mais je laisse ça à un autre !!
5 De Balise - 08/04/2008, 10:42
@le webmestre : t'en fais pas, ça viendra...
6 De Steph - 08/04/2008, 11:28
"En calendrier grégorien, les années divisibles par 400 (1800, 1900...) ne sont pas bissextiles. "
Par 100 tu voulais dire ?
(ce commentaire est à effacer une fois la bourde corrigée)
(Merci Steph, c’est corrigé - Le webmestre)
7 De miod - 08/04/2008, 17:16
@Balise : ce n'est pas un problème dès lors que l'on cesse de supposer que chaque être humain a forcément 26 paires de chromosomes (donc ni asbence, ni ajout, ni organisation différentes des 52 chromosomes).
8 De miod - 08/04/2008, 17:21
Autre problème standard que l'on rencontre de plus en plus souvent : la supposition que l'arithmétique dans Z/(2^32)Z est équivalente à l'arithmétique dans Z.
Pour les non-matheux : les valeurs entières stockées par un système informatique sont, sauf en de rares cas (bignum) stockées dans des éléments de taille finie, en général limités à 2^32 ou 2^64 valeurs distinctes. 2^32, ça fait un peu mieux de 4 milliards (4 x 10^9), ce n'est pas si énorme que ça. Et si l'on effectue des calculs sur ces valeurs finies sans faire attention, elles bouclent ! À savoir que si on ajoute un à la limite, la valeur devient.. zéro. Ce qui, en général, n'est pas le comportement attendu... et n'est tout simplement pas vérifié par le programmeur, parce qu'il n'a pas testé avec des quantités aussi gigantesques.
9 De Le webmestre - 08/04/2008, 18:54
@miod, Balise : Effectivement, si on suppose un nombre fixe de chromosomes dans chaque humain, on va droit dans le mur. On élimine d'entrée trisomiques et pas mal de monde avec anomalie génétique non létale, et on se coupe d'avance de toute avancée à base de manipulation du génome ou de l'accession au stade de citoyen d'animaux devenus intelligents ou d'extraterrestres immigrés (pour lesquels le concept même de chromosome sera peut-être à jeter).
@miod : Effectivement. Démonstration dans certains jeux, où dépasser 65534 va reboucler à -65534 (découvert dans un Tétris par une condisciple qui faisait son stage en entreprise (!), dans Sim City 2000 où lever les impôts après avoir engrangé le cheat code à plusieurs milliards faisait repasser les caisses à la même somme, en négatif !)
Ça me rappelle aussi que (1/3)*3 peut donner 0,99999999999... et pas 1.
Mais bon, ça ce sont des pièges de développement informatique pur, que le spécificateur n’a normalement pas à prévoir - alors que le numéro de Sécu non unique ou les années bissextiles...
10 De Thias - 08/04/2008, 21:23
À vrai dire, selon les pays, il y a plus ou moins de salutations que Mr, Mme, Mlle. En Allemagne, Dr. est une salutations tout à faire officielle.
11 De PB - 09/04/2008, 02:08
"Ça me rappelle aussi que (1/3)*3 peut donner 0,99999999999... et pas 1"
Pour les mathématiciens, pas de problème puisque 0,9999999999...=1
En informatique, c'est sûr que ça pose plein de problèmes ces choses là...
12 De Le webmestre - 09/04/2008, 15:28
@PB : En fait, l'informatique, c'est des maths, sans les possibilités d'infini...
13 De PB - 09/04/2008, 21:55
@Le webmestre : ou bien les maths, c'est l'informatique, sans les contraintes de mémoire…
14 De neonira - 10/04/2008, 10:48
Dans la même veine, la gestion des jours ouvrables tient la palme, spécialement sur un projet international. Imaginez un projet conduit avec une équipe anglaise et une équipe française, chacune soumise à une législation différente. Jours ouvrables différents, jours fériés distincts et communs, fixes et variables, comptabilisation des journées ouvrées différentes (à la journée en France, à l'heure en GB), fuseaux horaires différents, monnaie légale différente, formats de dates différents, et faux amis. Un bel exemple ou la réunion de deux univers conduit à des règles générales incongrues et inadaptées.
Juste pour info, comptablement une année fait 360 jours. Encore une règle générale ...
15 De vpo - 11/04/2008, 12:32
Pour ce qui est de chromosomes: fr.wikipedia.org/wiki/Plo...
Et la on s'amuse, car des spores on des cycles de vie en etant tanto haploides (que n chromosomes, comme pour nos gametes a nous les humains) tantot diploides (comme nous les humains et pas mal de monde sur terre sans chromosomes en trop / en moins).
Mais il y a des vegetaux triploides voire tetraploides (comme pour la banane) : publications.cirad.fr/une...
Et je ne parle pas des bacteries qui ont des chromosomes specifiques et recombinables entre especes differentes.
Imaginez une application informatique gerant une base de donnee sur les expeces vivantes de notre planete avec leur caracteristiques usuelles : phenotypes, genotypes, maladie usuelles, habitat, etc...
Un vrai cauchemard a specifier a l'avance pour prevoir toutes les exceptions...
Vincent le murphyprosien
16 De Phot's - 12/04/2008, 16:54
Le mois d'août précède le mois d'avril, c'est bien connu... et le dernier mois de l'année est le mois de septembre !
Si, si : quand des dossiers correspondent à des mois de l'année et qu'ils sont nommés en toutes les lettres, le classement se fait alors alphabétiquement... Résultat : avril, août, décembre, février, janvier, juillet, juin, mai, mars, novembre, octobre, septembre.
Parade : nommer les répertoires selon la syntaxe AAAAMMJJ ou Mois avec 2 chiffres (01, 02...). C'est moins esthétique mais permet de structurer les données.
17 De jid - 13/11/2008, 10:50
"Une multiplication puis une division d'un nombre A par un même nombre B redonne le nombre A."
En informatique (et notamment en COBOL) les nombres ont une taille maximale définies à la programmation, si on dépasse ça tronque au lieu de donner une erreur.