Innhold levert av Sylvain Abélard. Alt podcastinnhold, inkludert episoder, grafikk og podcastbeskrivelser, lastes opp og leveres direkte av Sylvain Abélard eller deres podcastplattformpartner. Hvis du tror at noen bruker det opphavsrettsbeskyttede verket ditt uten din tillatelse, kan du følge prosessen skissert her https://no.player.fm/legal.
Player FM - Podcast-app Gå frakoblet med Player FM -appen!
At the dawn of the social media era, Belle Gibson became a pioneering wellness influencer - telling the world how she beat cancer with an alternative diet. Her bestselling cookbook and online app provided her success, respect, and a connection to the cancer-battling influencer she admired the most. But a curious journalist with a sick wife began asking questions that even those closest to Belle began to wonder. Was the online star faking her cancer and fooling the world? Kaitlyn Dever stars in the Netflix hit series Apple Cider Vinegar . Inspired by true events, the dramatized story follows Belle’s journey from self-styled wellness thought leader to disgraced con artist. It also explores themes of hope and acceptance - and how far we’ll go to maintain it. In this episode of You Can't Make This Up, host Rebecca Lavoie interviews executive producer Samantha Strauss. SPOILER ALERT! If you haven't watched Apple Cider Vinegar yet, make sure to add it to your watch-list before listening on. Listen to more from Netflix Podcasts .…
Innhold levert av Sylvain Abélard. Alt podcastinnhold, inkludert episoder, grafikk og podcastbeskrivelser, lastes opp og leveres direkte av Sylvain Abélard eller deres podcastplattformpartner. Hvis du tror at noen bruker det opphavsrettsbeskyttede verket ditt uten din tillatelse, kan du følge prosessen skissert her https://no.player.fm/legal.
Innhold levert av Sylvain Abélard. Alt podcastinnhold, inkludert episoder, grafikk og podcastbeskrivelser, lastes opp og leveres direkte av Sylvain Abélard eller deres podcastplattformpartner. Hvis du tror at noen bruker det opphavsrettsbeskyttede verket ditt uten din tillatelse, kan du følge prosessen skissert her https://no.player.fm/legal.
Bonjour, aujourd’hui nous parlons de relatif et d’absolu. Le concept est abstrait, mais utilisé partout, mais vous le comprenez déjà très bien. Malheureusement il y a parfois des confusions. Contexte Par exemple, quand vous dites “ma chambre est au premier étage”, on suppose sans autre information qu’il s’agit de votre maison ou votre appartement. Si vous êtes en déplacement, qu’il s’agit de votre hôtel ou lieu de résidence. L’information est relative à quelque chose. Mais si vous donnez l’adresse, il n’y a plus de doute. On peut retrouver votre chambre dans l’absolu. Il y a un contexte qui aide à trouver “à partir de quoi” vous parlez. Désambiguisation Malheureusement la confusion cause souvent des erreurs, non pas de débutant mais d’étourderie, puisque ça arrive aussi aux experts. C’est juste que quand ça leur arrive, ils savent vite le voir car c’est en quelque sorte dans leur “checklist” interne de pistes d’attaques pour débugguer : le débutant ne l’a pas encore et c’est en rencontrant cette erreur (et tant d’autres) qu’il deviendra expert. Le système de fichiers : un arbre Depuis longtemps, les ordinateurs traitent des fichiers, qu’ils rangent dans des dossiers, et on peut mettre autant de dossiers qu’on veut dans un dossier. Bref, on a une sorte d’arbre. C’est une métaphore très utile qui nous sert depuis longtemps, dont “tout le monde” a l’habitude. Elle montre peut-être ses limites, on nous promettait des systèmes de fichiers basés sur des “tags” et peut-être que les terminaux mobiles et les applications Web sont en train de nous changer nos habitudes, mais ce n’est pas encore tout à fait ça. Arborescence de fichiers Bref, quand vous naviguez dans un explorateur de fichier, vous avez un point de départ, un endroit où vous êtes en ce moment, et un point d’arrivée désiré. En version graphique on espère que l’outil vous aide visuellement à situer où vous êtes. Windows, MacOSX et les différents Unix vous proposent souvent plusieurs points de départ : une “racine” d’arbre par support physique : je suis sur un disque dur ou une clé USB quelques points d’entrée : système/applications, mon compte/mes documents Et ensuite on navigue de plus en plus profond dans les dossiers, on remonte, etc. Chaque dossier est noté, pour Unix avec des barres obliques (slash), pour Windows avec des antislash (ou backslash). PATH On pourrait croire que dans la ligne de commande, il n’y a que deux points d’entrée : le dossier racine / , et votre dossier personnel ~ . Et bien non ! Il existe une variable d’environnement, le PATH (chemin) qui dira, quand vous cherchez une commande, où aller la chercher. Votre shell va d’abord regarder si c’est pour lui (un builtin), puis dans chacun des dossiers de départ. Faites echo $PATH et vous verrez la liste séparée par des “deux points”, par exemple /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin . Quand vous utilisez des gestionnaires de paquets, ils essaieront probablement d’ajouter dans ce PATH un dossier pour que le système regarde d’abord s’il n’y a pas le binaire voulu dedans. Quand on fait des ateliers d’installation avec des débutants, on se retrouve rapidement à gérer des erreurs du genre : soit l’exécutable n’est pas où on veut, soit le dossier que l’on veut n’est pas dans le PATH. Le Web Quand le Web a été inventé, il était lui aussi calqué sur l’échange de fichiers, la mise à disposition de ressources à des endroits précis, et a très naturellement calqué ses URL (Universal Resource Location), emplacement universel de la ressource, un peu comme des fichiers, d’où les slash dans de nombreuses adresses. Imaginons http://bibliotheque.fr/sciences_et_techniques/informatique/web/url.htm une adresse avec le protocole, le domaine, puis une arborescence de fichiers qui ne devrait jamais changer vous permet aussi de voir un peu la structure qu’ils ont choisi, pour explorer davantage Rails En Ruby on Rails, on fait bien davantage que juste accéder à des fichiers ou des représentations d’enregistrements de base de données. On a potentiellement toute une application qui tourne avec des actions différents et des process métiers spécifiques. Au départ, le routage de base donnait par exemple /users/show/1 pour aller voir les utilisateurs (et le UsersController), son action show (la méthode que vous avez codée) avec l’identifiant 1. REST Dans les applications Rails récentes on ne voit même plus le /show . On ira voir /users/1 et on lui dira quelque chose : on va soit lui demander de se présenter, soit lui ordonner des modifications, soit le supprimer ou juste voir s’il existe sans se soucier des détails… Ce sont respectivement les verbes HTTP GET, POST, DELETE, HEAD. Il y a bien plus de verbes et de nuances dans l’utilisation qu’on en fait, mais ce sont les conventions que Rails utilise, et donc celles dont j’ai le plus l’habitude dans mes projets, ceux que je donnerai aux autres et ceux que je récupèrerai des autres. Encore une histoire de contexte à réexpliquer ou non. URLs En réalité, une requête Web est un peu plus complexe : il y a une partie visible que vous voyez dans la barre d’adresses du navigateur, et une partie cachée qui donnera des informations en plus. Le fameux verbe, les fameuses données à envoyer, les cookies etc. Relatif et absolu Pour en revenir au sujet, on voit bien que répéter l’aborescence est parfois pénible : quand vous demandez votre chemin, on vous donnera souvent à partir de là où vous êtes, allez dans telle direction jusqu’à tel repère etc. On ne vous réexplique pas comment arriver là où vous êtes en ce moment, on ne vous donne pas l’adresse ou la position GPS, mais plutôt quelque chose comme “troisième à gauche”. De même, quand vous donnez une adresse Web, quand le moyen le plus simple est de dire “par rapport à là où vous êtes, allez dans ce sens-là”, ça vous embête de répéter “pour tel site web à tel endroit de départ”. HTML HTML vous permet, dans les liens, via les références hypertexte ( href ) soit de commencer par le protocole (ou double slash // pour dire “reste comme ça” : HTTP reste HTTP et HTTPS reste HTTPS) et le nom de domaine ( zenm4.net ), soit à partir du début de l’arborescence du site, avec un slash ( /archive ou /img/barque.png ) ou encore juste un nom de fichier ou dossier, sans slash, qui signifiera “à partir du dossier dans lequel je me trouve”. Rails Rails cache beaucoup de “magie” dans son helper link_to , ou plus précisément url_for : vous pouvez mettre un objet ActiveRecord, et il tentera de voir si le routage, pris en sens inverse, permet de lui donner une URL vous pouvez mettre des options et il tentera de trouver la bonne URL en imaginant que tout ce que vous lui précisez, c’est parce que ça change, et tout ce que vous ne lui précisez pas ne change pas (changer d’action dans le même contrôleur etc) vous pouvez mettre du texte respectant la norme des liens HTML et il ne devinera rien, considérant que vous savez ce que vous faites CSS Même le CSS s’y met avec la directive position: absolute : HTML permet de décrire une structure de boîtes dans des boîtes, et CSS permet de préciser des règles d’affichage de ces boîtes. Par défaut, tout est dépendant de la boîte dans laquelle vous êtes, donc tout est relative , mais parfois vous voulez préciser que c’est à partir du coin en haut à gauche de la page, donc absolute , voire indépendamment de la page, fixé sur l’écran, donc fixed . Fini la confusion Voilà ! Comme toujours j’espère avoir démystifié le sujet et que cela vous permettra de ne pas vous faire avoir par la suite. Quand votre installation rate, votre fichier n’est pas trouvé, vos liens ne fonctionnent pas en HTML ou Rails, vos affichages visuels sont décalés… vérifier si vous parlez en absolu, ou bien en relatif, et si oui par rapport à quoi. C’est un outil crucial dans votre “boîte à outils de débuggueur”, aussi important et bête que “avez-vous bien branché les câbles”, “est-ce qu’il y a du courant électrique” ou “êtes-vous connecté à Internet”. Clarté et concision Je n’ai pas de préférence entre l’un et l’autre. Chaque cas d’usage fera que l’un est plus pratique que l’autre, soit plus clair, explicite et verbeux, soit plus concis. Si vous pensiez tout savoir, si vous pensez avoir perdu votre temps, rappelez-vous surtout si vous formez de grands débutants que c’est pourtant loin d’être évident : c’est en reformulant les référentiels et en questionnant les bases que de grandes découvertes scientifiques ont été faites (géocentrisme, héliocentrisme, physique de Newton et relativité). Carl Sagan disait “si vous voulez faire une tarte aux pommes à partir de zéro, vous devez commencer par inventer l’univers”. Blague à part, aucune communication humaine ne peut tout réexpliquer, toutes se basent forcément sur des postulats de base. Ça fait parfois du bien de les revisiter pour s’assurer qu’on est toujours dans le même référentiel. À bientôt !…
Retour à l’école et aux épisodes “concept” pour parler des graphes ! En première année de prépa en cours d’algo, j’ai vu trois structures de données principales que sont les listes, les arbres et les graphes. Encore une fois, mon but n’est pas que les profs d’algos s’étranglent scandalisés devant ce que je raconte, mais de dédramatiser pour les débutants et leur mettre le pied à l’étrier. Listes, Arbres, Graphes Évidemment il y a énormément à dire sur chacun, la clé est que chaque fois que vous arrivez à représenter le problème que vous avez, sous des formes connues, vous avez tout un ensemble de connaissances à votre disposition. Et à chaque spécificité de votre problème, vous avez soit la chance d’avoir des contraintes qui simplifient les algos connus ou vous permettent d’éviter des prises de tête, soit la malchance de ne pas rentrer dans les cases de ce qui est couramment étudié et présenté, et de devoir trouver les astuces vous-mêmes. On a parlé des listes chaînées, et des énumérations en Ruby, et bien qu’il y ait de nombreuses variantes et astuces à ajouter, je pense en rester là. Je n’ai pas encore parlé des arbres, principalement parce que je n’ai eu ni d’inspiration, ni vu de problème majeur et explicable simplement : soit des étudiants se battre sur des points d’algo assez techniques, soit des gens qui n’avaient pas vu que leur problème était en réalité à représenter sous forme d’arbre, mais le concept en lui-même me semble assez bien compris. Graphes La manière dont je visualise un graphe, c’est un GPS ou une carte des transports, disons le métro parisien. Quand vous dessinez un graphe, vous avez des boîtes ou des points reliés par des lignes ou des flèches. Les relations sont des arcs (“arêtes”), les éléments reliés entre eux, des noeuds (“sommets”). La carte du métro vous représente les lignes et stations, d’ailleurs de manière simplifiée par rapport à la réalité : vous n’avez pas les sorties, les couloirs, le temps de trajet représenté fidèlement. Les deux choses les plus simples à faire avec un tel graphe sont : lister les stations (parcours du graphe sans rien oublier) trouver un plus court chemin entre deux stations Les façons les plus simples de faire sont de choisir un point de départ, et de tout lister ensuite à partir de là. Pour trouver une stratégie adaptée, on doit se poser plusieurs questions. Graphe orienté Est-ce que je peux toujours faire marche arrière ? Dans la plupart des stations du métro parisien, oui. S’il y a un tunnel entre deux stations, il les relie dans un sens et dans l’autre. Mais sur quelques endroits, on a des sens uniques : ligne 7bis ou Michel Ange (Auteuil/Molitor) lignes 9 et 10. Le graphe du métro parisien est orienté (ou dirigé) : si vous trouvez un chemin pour aller d’une station à une autre, le chemin retour ne sera pas forcément exactement le même. Graphe connexe Est-ce que toutes les stations sont reliées entre elles ? A priori, oui. On peut débattre sur le funiculaire de Montmartre, mais c’est à peu près tout. Par contre, imaginez un instant que telle ou telle ligne ou station soit fermée : travaux, grèves, incidents, ou même correspondance fermée vous obligent à changer de trajet. Le métro parisien est si dense qu’on imagine mal une situation où il représenterait deux graphes coupés qui ne peuvent pas communiquer entre eux. À la rigueur, couper le pont de Charenton : le terminus de Créteil est assez loin mais la ligne 8 n’a pas de correspondance après Porte de Charenton. Bien entendu, dans ces cas-là, il n’y aurait probablement pas de métro entre les poignées de stations qui restent seules. Mais si on représente le graphe de toutes les voies ferrées françaises et britanniques, quand le Tunnel sous la Manche est fermé, on a bien deux graphes assez grands qui ne sont pas reliés entre eux. Graphe pondéré Est-ce que tout chemin d’une station à ses voisines prend le même temps ? À Paris, bien sûr que non. Certaines stations sont proches et d’autres éloignées. Si on veut vous proposer un chemin optimal, c’est une information intéressante à prendre en compte : non seulement il y a des trajets plus courts, mais il y a aussi des correspondances plus simples, mais il y a aussi dans la vraie vie le fait de marcher plus ou moins longtemps en surface et choisir les bonnes stations de départ et d’arrivée. En voiture, votre GPS va même probablement avoir des poids différents, voire toute une liste de contraintes : les kilomètres à parcourir, mais aussi les vitesses maximum autorisées voire le trafic en temps réel, pour calculer le temps ; l’argent, les voies limitées en hauteur ou largeur… Plus court chemin À partir de là, vous pouvez envisager plusieurs algos de cartographie par analogies simples : vous partez d’une station, et on va simuler presque tous les chemins possibles entre départ et arrivée. Si vous le faites vous-mêmes, vous allez repasser par plein de stations. Plus rapide, vous le faites avec une équipe, ou disons une infinité de clones de vous-mêmes, qui doivent pouvoir se parler pour comparer les chemins empruntés. Et là, la métaphore a atteint ses limites : quand on rédige un algorithme, on doit se rappeler que l’ordinateur est très bête, il ne se rappellera de rien de particulier sauf si vous lui dites de faire attention. Un algo un peu naïf pourrait l’oublier et ferait des recherches à l’infini, en passant sans cesse par les mêmes stations. Ça nous mène à une propriété et une contrainte de plus : Graphe cyclique Est-ce que partant d’une station, je peux y revenir ? À Paris, oui, vu le nombre de lignes et le fait que presque tous les chemins sont faisables en sens inverse. Comme dans la vraie vie, on sait bien qu’on est en train d’évaluer un chemin qu’on a déjà vu, dans la plupart des algorithmes on va conserver quelque part une liste des sommets qu’on a déjà visités. Cycle absorbant Est-ce que je peux faire tourner le temps à l’envers ? OK ce n’est pas la meilleure formulation, mais imaginons des poids négatifs dans un graphe pondéré. Dans l’image du métro, on ne peut pas revenir dans le temps, aucune arête n’a de poids négatif. A fortiori, il n’existe pas de boucle de transports qui vous ferait revenir dans le temps. Mais imaginons que vous avez construit un graphe pour représenter une suite de choix et d’étapes, certaines où vous payez de l’argent et d’autres où on vous en rend. Si vous trouviez une combine pour gagner de l’argent indéfiniment, pourquoi pas : elle n’est probablement soit pas légale, soit pas éthique, soit avec des conditions de départ particulièrement restrictives, mais pourquoi pas. En tout cas, parcourir un tel graphe pour trouver le coût le moins cher est une question qui n’aura pas de sens, puisque le moins cher serait “moins l’infini”. La plupart des algos de plus court chemin ne savent pas gérer ce cas-là, le mieux qu’ils puissent faire c’est détecter quand ça arrive. Liste d’adjacence On a raisonné tout l’épisode sur la carte du métro. Comment on pourrait stocker de telles informations dans un ordinateur ? Deux des méthodes les plus utilisées sont la liste d’ajacence et la matrice d’adjacence. La liste d’adjacence, c’est quand chaque station connaît ses “voisines”, celles qu’on peut atteindre à partir de là. C’est ce que vous avez affiché ou annoncé dans de nombreux systèmes de transport : la station suivante et les correspondances. On n’en parle pas dans les transports mais bien évidemment, dans votre code, il faudrait mentionner la station précédente si on peut y aller (hors cas du sens unique donc). Matrice d’adjacence Et la matrice d’adjacence, c’est faire un tableau avec tous les sommets en ligne d’en-tête, tous les sommets en colonne d’en-tête, et à chaque case correspondante, ces sommets sont-ils reliés par un arc ? Oui, non, et le cas échéant avec quel poids ? Ça ressemble un peu à ce que vous avez dans les cartes routières ou sur des tickets de péage : à titre indicatif, de telle ville à telle ville, tant de kilomètres ou tant d’euros. Et comme on peut faire l’aller et le retour, c’est souvent représenté sous forme de triangle : je ne peux pas lire “de Toulouse à Bordeaux”, mais je peux trouver “de Bordeaux à Toulouse”. Si le graphe était orienté, on aurait besoin du tableau complet. Essayez de l’écrire sur papier ! À écrire comme à lire, on voit rapidement que la liste d’adjacence est plus pratique quand il y a peu d’arêtes, de connexions, et que la matrice d’adjacence est plus adaptée quand il y a beaucoup de connexions entre les sommets. Ce n’est pas toujours le cas qu’une intuition s’avère vraie, alors autant le noter :) Le cours n’est pas terminé L’épisode va s’arrêter là, mais bien sûr le cours sur les graphes va plus loin : définitions précises, algos différents et calculs de complexité, et puis plusieurs outils de transformation, par exemple représenter un graphe sous forme d’arbre etc. Ça permet quand on coince sur une représentation qui ne nous aide pas beaucoup, de retomber sur des situations qu’on maîtrise mieux, ce qui est une excellente méthode à suivre quand vous bloquez sur un cas précis.…
Suite de l’épisode 15 sur le debugging. On a vu comment un bug peut arriver, et on en a détecté un. Maintenant, comment le résoudre et comment réagir ? Et comment gérer humainement ce qui se passe autour de vous ? Urgence J’avais pris le parti de regarder du côté de la médecine, mais parlons maintenant des interventions et secours d’urgence. Les formations de premiers secours vous donneront trois étapes : protéger, alerter, secourir. Protéger Protéger, c’est éviter le suraccident. Si une erreur source vous cause des problèmes en pagaille, et si vous avez une idée de ce que ça peut être, évaluez rapidement et limitez les dégâts. Alerter Alerter, c’est prévenir qui de droit : qui a été ou est encore impacté, que doit-il absolument savoir tout de suite, pour ne pas le noyer dans les informations inutiles, peut-il agir, que recommandez-vous… Secourir Et enfin, secourir, c’est à dire a minima s’assurer que lorsque les secours arrivent, la personne en détresse n’est pas dans une pire situation qu’auparavant. Si vous résolvez le tout, tant mieux, mais il y aura probablement l’avis d’un professionnel de santé plus tard, question de responsabilités. Reprenons dans notre contexte. Protéger : coupure d’urgence Dans certains cas, et sûrement en accord préalable avec ceux que ça concerne, la solution la plus simple est de “tout couper”. Comme vous pourriez couper le disjoncteur ou le gaz en cas d’incendie, ou l’eau en cas d’inondation de votre appartement : si le site Web institutionnel de votre entreprise est tombé, ce n’est pas sérieux, mais s’il a été “défiguré” par des pirates, c’est pire. Peut-être vaut-il mieux le couper le temps de comprendre et réagir. Souvent, on aura mis des barrières pour éviter les attaques massives : au bout de plusieurs tentatives erronnées pour votre code de carte bleue ou de téléphone, ça se bloque, ou ça attend de plus en plus longtemps. Alerter : qualification de bug Quand vous appelez les secours (pompiers, SAMU…) ils vous posent un certain nombre de questions pour qualifier votre urgence : un nid de frelons ou d’abeilles, ce ne sont plus les pompiers qui gèrent un arrêt cardiaque, c’est plus urgent qu’une jambe cassée un souci de santé exige ambulance et médecin, pas un camion incendie un carambolage avec 3, 10, 30 voitures n’a pas le même nombre de blessés Bref, savoir quels moyens (type, nombre) mettre en face de votre besoin, et s’occuper de vous au mieux sans priver quelqu’un dans une urgence encore plus grave. et selon les cas, faut-il aussi contacter la police ? Les gens du centre de répartition pourront se coordonner avec d’autres services pour alerter, communiquer, limiter les dégâts ou assurer une continuité de service : par exemple lors d’un accident de la route, il y aura les constatations à faire, et la circulation à assurer. Prioriser Une fois identifié, un bug finit souvent dans un outil de ticketing ou bug tracker : un produit du marché, quelque chose de dédié, de fait maison, ou comme très souvent rangé dans un tableur. On apprécie en général de pouvoir noter la gravité de chaque bug, pour savoir ce qui est prioritaire. Et là, la médecine a deux mots utiles pour nous : “aigu” et “chronique”. Une douleur aigue est typiquement courte et intense, elle s’impose à vous. Une condition chronique se fait dans la durée… et peut causer, à terme, des épisodes aigus. À vous de voir comment vous priorisez. Secourir : “cellule de crise” Tous les bugs ne le justifient pas forcément, mais on peut s’inspirer de plusieurs protocoles que mettent en place notamment les pompiers, l’armée, mais aussi des cellules de relation presse en cas d’incident. On trouve assez souvent des process réinventés par chaque équipe, mais les points qui reviennent souvent sont : une seule personne qui supervise et décide une seule personne qui sert de point d’entrée et de communication déranger le moins possible les personnes qui résolvent Bref, une “cellule de crise” ou “war room” pour améliorer la communication et les retours rapides. C’est très bien mais les petits malins se demanderont toujours pourquoi on n’a pas mis en place avant un système de communication inter-équipes efficace. À vous de voir. La vie reprend son cours En parallèle à l’incident ou après celui-ci, il faudra bien reprendre un jour le cours normal des événements. Je ne vais pas m’étendre sur les PCA et PRA, plans de continuité ou reprise d’activité, mais c’est là qu’on verra si vous en avez un, s’il a été testé, et s’il marche. Rétrospective On essaie aussi au maximum de noter les étapes de résolution : si on se rate lors des correctifs, on pourra savoir où et quand on s’est ratés, pour faire une reprise sur incident. Puisque tout est déjà écrit, ça peut aussi devenir à terme un nouveau processus dans l’équipe : si le problème revient, on saura mieux chercher, mieux résoudre, et limiter les pistes à explorer. De même, quand des médecins se renvoient votre cas les uns les autres, ils font parfois pour eux, parfois par contrainte réglementaire, parfois pour la recherche, des notes sur ce qui marche ou marche pas, afin de mieux réagir les fois d’après. Puisque j’ai choisi une analogie avec la médecine, je préfère le mot “rétrospective”, mais on trouve souvent le mot “post-mortem”, notamment dans le cas des attaques informatiques. Blameless Post-Mortems Une bonne rétrospective doit être faite avec des informations fiables pour occasionner le changement voulu : process, doc, code, infra… afin qu’on gagne du temps et de la confiance par la suite. Mais elle se fait forcément après l’incident. On souffre donc : de ne pas la prioriser car on a plus urgent (on ne s’améliorera pas) de la voir se transformer en distribution de claques (culture du blâme) et donc de ne pas avoir d’informations fiables (tendre le bâton pour se faire battre) Là encore, j’espère que si ça n’est pas le cas dans votre équipe, vous aurez l’occasion d’expliquer pour mettre ça en place sereinement. Humainement Pour tout le monde, l’enjeu est d’accepter l’erreur humaine mais d’avoir un process robuste mais flexible, “résilient”, qui résiste à ce genre d’erreurs. Un moyen simple et que le monde hospitalier a mis en place pour cela, c’est une abondance de check-lists : toutes ces questions pour s’assurer que vous êtes bien le bon patient, venu pour telle raison, qui a ou n’a pas pris tel médicament, n’a pas fait tel voyage etc. On parlera peut-être un jour des estimations, qui prendront au moins un épisode à elles toutes seules, mais pour le moment dites-vous juste que, bien que tous mes conseils insistent pour garder son calme, résoudre les choses correctement après enquête, il y a forcément un sens de l’urgence pour certains, et que leur répondre “on verra quand ce sera fait” n’est pas satisfaisant. Empathie et compassion Bien sûr, tout le monde peut le comprendre, que penserait-on d’un médecin qui vous annonce votre problème sans vous avoir examiné ? Question de sérieux, de professionalisme, et de bon sens. Mais quand vous gérez un bug en tant que développeur ou développeuse, pensez à ce que vous répondez à vos clients et demandez-vous “comment je le prendrais si j’étais malade et que les médecins me disaient cela ?” Dans ces situations, n’oubliez jamais de faire preuve d’empathie et de compassion. Non seulement c’est la base du respect, mais vous risqueriez bien d’en apprendre davantage sur le métier, les contraintes non dites, et avoir des idées pour la suite en terme de priorisation, communication, et prévention.…
Bienvenue dans l’épisode 15, sur le debugging. On ne va pas parler des méthodes de résolution de bugs, qui vont dépendre de chaque langage, plateforme, et bug bien sûr. Ce qui va m’intéresser ici c’est de voir comment un bug peut arriver, comment le résoudre, et comment gérer ce qui se passe humainement durant les étapes de résolution du bug. Là encore j’ai de quoi faire une petite série, pour l’instant en deux épisodes : aujourd’hui sur la détection et la réaction au bug, et la semaine prochaine sur la résolution du bug. Il n’est pas impossible que d’ici quelque temps on reprenne le sujet si ça vous intéresse et si je trouve encore d’autres choses à dire. Quoi de neuf, docteur ? Pour ne pas épuiser la métaphore sur la voiture, et parce que bien souvent on rabaisse les développeurs à des exécutants techniques, je vais plutôt choisir une métaphore filée sur la médecine. On parle parfois d’un développeur sur un bug comme d’un pompier, un démineur, mais je n’aime pas le côté urgence forcée, et l’absence de responsabilité que cela sous-entend. Pour moi, intervenir sur un bug, c’est comme être le médecin traitant face à quelques symptômes. On pourrait dire chirurgienne, mais j’aime moins l’aspect d’intervention certes d’une haute technicité, mais ponctuelle et qui ignore la santé globale : à résoudre les soucis un par un, on peut facilement oublier d’avoir une vision générale. Les causes Je suis obligé de commencer par la définition du mot “bug” la plus générale qui soit : quelque chose d’inattendu ou de néfaste que l’on attribue (à tort ou à raison) à votre système. Et donc la cause la plus générale qui soit, c’est qu’un postulat sur lequel vous vous basiez… n’est plus valide en ce moment. Ça peut être dans votre infra, vos données, votre code, votre documentation ou vos spécifications. Pour être clair, il y a quelque chose de : physiquement cassé : connexion, serveur… mal tourné dans l’environnement : configuration, dépendances… différent de vos attentes dans les données, ce qui peut “casser” un algo… mal exprimé dans votre documentation, et ça coince ceux qui dépendent de vous pas très clair dans les messages d’erreur ou options proposées pas prévu ou mal anticipé dans vos spécifications dangereux dans la résolution hâtive d’un bug, qui cause un autre bug ! Ou enfin, tout simplement, c’est que votre code est en défaut. Le corps médical a le même problème : outils cassés, prescriptions mal suivies parce que pas claires ou trop contraignantes, situation imprévue, combinaison de médicaments ou de maladies aux effets combinés désastreux… Sans parler de l’environnement global du patient qui serait toxique ou délétères (mauvaises habitudes…) et ça finit toujours pareil : quelqu’un va voir son ou sa médecin (qui est rarement la cause du souci), exige une solution (rapide si possible), et le tout sous peine de conséquences (parfois dramatiques). Le message n’est pas clair De même, un diagnostic est parfois difficile quand il y a une ou plusieurs causes de départ, mais qu’on ne les voit pas parce que les informations sont cachées, conflictuelles, similaires à un autre cas… pensez à la série Dr House si vous voulez un exemple. Mais, c’est pas mon problème ? Pourquoi ai-je tenu à faire cette liste si longue et qui parle si peu de code ? Tout d’abord parce que les cas de la vraie vie sont au moins aussi nombreux. Mais aussi parce qu’on tentera d’attribuer des erreurs de ces huit catégories-là à votre code, faute de mieux comprendre ou par calcul politique. Pour être clair, parce qu’il y a quelqu’un qui pense “ce bug, c’est pas mon problème”. Enfin, pour ne pas vous entendre, en tant que développeurs et développeuses, dire ce genre de phrase. Parce que toutes ces catégories sont ou devraient être de votre ressort : comprendre les implications des choix en amont, en aval, savoir dire non et expliquer les options à ceux qui feront les choix. Accepteriez-vous de voir un médecin qui se dédouane de vos problèmes ? Un ou une médecin a une position de prestige, de pouvoir, et vous êtes en position de dépendance. Les sujets abordés vous touchent directement. Les décisions ont intérêt d’être claires et concises. On n’accepte pas d’être cobaye, de jouer aux devinettes. Toute action doit être motivée et expliquée, y compris quand il s’agit de se dessaisir du sujet pour le confier à un confrère ou une consoeur. Et pourtant, on serait tellement en colère de voir une décision hâtive et fausse prise avec autorité et aplomb, se révéler fausse : on se sentirait trompé, on perd confiance, on peut se mettre en colère ! Mais à l’inverse, ça donne davantage confiance de s’entendre dire “je ne sais pas, on va chercher” ou “j’ai une piste, on va faire des examens pour confirmer”, ou encore “j’ai plusieurs pistes, on va tester pour voir”. Avant le bug : monitoring Je n’ai pas retrouvé de source mais Toyota avait une manière de décrire les problèmes, non par leurs conséquences comme souvent, mais comme étant une déviation de la norme. Les tests médicaux, analyse ou monitorings sont chers ou pas pratiques. On aura tendance à ne les faire que quand tout va mal. C’est un peu dommage, et c’est pourquoi on encourage non seulement à un suivi de ce qui a été mal un jour, mais aussi parfois à un checkup régulier. Avant de se dire ce qui est normal, il faut pouvoir le suivre, savoir ce qui est dans la norme ou pas. Et encore, pensez à la météo, aux pollens ou aux grippes : il y a la norme saisonnière. Pour un site web de commerce, par exemple, quelles sont les heures, les jours de la semaine, les périodes de l’année les plus importantes ? Après le décès de Michael Jackson, Google a reçu tellement de requêtes qu’ils ont cru à une attaque. Après chaque événement marquant, Wikipedia reçoit un flot de modifications plus ou moins légitimes : il est important d’avoir un plan d’action, même s’il dit juste “attention, il se passe davantage de choses que la normale”. Identification du bug L’identification d’un problème est facilitée si vous avez un monitoring en place. Sinon, c’est souvent par hasard, par chance (en anticipation), ou parce que les conséquences de votre bug vont remonter avec bruit. Je pense qu’il y aurait beaucoup à dire, et chaque métier a probablement ses moyens d’améliorer et d’anticiper l’identification de problèmes, mais ça dépend tellement de chaque cas que je vais arrêter là. À la semaine prochaine ! Et voilà, on a vu ce qu’on peut faire avant et au moment où l’on détecte un problème, à la semaine prochaine pour voir comment on peut réagir et corriger ce bug !…
Bienvenue dans l’épisode 14 ! On va continuer un peu sur la sécurité, après un épisode complet sur une approche générale et un autre sur les injections. Il nous reste deux types de failles du top 10 de l’OWASP, et dans ma grossière qualification ça donne : “faux et usage de faux” (impostures, arnaques…) “la porte était ouverte” (ou une autre porte) “trop d’infos disponibles” La sécurité par l’obscurité Mais dès qu’on se dit que laisser trop d’infos c’est une mauvaise sécurité, on pourrait croire qu’une bonne sécurité c’est laisser peu d’informations. Bien entendu, ça ne suffit pas. Trop d’infos, ça augmente les chances qu’un attaquant trouve une porte d’entrée, et pourquoi pas un moyen spécifique de l’attaquer (on réduit les possibilités auxquelles il devrait se préparer), mais la base reste quand même d’avoir toutes ses portes bien sécurisées. Si votre clé est sous le paillasson ou sous un pot de fleurs, elle n’est pas en évidence, mais vous avez quand même un double dans la nature et vous ne faites qu’espérer que personne ne le trouvera. Au lieu de vous dire “ma porte et ma clé sont sécurisées”, vous devez alors vous assurer que : personne n’ira par hasard chercher sous le paillasson lors des rares occasions où je dois chercher mon double, personne ne me voit quand je donne la cachette à une connaissance, personne n’entend Et bien sûr puisque vous avez transmis votre confiance, s’assurer que cette personne mérite cette confiance, ne fera pas de double, n’ébruitera pas votre secret, etc. Passe et Backdoor Entre parenthèses, c’est tout à fait l’enjeu du récent procès entre Apple et le FBI : autoriser une “Master Key”, un passe, surtout si c’est public, fait que les attaquants ne vont plus nécessairement chercher à pirater les maisons une par une, mais simplement tenter de récupérer le passe qui leur ouvrira d’un coup toutes les maisons. La porte n’était pas fermée La sécurité d’une chaîne est celle de son maillon le plus faible. L’adage est connu. Le plus bête : vous avez une super porte, mais vous avez oublié de la fermer en partant. C’est le cas “mauvaise configuration” de l’OWASP : vous avez des outils, qui sont bons et bien choisis, mais vous les utilisez de travers, ou vous oubliez de les brancher. La fenêtre était ouverte Presque aussi bête, puisque ça ne vient pas de vous : une de vos dépendances est vulnérable. La porte d’entrée est fermée, mais il y a une fenêtre ouverte au rez-de-chaussée. Tous nos systèmes informatiques et tous nos logiciels sont composés de nombreuses petites parties qui s’articulent entre elles. Si vous vous basez sur tel outil ou telle bibliothèque un peu vieille, sa dernière version a peut-être mis des correctifs de sécurité. Ne pas la mettre à jour, c’est risquer de se faire attaquer par là. Le problème c’est que les dépendances d’un logiciel sont de plus en plus nombreuses et ajoutent elles-mêmes d’autres dépendances. La vérification de chacune devient vite pénible, sauf si vous la faites automatiquement. Heureusement, chaque langage et framework vient de plus en plus avec son gestionnaire de dépendances, et outre les commandes pour installer et mettre à jour des paquets, ces outils proposent souvent aussi de lister les paquets à mettre à jour, obsolètes etc. La porte est restée ouverte trop longtemps C’est un peu le cas du fraudeur qui passe le portillon du métro derrière d’autres : la porte est là, elle marche, elle est plutôt bien dimensionnée, mais il y a des cas où c’est ouvert trop grand, trop longtemps etc. Ce n’est pas suffisant, mais c’est la raison pour laquelle certaines applications vont vous déconnecter après un temps d’inactivité, vous faire changer de mot de passe de temps à autre, vous rappeler de supprimer les accès qui n’ont plus raison d’être, rappeler de ne pas prêter son badge, etc. L’accès pièce par pièce, placard par placard Enfin, la métaphore a là aussi atteint ses limites d’utilité. Je parlais de la sécurité de votre habitation, et il y a un “dehors” et un “dedans”. Une fois “dedans” on peut tout faire. Dans un logiciel, on peut et on veut souvent être bien plus spécifique : une zone pour les administrateurs et une zone pour les clients, très souvent. On pourrait dire aussi : une zone pour la gestion de stock, une autre pour la comptabilité. Un accès pour la succursale de chaque département, et un accès global pour consolider les infos. Imaginez une telle finesse chez vous : le facteur peut entrer s’il a un trop gros colis, mais ne peut que laisser un colis dans l’entrée ; la voisine peut nourrir le chat, mais pas aller dans les chambres ; les enfants ont accès aux placards pour les boissons et le repas, mais pas pour piller les desserts et les bonbons. L’une des failles d’OWASP est d’oublier ou de mal configurer ce genre d’accès. Dans leur section propre à Ruby on Rails, ça donne même un conseil de plus : utiliser les “strong parameters” pour que le concept “modifier un enregistrement” se limite à certains champs, et eux seuls. Je laisse trop d’infos Maintenant qu’il est clair que cacher des choses ne vous sauvera pas, on garde quand même la logique de rendre les attaques plus dures, plus longues, plus complexes et plus visibles. Bref, on peut quand même éviter de simplifier les attaques. Par exemple, un attaquant peut tenter de vous envoyer un email en se faisant passer pour votre banque. S’il se trompe de banque, non seulement il ne vous aura pas, mais en plus il va potentiellement vous mettre la puce à l’oreille pour la prochaine tentative. S’il fait un envoi de plusieurs spams avec chacune des banques les plus probables, l’attaque est plus longue et plus visible, et vous vous doutez non seulement qu’on vous en veut, mais d’où les attaques viennent en ce moment. En cas de doute, vous serez plus enclin à appeler votre banque pour confirmation, et elle vous précisera en général comment identifier un mail qui vient bien de chez eux, et vous précisera probablement que JAMAIS ils ne vous demanderont de mots de passe ou données confidentielles par email. German Tank Problem De même, si vos identifiants sont numériques et croissants, sans même vouloir vous attaquer, vos concurrents sont capables de voir votre progression : tiens, mon compte test d’hier est le numéro 300, mon compte test d’aujourd’hui est le numéro 400, et l’entreprise prétend avoir des milliers d’inscriptions par jour, et des millions d’utilisateurs au total ? Peu crédible. Open API Laisser trop d’infos, comme vos identifiants ou la liste de vos champs, très classique dans le cas d’une API ouverte à l’extérieur, permet à un attaquant de mieux cibler ses tentatives d’injection. Si je sais qui sont les admins, où est le champ qui donne les droits… CSRF Tout cela nous mène au dernier point, la CSRF, prononcée Sea-Surf, pour Cross-Site Request Forgery : fausse requête de site à site. Si un attaquant sait que votre site a une URL qui fait quelque chose, par exemple vous désinscrire, ou valider un transfert d’argent, ou vous faire voter dans un concours en ligne qui l’intéresse, il peut en profiter pour vous faire cliquer ou vous faire faire une requête du genre, depuis un autre site, par exemple avec un lien “cliquez ici pour voir des photos de chatons”. On se protège rarement de cela pour des requêtes en lecture (GET), mais pour un formulaire qui envoie des informations, Rails va souvent ajouter son CSRF-token, un “jeton unique” avec une clé qui permet de se dire “tiens, l’utilisateur souhaite voter pour le concours, mais pourtant il ne connaît pas la clé que je lui ai donnée, c’est donc qu’il vient probablement d’un endroit que nous n’avions pas prévu”. OWASP TOP 10 Bref, révision rapide du top 10 de l’OWASP : Faussaires, imposteurs et passe-passe 1. injection SQL ?. injection shell 3. XSS (Cross-Site Scripting) 10. redirections non vérifiées Je laisse la porte ouverte 5. Mauvaise configuration 9. Dépendances vulnérables 2. Authentification / gestion des sessions 7. Missing function level access control ?. Oubli des `strong parameters` Je laisse trop d’infos 4. Insecure direct object references 6. Sensitive data exposure Un peu un mix : 8. CSRF - Cross Site Request Forgery vous avez confiance en votre browser mais il est prédictible et je vous ferai cliquer sur un lien Je pense que pour la suite du sujet je vais vous laisser vous documenter auprès de qui de droit, la technique et les sujets pointus ne tiendront pas dans un format audio ni en 5~10mn, et j’espère que vous avez une meilleure idée de la sécurité, ses enjeux, et les endroits où vous pouvez intervenir. À bientôt !…
Bonjour, bienvenue dans l’épisode 13. Dans l’épisode 011. À l’attaque ! on a fait une introduction sur la sécurité : une vision globale pour éviter de se perdre sur la technique, en comparant avec la sécurité de votre habitation. Pour mieux se protéger, il est important de comprendre comment pense l’attaquant, et comment les points techniques de la sécurité se traduiraient dans le monde réel… Disons plutôt le monde physique, par opposition à virtuel ou numérique, parce que vu la place des technologies dans notre vie, le monde numérique est tout à fait réel. Je vais me baser sur douze erreurs classiques listées par le projet OWASP (Open Web Application Security Project), que je classe grossièrement en “usage de documents falsifiés”, “la porte était restée ouverte”, et “j’ai laissé trop d’informations à l’attaquant”. Encore une fois, je ne veux pas vous empêcher de dormir la nuit, mais après avoir acheté et fait installer une porte d’entrée très solide avec des clés compliquées, c’est sûr qu’on se sent bête d’avoir laissé le garage ouvert ou la clé sur la porte. Faux et usage de faux Une énorme partie de ces erreurs vient tout bêtement par “imposture” : un ordre arrive, vous croyez qu’il faut l’exécuter, mais il s’agit en fait d’un mensonge placé là par un attaquant. Le souci c’est que chaque canal de communication sur chaque partie de vos systèmes peut avoir son attaque appropriée. Depuis des siècles, on a aussi plusieurs personnes ou équipes qui vont faire des faux : fausses lettres, fausses signatures, fausse monnaie… Vous faites confiance à l’autorité, à la signature, à un papier qui ressemble à de l’argent, et vous êtes coincés. Injection Encore plus facile que de fabriquer un faux message royal, imaginons que le contenu du message soit : “faites ce que dira mon messager”. Vous prenez la place du messager, et vous avez gagné. Et encore plus facile que tout cela : si le message du roi a une zone blanche dans laquelle vous pouvez écrire tout ce que vous voulez, le message, la signature, le messager ont beau être connus et certifiés, vous ajoutez “et vous donnerez une forte somme d’argent à untel”, et tout tombe à l’eau. De même, vous faites tourner du code sur toute une infrastructure (machine, OS, BDD…) et vous avez besoin que le code leur envoie des ordres. Si ces ordres viennent du monde extérieur, vous DEVEZ vous en méfier. Le plus connu c’est l’injection SQL. On va écrire une requête très simple, SELECT * FROM users where email = "#{params[:email]}" AND active = true et quel que soit votre langage vous aurez une méthode pour dire “dans la chaîne de texte qui représente ma requête, ajoute ici la chaîne de texte qui vient du champ de recherche, du champ login etc. Si jamais j’entre une recherche avec du code SQL dedans, je peux par exemple faire croire que la chaîne email est finie avec un caractère simple quote ou double quote (qui ressemblent à des ‘apostrophes’ ou “guillemets” respectivement), que la requête est finie avec un point virgule, puis je continue à écrire le code SQL que je veux pour détruire ou récupérer vos données (un mot de passe admin par exemple, ou modifier le montant de ma facture), et enfin je termine en mettant le reste en commentaire pour éviter toute erreur de syntaxe. Ça y est, votre base de données fait confiance à la chaîne de caractères ainsi envoyée, mais elle contient de quoi vous attaquer de l’intérieur. En Ruby on Rails, comme dans la plupart des frameworks Web ou bibliothèques pour accéder à la base de données, on trouvera des mécanismes qui évitent cela en interdisant ou en “échappant” les caractères : tout guillemet contenu dans le paramètre email sera traduit afin que la base de données comprenne que ce n’est pas la fin de la chaîne, mais un guillemet dans la recherche : Personne.active.where(email: params[:email]) Autres injections Dès que vous parlez à quelqu’un qui vous fait confiance, c’est le même problème. Il existe l’injection shell, qui envoie des commandes à votre ligne de commande, et via laquelle on peut attaquer le système d’exploitation du serveur. Il y a aussi les XSS (Cross-Site Scripting) : le but pour l’attaquant est d’écrire du Javascript qui va tourner dans la même page que votre site. Par exemple, si dans mon champ email de tout à l’heure j’écris du JS et que dans une page vous affichez mon JS sans “échapper” les caractères, il a gagné. Gagné ? Eh oui, il peut voir plein de choses, comme vos cookies, et envoyer tout ce qu’il trouve sur un autre site. Par exemple, récupérer la session sur votre banque en ligne et émettre des virements. Enfin, en JS, en affichage ou autres, si j’arrive à vous faire cliquer sur un lien qui vous sort du site en question, je peux faire du phishing (hameçonnage en français) : au lieu d’aller sur le site de la banque, vous allez sur un site qui appartient à l’attaquant, aux mêmes couleurs, qui vous fait croire que vous êtes déconnecté par exemple. Vous rentrez alors votre login et mot de passe… sur le site de l’attaquant. Là ce n’est plus du tout une histoire de sécurité sur VOTRE site, mais de filoutage classique où l’on vous met de la poudre aux yeux pour avoir des informations confidentielles. Toutefois, vous pouvez au moins de votre côté et pour vos utilisateurs, éviter le XSS et pour les redirections intempestives, a minima les éviter, interdire, ou les rendre plus difficiles ou plus évidentes : si je dois me reconnecter à ma banque juste après avoir vu “vous allez sortir de votre espace sécurisé”, je suis plus méfiant. alert(‘pwn3d’) Et c’est pour cela que vous voyez des démos de sécurité, où il y a écrit alert("bad security") et un popup navigateur avec le message “bad security”, bien sûr ça ne fait rien de grave. Ce que la personne vient de vous prouvez, c’est que vous êtes vulnérables à ce XSS et à ces redirections de votre site vers un site vérolé. Autres attaques L’épisode est assez long, je vais garder huit autres failles et vulnérabilités pour la suite. Je ne vais pas les dicter mais vous pourrez les trouver, ainsi que des liens vers le site OWASP et la présentation à ParisRB de Dorian Lupu sur la page de l’article zenm4.net/013/ - à bientôt ! http://slides.com/kundigo/if-you-are-hacked-via-owasp-top-10-you-re-not-allowed-to-call-it-advanced-or-sophisticated#/5…
Bonjour, bienvenue dans l’épisode 12 sur Git. Beaucoup de cours pour apprendre à coder se basent sur Git, et c’est très bien de viser tout de suite une bonne pratique qui ne va jamais cesser d’être utile. En plus, un code bien versionné c’est le droit de faire des erreurs et revenir en arrière, ce qui est parfait pour se rassurer quand on tente des choses nouvelles. Mais cela bloque aussi les débutants : je voulais “juste” apprendre à coder, et voilà qu’on me gave d’outils annexes sans vraiment me dire pourquoi ils sont là, si on peut s’en passer au début, ou si on peut apprendre juste quelques parties et se lancer, ou qu’on doit tout savoir dès le début. Du coup le but ici n’est pas de vous faire une liste des commandes (j’ai essayé avec l’épisode sur les itérateurs, c’est beaucoup trop long et pas forcément adapté en podcast, et en plus il y a déjà pléthore de sites et docs très bien faits) mais encore une fois de donner une vue d’ensemble pour dédramatiser le sujet. La tradition orale J’aimerais rapprocher l’écriture de code (du texte à la base), avec quelque chose que l’humanité fait depuis très longtemps : raconter des histoires. Dans toutes les cultures, mythes, légendes, contes se transmettent par tradition orale : les griots, les druides, les aedes grecs… et un jour tout cela se cristallise dans un ouvrage : l’épopée de Gilgamesh ou l’Iliade et l’Odyssée, etc. Comme dans le logiciel ou le business, l’écriture dans une version “canonique” n’empêche pas les reprises, redécouvertes ou réinventions : Molière a repris énormément d’idées de ses fables chez Esope, pourtant il a écrit quelque chose d’original en l’adaptant à sa langue et à son époque. Pourquoi versionner ? On souhaite avoir plusieurs versions d’un logiciel qu’on écrit : soit parce qu’on travaille à plusieurs, soit pour faire une expérience par ci, une tentative par là, sans que cela ne bloque tout le monde. Vous avez tenté quelque chose de trop courageux toute la journée de mardi ? Rien ne marche le soir ? Pas de souci : on revient à la version de lundi. Quand on commence un long chantier sur son code, on ne veut pas le mettre en prod tant qu’il n’est pas fini, pourtant il faut bien que le logiciel avance : une urgence, un patch de sécurité, et on doit soit reprendre la version d’avant votre chantier, soit mettre en prod quelque chose qui n’est pas maîtrisé. Une façon simple de faire ça était de tout copier-coller dans des dossiers, avec des noms plus ou moins explicites (v1, v2, backup, test…) mais plus on va mener de chantiers en parallèle plus ça va être difficile, déjà de tracer, mais ensuite de remettre ensemble à la fin quand le résultat est satisfaisant et “mérite” de rentrer dans le produit final. Les conflits Bien entendu, ça arrive tout le temps. Parfois, pour avancer, on doit se baser sur une hypothèse différente : pour le métier, une découverte qui n’était pas dans le plan de base, une contrainte légale ou une opportunité business ; pour les développeurs, des contraintes ou opportunités techniques. Votre code et votre base de données peuvent avoir des changements majeurs qui mettent une partie du système KO. Quand ça arrive, votre code est en conflit avec celui du voisin. Par exemple, dans l’histoire du barde voisin, le personnage principal meurt, c’est bien plus dramatique, mais vous en aviez besoin dans la scène finale que vous aviez enjolivée : l’un des deux aspects va devoir changer, quitte à faire deux ouvrages. Quand ça n’arrive pas ou très rarement… soit votre projet ne change plus (pas toujours bon signe) soit vous aviez une excellente conception ou architecture logicielle (souvent le genre de choses dont on se rend compte avec beaucoup d’expérience, ou a posteriori). Gestion de version, distribuée Typiquement les versions des contes de Grimm finissent mal et les Disney finissent bien : je ne dis pas que l’un ou l’autre a raison, ils ont chacun leur public, leur époque, leur succès, et sont tous les deux dépositaires d’une version qui est stable et se suffit à elle-même. Chez les développeurs, ce serait un fork du logiciel, et chacun vivra sa vie complètement séparée de l’autre. On ne remet plus trop de Grimm dans les Disney, l’inverse à la rigueur ? Ça peut être un changement de version majeure de la 1.0 à la 2.0, ou deux branches de la même histoire qui coexistent. Mais des scénaristes qui travaillent en parallèle ? Tout simplement sont deux dépôts du même code, qui ont vocation à fusionner un jour en reprenant le meilleur de chaque. Régulièrement, ils s’envoient ou ils vont chercher les modifications de l’autre. Git est prévu pour ça, pour s’échanger les différences pour que chacun puisse profiter des améliorations de l’autre, à condition d’être prêt à résoudre les conflits. Dépôt, branche, versions, table de travail Du coup, Git propose énormément de commandes en fonction des subtilités choisies : cloner, envoyer, récupérer les dépôts ; expérimenter et naviguer entre plusieurs branches des possibles ; voir l’état de votre table de travail, jeter les brouillons ou intégrer les nouveaux travaux à telle ou telle branche ; fusionner les modifications. Enfin, parfois, vous voulez présenter non seulement votre travail à quelqu’un, mais qu’il ne voie pas les annotations et modifications successives : on peut alors réécrire l’histoire des commits. Là encore, ça n’est pas une opération quotidienne ou anodine : maîtrisez d’abord la base et vous saurez par la suite si vous voulez vraiment le faire, et armé de la pratique git que vous aurez eu entretemps, la méthode vous semblera plus claire. Le distribué centralisé C’est compliqué d’imaginer que chacun a sa version. De toutes façon, un seul logiciel finira en production dans votre entreprise. Souvent, on va se dire qu’un des dépôts a autorité sur les autres, disons celui de l’entreprise ou du projet et pas celui des contributeurs. Au lieu de vous synchroniser avec chacun de vos collègues, vous le ferez via celui-ci. Git est si populaire que de nombreux outils de développement se basent dessus : l’intégration continue par exemple, permet de dire “quand une nouvelle version est envoyée à tel endroit, lance des tests, et s’ils réussissent, déploie le tout en production”. Confort maximum, gain de temps : bel exemple d’automatisation. Il existe aussi de nombreuses plateformes, publiques ou privées. GitHub étant devenu de fait un hébergeur majeur de projets Open Source, il y a de fortes chances que toutes les briques dont votre projet a besoin pour fonctionner soient sur GitHub. Si vous avez un outil de gestion de dépendances (npm pour Node, gem pour Ruby par exemple), il y a de fortes chances pour qu’il aille tout chercher sur GitHub. Du coup, bien que Git soit conçu pour être un système distribué, vous venez de baser un système qui se centralise sur GitHub, et en cas de problème chez eux, votre projet est affecté aussi.…
Récemment à ParisRB, nous avons eu des présentations sur la sécurité. Dorian et Jean-Baptiste se sont gentiment proposer de continuer avec une série régulière. Tout d’abord je rappelle aux curieux que nous réussissons depuis janvier à transmettre les meetups en live sur la chaîne YouTube ParisRB et que nous avons un Slack qui vous permet de réagir durant l’événement et poser des questions. La sécurité c’est bien joli mais il est difficile de comprendre pourquoi un code javascript alert('pwn3d!') est une faille. Plus que jamais je ne suis pas un expert mais je vise à vulgariser et démystifier ces sujets : je ne suis pas un dentiste, mais je peux quand même vous expliquer comment vous brosser les dents. Acceptez les difficultés Car au niveau de la plupart des développeurs, c’est bien de ça qu’il s’agit : une forme d’hygiène. Avec les bonnes habitudes, et dans une équipe un peu complète, on évite un maximum de problèmes. Dans les cas rares où vous avez des besoins très précis, vous serez au courant avant et vous prendrez vos dispositions. Le monde de la sécurité peut rebuter pour plusieurs aspects. Tout d’abord ça fait peur, et plus que tout autre domaine on a peur de ne jamais être à la hauteur : le sujet est vaste, plein de jargon et de technicité, et comme dans le jeu des gendarmes et des voleurs c’est un jeu d’attaques et contre-attaques, et on a toujours l’impression d’avoir une étape de retard. Ça fait aussi de vous quelqu’un d’extrêmement parano, jusque dans la vraie vie. Et pire, comme “la sécurité d’une chaîne est celle de son maillon le plus faible”, et personne ne veut être le maillon faible. L’approche par le risque Là encore j’ai a priori de quoi faire un épisode complet sur chaque type de faille, mais on va commencer par des généralités. Parlons de la sécurité de votre habitation, et désolé si ça vous empêche de dormir ce soir :) Le premier postulat c’est que tout change et rien n’est certain : “le risque zéro n’existe pas”. On va protéger sa maison contre les cambrioleurs, mais pas contre une attaque au camion bélier ou au lance-roquettes. Les banques et data-centers, eux, peuvent et devraient s’en inquiéter. L’idée est dissuader l’attaquant avant même qu’il tente de rentrer chez vous : trop long, trop compliqué, pour des gains incertains. Analyse de comportements Des études disent qu’une bonne porte et de bonnes fenêtres font fuir la majorité des cambrioleurs : plus le temps passe et plus ils font de bruit, plus ils ont de chances que vous reveniez, ou qu’un passant les remarque. Avec cette approche, une des clés de votre système, ce n’est pas d’être totalement imperméable, mais que toute attaque soit aussi difficile, et longue, et bruyante que possible. C’est comme avoir des caméras de surveillance : ça n’empêche pas le crime d’avoir lieu, mais ça augmente les chances de détection et de retrouver des traces pour punir le coupable. Aucune protection, mais de la dissuasion. Dans vos systèmes, en tant que développeur, vous êtes de toutes façons déjà parti pour tout tracer et analyser : pour votre reporting, votre chef, votre curiosité, votre business, avoir des idées de ce qui est important et ce qui l’est moins… Il suffit de rajouter l’aspect sécurité à cette question : qu’est-ce qui consitue un comportement normal, et qu’est-ce qui sort de la norme ? Mettez en place un système d’analyse et d’alerte, vous ne serez jamais déçus d’être prévenu d’une situation anormale : appli cassée, serveur KO, réseau coupé… et intrusion en cours. Et tant pis pour le voisin ! On dit parfois que si vous êtes dans un groupe poursuivi par un lion affamé, il n’y a pas besoin de courir plus vite que le lion, mais plus vite que la personne la plus lente du groupe. C’est pareil : si votre porte ou votre site ne sont pas ultra sécurisés, on souhaite au moins qu’ils soient plus difficiles à pirater que celui du voisin. On suppose les attaquants ne sont pas totalement idiots et se reporteront sur la cible la plus facile. Le coût total Tout cela coûte de l’argent à mettre en place et à regarder en permanence. Il y a de nouveau un équilibre à trouver entre la prévention, la réaction (qu’est-ce que ça vous coûte de couper puis de réparer), et ce qu’une attaque vous aura coûté entretemps en business perdu. Dans la vraie vie on peut tout à fait mettre des assurances, vous en avez une sur votre logement, et sur votre business, que vous négociez en fonction de votre budget, des risques et des coûts. Bon, ça remplit déjà un épisode, on verra plus tard pour l’explication des méthodes elles-mêmes comme les injections. J’imagine que vous avez de quoi réfléchir, et que vous ne serez pas surpris d’apprendre que la plupart des fans de sécurité que je connais sont aussi très intéressés par la sécurité physique des locaux, et notamment les serrures. Dormez bien !…
Épisode 10 sur des traitements classiques sur les listes. En Ruby on appelle ça Enumerable, mais heureusement les mots sont partagés dans la plupart des bibliothèques et langages. Traitons d’abord quelques oublis classiques de débutants (et d’étourderies d’experts aussi, ne vous sentez pas ridicules quand ça vous arrive, c’est le jeu) sur des listes et “boucles”. each et les itérations Imaginez-vous dans un emploi qui traite des dossiers un par un. Votre méthode de travail est de prendre des fiches, et les traiter. Partons sur un tableau nommé a et contenant les chiffres de 1 à 5. a = [1,2,3,4,5] # ou (1..5).to_a Traiter, ça peut vouloir dire prendre une feuille, noter quelque chose ailleurs, et les remettre exactement à leur place. C’est ce que fait each : le code b = a.each{|x| x * 2} met effectivement un tableau dans b , mais [1,2,3,4,5] et non pas [2,4,6,8,10] . map et les pièges sémantiques Traiter, ça peut vouloir dire prendre un dossier a , ouvrir un nouveau dossier vierge, et mettre dans ce nouveau dossier le résultat de votre travail. Le piège, c’est qu’après vous pouvez tout aussi bien mettre une nouvelle étiquette b sur ce nouveau dossier, ou voler l’étiquette du dossier a pour la coller sur ce nouveau dossier. Pire encore, vous pouvez travailler soit avec des photocopies de chacune des feuilles de a , soit modifier physiquement chacune des feuilles : vous avez mis du surligneur, déchiré un coupon, écrit sur la fiche ou mis un tampon ? Impossible de retrouver la feuille de départ dans l’état de départ ! En terme de code, ces trois options donneraient cela : b = a.map {|x| x * 2} , qui renvoie bien [2,4,6,8,10] et le stocke dans b , sans aucunement déranger le tableau a . a = a.map {|x| x * 2} a travaillé sur une copie de a (sans la nommer) puis finit par lui recoller l’étiquette a dessus. On ne parle pas des informations de départ : en ayant redonné l’étiquette au nouveau dossier, on n’a pas vraiment prévu de moyen d’aller chercher les anciennes informations. ['bonjour', 'au revoir'].map{|x| x.upcase!} a vraiment modifié le contenu, chacune des chaînes de caractères du tableau. On note d’ailleurs que par convention, les Rubyistes mettront un point d’exclamation à la fin des noms de méthodes “destructrices”, c’est à dire qui changent le contenu de départ. str = "Bonjour" # => "Bonjour" # valeur de départ str.upcase # => "BONJOUR" # ça n'est pas la même donnée str # => "Bonjour" # on n'a pas touché à str str.upcase! # => "BONJOUR" # on a mis en majuscule et on altère str str # => "BONJOUR" # str a été modifiée Traitement “en place” Pareillement pour les dossiers, si je veux trier mon dossier a je n’ai pas forcément envie de préparer un nouveau dossier pour conserver les valeurs triées, et jouer ensuite avec les étiquettes. Je peux vouloir simplement dire que tout se fait dans le tableau a et que je n’ai pas besoin de faire de copies. Ça s’appelle un traitement “in-place” et la plupart des rubyistes vont le faire avec des méthodes finissant par des points d’exclamation. On n’en voit pas dans Enumerable , mais on voit beaucoup de paires dans la classe Array : sort et sort! , rotate , reverse , uniq … D’une liste à un seul résultat Je pense qu’il faudra un autre épisode pour toutes ces super fonctions. En attendant, il y a une classe entière de besoins à voir. Imaginez que votre travail c’est de prendre une liste de fiches, et de ressortir un seul nombre : la somme des paiements, ou le nombre de mauvais payeurs par exemple. Cette méthode a trois noms. Ruby l’appelle reduce : on “réduit” les N fiches à 1 résultat. Ruby l’appelle aussi inject : on “injecte” la valeur zéro, puis on va regarder chaque fiche pour ajouter la somme d’argent de LA fiche au total “temporaire” et ainsi de suite. Par exemple, 50 + 100 + 25 + 20 + 5 : vous avez probablement fait l’addition étape par étape. [50, 100, 25, 20, 5].inject(0) {|somme, obj| somme + obj} [100, 25, 20, 5].inject(50) {|somme, obj| somme + obj} [25, 20, 5].inject(150) {|somme, obj| somme + obj} [20, 5].inject(175) {|somme, obj| somme + obj} [5].inject(195) {|somme, obj| somme + obj} # => 200 Le troisième nom n’est pas très utilisé en Ruby, mais dans le reste des langages : fold . Il applique le résultat étape par étape, comme on vient de voir. J’aime bien l’image que ce mot donne : si vous avez déjà vu de vieilles imprimantes avec des piles de papier qui se pliaient et dépliaient, c’est vraiment pour moi l’acte de replier une très longue liste de pages en un accordéon qui prend moins de place et affiche en bas le résultat voulu. That’s all folks! Et bien voilà, c’est déjà assez long pour cette fois ! Mon but n’est pas franchement de vous lire la doc Ruby à voix haute, donc allez lire Enumerable , Array , Hash , et aussi String , les opérations sur les chaînes de caractères, pour faire bonne mesure, mais peut-être que je ferai un épisode “rappel” sur quelques-unes de ces méthodes un de ces jours.…
Bonjour, bienvenue dans cet épisode 9 sur l’indexation dans les bases de données. C’était l’étape logique juste après l’épisode 8 sur la manière de ranger et rechercher des données. On parlait dans l’épisode précédent de ranger des livres, et d’aller les chercher. Les seuls outils pour cela étaient un ensemble d’étagères et quelques règles non écrites. J’aime bien chercher les règles non écrites : c’est ce qui permet de tout clarifier, et parfois de tout remettre en cause pour créer de nouvelles opportunités. 1) On voulait donner un ordre, mais lequel ? On supposait que la personne qui range ses livres ne se pose pas la question, ou plutôt qu’elle a une réponse toute faite : probablement de haut en bas du meuble, de gauche à droite par étagère. Si c’est vous qui savez, qui rangez et qui cherchez, ça marche, mais bien sûr il faut prévenir les autres personnes qui pourraient vouloir le faire aussi, sinon ils ne trouvent pas le livre (dommage) voire pire : ils “cassent” votre rangement avec des livres en désordre, avec le coût en performance qu’on a vu. 2) On se basait sur le fait que la seule information est la tranche du livre, avec titre et auteur. Mais on n’est pas obligés. On peut faire un papier qu’on scotche à côté de notre étagère pour expliquer le système de rangement. Enrichir la structure Et là encore, les bibliothèques existent depuis longtemps et ont tenté plein de bonnes idées, pour finir par s’accorder sur un standard. Les allées sont rangées par thèmes, qui ont des sous-catégories, on colle à chaque livre une référence unique… et on souhaite toutefois que ce soit facile à naviguer quel que soit la manière dont nos lecteurs veulent aborder le problème. On ne peut ranger nos livres physiquement que d’une façon, alors on a recours à une “structure” encore plus complexe mais plus astucieuse : ajouter en plus des étagères de livres des fiches ou dossiers, permettant de retrouver référence et section en fonction de votre question. Un catalogue va lister tous les livres par ordre alphabétique du nom des auteurs. Quand un livre a trois auteurs, il sera présent trois fois dans ce catalogue et ce n’est pas grave parce que ces trois lignes mèneront vers la même référence, et donc un seul exemplaire physique du livre. Sur les tonnes de livres et les millions de pages cumulées des ouvrages, vous venez d’ajouter trois lignes, même pas une feuille A4, pour simplifier la vie de tous vos lecteurs. On a fait une structure plus complexe mais plus puissante. Et tant qu’on y est, on va faire un catalogue par titre, un par éditeur, un par date, et des entrées par sujets pour pouvoir répondre aux lecteurs qui cherchent des livres à la croisée des sujets, comme histoire et religion, science et bande dessinée, etc. Indexation Ces catalogues papier ont un nom : maintenant presque tout est informatisé, mais avant on appelait ça des index. Et c’est tellement utile que de nombreux livres de référence ont aussi un ou plusieurs index permettant de retrouver le contenu dans le livre. Index est un mot que vous avez peut-être déjà entendu au sujet des bases de données, j’y consacrerai peut-être un épisode mais a priori vous avez déjà compris comment ça marche, et surtout vous venez de comprendre pourquoi un index est souvent très bien (pratique pour la recherche), mais qu’il a toujours un coût (écrire et mettre le catalogue à jour), et que parfois on choisit de ne pas payer ce coût car ça n’a pas assez d’utilité, par exemple, de faire un catalogue de livres en fonction des prénoms des personnages principaux et secondaires. Un mot sur la suite On a balayé la plupart des catégories d’épisodes que je voulais faire : un concept très abstrait mais utile ( 002. le cache ), un sujet simple mais plein de pièges à démystifier ( 004. la priorité des règles CSS ), un sujet business ( 005. achats IT B2B ), de la philosophie ( 006. le Vide, l’Unité et l’Infini ), et quelques pièges ou astuces dans Ruby on Rails ( 003. les requêtes N+1 et 007. les associations ). Avec 001. listes chaînées et 008. structures de données et algos de recherche je vise à dédramatiser un sujet souvent inquiétant dans les premières années d’école d’informatique ou d’apprentissage en solo dans les livres ou sur Internet. Dans la vraie vie vous utiliserez rarement les listes chaînées mais plutôt une bibliothèque ou les constructions de votre langage de programmation. Bref c’est bon pour la culture, et pour donner des idées, mais je trouve très dommage qu’il y ait des barrières à l’entrée alors qu’on pourrait tout de suite commencer à apprendre sur des projets plus amusants. Pour la suite, je vais essayer de tourner sur ce genre de sujets, je suis preneur de vos retours sur twitter . Merci et à bientôt !…
Bonjour, bienvenue dans cet épisode 8 sur les algorithmes de recherche et de tri de données, inséparable de cet autre sujet : les structures de données. Pour moi, une grande partie du travail de codeur (mais pas que de codeurs), surtout débutant (mais pas que), c’est de rentrer des informations, puis chercher des informations. Il y a beaucoup à dire, j’ai écrit de quoi faire deux épisodes, il y en aura sûrement un troisième dans les mêmes lignes plus tard. Ranger et chercher Les deux sont très liés : jeter tous vos livres n’importe où est une méthode de rangement incroyablement rapide, mais la recherche est incroyablement inefficace. Ranger tous vos livres par titre demande du travail, mais revenir chercher un livre par la suite est très rapide, si on se rappelle du titre bien sûr. Autre avantage : si vous n’avez pas le livre, vous voyez qu’il manque là où l’ordre alphabétique l’aurait placé : inutile de le chercher ailleurs, vous savez que vous ne le possédez pas ou l’avez prêté en ce moment. L’alternative, sans rangement, aurait été de regarder chacun de vos livres, et de vous rendre compte tout à la fin que vous ne l’avez pas. C’est très inefficace et frustrant. C’est pour cela que chacune des méthodes n’est pas objectivement meilleure ou moins bonne, mais les papiers scientifiques sur les structures de données ou algos de tri vont chercher à les évaluer en terme de meilleur cas, pire cas, et cas moyen. Explorer le problème Un léger problème toutefois, une série de plusieurs tomes a rarement des titres en ordre alphabétique, et vous devrez donc éparpiller la série dans votre bibliothèque. Nouveau problème, nouvelle solution. On tente un truc un peu plus malin : trier par nom d’auteur. C’est un avantage intéressant dont se servent les librairies et les bibliothèques : ranger par auteur permet souvent d’avoir des livres côte à côte qui soient probablement intéressants pour l’acheteur ou le lecteur, ne serait-ce que par thème proche ou pour ranger une série ensemble. Chaque auteur écrit plusieurs livres, enfin on l’espère pour eux. Il faut donc un autre critère déterminant pour classer entre eux les livres de l’auteur : alphabétique ou date casserait là aussi des séries (pour les auteurs qui écrivent plusieurs séries en parallèle), à vous de voir. Au pire, on vous force à reparcourir la section des livres d’un auteur du début à la fin pour savoir si le magasin possède bien tel ou tel exemplaire. On a perdu le côté immédiat et infaillible de l’ordre alphabétique pur, mais on a gagné quand même puisqu’on a restreint cette phase pénible à la section d’un auteur. Sur les milliers d’ouvrages de la librairie, vous y gagnez : imaginez la longueur de la section de livres qui commencent par “Histoire de/des/de la” ou “Méthode de/des/pour” par exemple. Eh oui : la nature de vos données va donc aussi influer sur le choix de la structure de données à choisir ! Attention toutefois : il faudra trouver une astuce quand il y a plusieurs auteurs… La structure et le besoin On vient de faire un arbitrage entre la complexité de rangement à chaque fois qu’on ajoute ou remet un livre dans les étagères, contre un énorme avantage à la recherche. Si votre problème est rarement d’ajouter ou ranger des éléments, et plus souvent de rechercher, c’est un coût qu’il est intéressant de payer. Mais quand vous faites des logs dans votre application, vous listez tout ce qui se passe pour, peut-être, y chercher des informations un jour. On peut alors légitimement choisir l’arbitrage inverse. Par exemple, les journaux sont un produit radicalement différent d’un livre : ils contiennent des informations variées d’auteurs variés, et une bonne partie de ce qu’ils contiennent n’est plus aussi intéressant au bout d’une semaine, un mois, deux ans… Le rangement de journaux par date semble être le plus sensé, et empiler vos journaux les uns au-dessus des autres une méthode tout à fait acceptable. Conclusion Bref, ranger et rechercher : l’un impose des contraintes à l’autre, et vice-versa. Même chose pour la paire structure de données et traitements : vous rendrez certaines choses possibles ou impossibles, tout en en rendant d’autres plus simples ou plus compliquées. C’est pour cela qu’en général aucun code ou aucun algo n’est mieux qu’un autre, ils sont simplement plus ou moins adaptés, et la clé est de connaître à la fois la nature des données, les opérations que l’on veut faire le plus souvent, le moins souvent, et des ordres de grandeur pour chaque. Pourquoi cet épisode ? C’est un sujet beaucoup enseigné en écoles et dans les livres de programmation, on a du mal à voir le but, et ça en bloque plus d’un. Heureusement, il y a des chances que vous déléguiez tout ce travail à la base de données, qui fait cela très bien. Pas d’inquiétude. Mais pour les rares fois où c’est votre job de choisir la base de données la plus adaptée, et pour les cas très fréquents où vous seriez tentés d’écrire des lignes de code très simples mais qui refont en moins bien le travail que la base de données aurait pu faire, ça me semble important voire nécessaire de comprendre ce qu’il y a en dessous.…
Bonjour, voici l’épisode 7, sur les associations dans Rails. Il fait suite à l’épisode 6, où je vous recommande de toujours considérer la cardinalité de ce dont vous parlez : 0, 1 ou N. En pratique c’est aussi ce que vous trouverez dans un diagramme UML ou dans vos bases de données : associations 1 à 0 ou 1, 1 à 1, 1 à N et N à N. Plus qu’un épisode de métaphore, c’est un épisode qui sert de “pont” entre trois domaines : UML, SQL relationnel, et ActiveRecord qui est l’ORM de Ruby on Rails. Là encore, il y a une introduction à Rails et ActiveRecord dans l’épisode 3 sur les requêtes N+1 , que je vous recommande si vous êtes perdus. Le cas de l’association L’ORM, c’est la correspondance entre des objets Ruby et des données dans une base de données. On fait une correspondance entre une table et une classe, un champ dans une table et une propriété de l’objet, et un enregistrements de la table avec une instance d’objet. L’enjeu de la modélisation objet est de représenter un modèle pratique et utilisable de la réalité (à défaut d’être exact), et une des méthodes les plus connues (je ne dis pas les seules ni que la norme précise est respectée) est le diagramme de classes de la norme UML. Quant aux bases de données relationnelles, elles sont souvent représentées par quelque chose approchant les diagrammes entité-relations, les MCD de Merise ou plus simplement… les schémas de bases de données. Dans Ruby on Rails également, on a la possibilité de décrire des associations entre objets. Note sur l’anglais Je parlerai de code en anglais avec un énorme accent français, parce que ça fait une différence entre le code et le commentaire ; pour retrouver les mêmes mots dans mes exemples que dans la documentation ou sur StackOverflow, et parce que le code Ruby et Rails est presque aussi facile à lire que des phrases anglaises. On peut débattre de “faut-il coder en français ou en anglais”, mais mon but n’est pas de vous forcer à faire quoi que ce soit : dans votre équipe, dans votre projet, trouvez votre propre équilibre. Has Many L’association 1-N, que Rails nomme Has Many. Par exemple, un panier a beaucoup d’articles : Cart Has Many Articles . À l’inverse, un article ne peut être que dans un seul panier. C’est l’association Belongs To : Articles Belongs To Cart . En base de données, ActiveRecord s’attend à trouver la colonne cart_id dans la table articles , et un id dans la table carts . Vous pouvez sortir de ces conventions, mais lisez bien la doc d’ActiveRecord pour apprendre à le faire proprement. ActiveRecord vous donnera plein de méthodes utiles : cart.articles pour avoir un tableau des articles du panier, cart.articles= pour enregistrer ces articles dans le panier, cart.article_ids pour les identifiants. De l’autre côté, article.cart , article.cart= , article.cart_id . Note sur l’enregistrement Attention, il est important de noter que tout ce que vous faites ici c’est travailler sur des objets Ruby. Rien n’est enregistré. Il y a trois étapes : aller chercher les données en base et en faire des objets avec un where, find, ou une méthode d’accès comme @cart.goods travailler sur lesdits objets avec tous les traitements Ruby et Rails que vous voulez enregistrer tout cela dans la base de données si vous avez fait des changements, il faut les sauvegarder Si vous modifiez des objets Ruby, tant que vous n’avez pas sauvé vos objets Ruby en base, seul le bout de code qui est allé les chercher (et les bouts de code auxquels il les a donnés) sont au courant des modifications. Si quelqu’un d’autre va chercher les infos en base, il ne voit pas les changements. HABTM Il y a aussi l’association N-N, que Rails nomme Has And Belongs To Many, HABTM pour faire court. Par exemple, une personne peut posséder plusieurs logements. Vous pouvez n’être propriétaire de rien du tout ( [] ), d’un seul ( [:home] ), et certains peuvent en avoir énormément ( [:home, :beach_house, :ski_house, :fishing_house] ). Mais si votre client souhaite pouvoir noter qu’une maison a plusieurs propriétaires, et non un seul, 1-N (Has Many) ne suffit pas. Il faut passer à N-N (HABTM). La table Owner ne contient pas d’ID de House (sur un formulaire papier, on écrirait maison 1, maison 2, maison 3…. impossible de savoir combien on devrait en prévoir, et que d’espace gaspillé !), pas plus que la table House ne contient d’ID de Owner. Mais il y aura en BDD une table dite de jointure, parce qu’elle fait le lien entre les données des deux tables. Rails l’appellera Houses_Owners , et cette table contiendra une clé house_id et une clé owner_id contenant les identifiants respectifs de House et Owner. Il y aura ensuite autant d’enregistrement que de “liens de possession” entre une maison et un propriétaire. Les méthodes utiles seront les mêmes, owner.houses , owner.houses= , owner.house_ids et réciproquement house.owners , house.owners= et house.owner_ids . Has-Many Through Mais on sait seulement qu’il y a un lien ! On n’a pas d’information sur la nature ou les conditions de ce lien. Si vous voulez que cette association porte des informations, l’idée de la jointure est bonne. Poussons-la plus loin. Faites un objet qui relie les deux et dans lequel vous rangez les informations de ladite relation, puis des Has-Many vers cet objet. Par exemple pour une location de voiture Person Has Many Rentals et Car Has Many Rentals . Ainsi chaque Rental sait retrouver la bonne voiture, son locataire, et tout ce que vous voudriez ajouter, comme : les dates et heures de début et fin de location, le prix appliqué, des infos variées etc. Rails proposera un dernier confort dans ce cas, les Has Many Through, ici Person Has Many Cars Through Rentals , qui veut dire “on peut retrouver toutes les voitures d’un client, à condition d’aller les chercher à travers son historique de locations”, et vous pourrez alors avoir les deux méthodes utiles person.cars et person.car_ids à disposition. Je ne pourrais pas vous donner de person.cars= car il faudrait alors renseigner tous les objets Rental entre deux. Has-One Enfin, je vous mets en garde contre les associations 1-1, qui sont toujours techniquement possibles, mais qui sont pour moi assez rares. En tout cas, c’est signe qu’il y a une question à poser : on veut dire “un chien a un maître”, Dog Has One Master … mais en réalité Dog Belongs To Master , car un maître peut avoir plusieurs chiens (là encore, 0, 1 ou N chiens) mais un chien ne peut pas avoir plusieurs maîtres. Enfin, c’est possible dans la vraie vie et mais si c’était le cas, vous n’auriez pas tenté d’écrire “un chien A UN maître”. D’autre part parce que si les informations sont si “couplées” et doivent aller la main dans la main, pourquoi ne pas tout mettre dans la même table ? Si un client peut avoir plusieurs mails, que certaines boîtes mail peuvent être partagées… on ne se pose aucune question, on laisse dans la même table email et nom du client. Mais quand vous avez un souci avec un Has One, je pense qu’en général il y aura une évolution un jour pour le transformer en Has Many : Customer Has One Address deviendra probablement Customer Has Many Addresses PhoneNumber Has One Customer plutôt Customer Has Many PhoneNumbers Si vous êtes toujours coincés, voici mon astuce, demandez-vous : “puis-je avoir l’un sans l’autre ?” Une adresse sans maison a du sens (terrain vide), une adresse avec plusieurs maisons a du sens (appartements), une maison sans adresse n’a pas de sens (on l’a bien construite quelque part), une maison avec plusieurs adresses est possible mais rare (coins de rues). Ainsi, on part sur Address Has One House , ce qui était probablement l’inverse de ce que vous vous attendiez à écrire dans un raisonnement classique. En tout cas, j’avais pris l’exemple au hasard et la conclusion m’a surpris moi-même.…
Bonjour, bienvenue pour l’épisode 6, l’épisode philosophie. Pas de métaphore principale à filer tout le long de l’épisode, parce qu’à chaque fois que je trouvais une formulation, elle semblait aussitôt évidente ou idiote. Mais commençons. Pour moi, il y a trois “quantités” en informatique, que vous trouverez à la fois dans votre code, vos bases de données, et même votre design et vos aspects métier : 0. rien du tout 1. une chose N. une liste d’éléments Quand on parle d’une chose, on doit souvent envisager qu’elle soit présente ou absente. Quand on parle d’une liste, elle peut bien sûr être vide ou contenir un seul élément, plusieurs éléments, voire… une infinité. Questions pièges et découverte du métier À titre personnel et professionnel, ces nuances m’ont beaucoup aidé à communiquer, et parfois soulever des problèmes ou proposer des solutions. Ce sont des recettes et astuces que j’essaie de ne jamais oublier. Quand on vous parle d’une seule chose, demandez s’il y en a aucune ou plusieurs. Imaginez qu’on vous montre un prototype d’interface et qu’on vous dise “et ici on affiche l’adresse du client”. Essayez toujours d’envisager les cas : du client qui n’a pas d’adresse connue (ça vous aidera à gérer les cas des NPAI, des incontactables, des données invalides) du client qui a plusieurs adresses (ça vous aidera à parler des déménagements, des résidences secondaires… et des données en doublon !) Le Code et l’unité Les structures de code de presque tous les langages usuels reflètent cela : les if then else parlent d’un prédicat vrai ou faux, les variables peuvent être vides ou remplies, quand on a un objet dans une variable, on peut aller chercher une propriété ou appeler une méthode sur cet objet, et ça peut marcher ou non. Dans tous ces cas-là, on parle du cas “UN” où il y a une chose au départ, une méthode à appliquer, et une chose à l’arrivée (fut-elle une liste). On commence en général à enseigner cette façon de voir dans les tout premiers paragraphes et cours d’algo ou de code : les variables et les structures de contrôle. Le Code et la Pluralité Juste après, vient l’une des constructions les plus importantes : les listes, les boucles, etc. Dans tous ces cas-là, on parle du cas où “N” éléments au départ, mais à l’arrivée, on peut vouloir plein de choses différentes. Par exemple, sur “N” éléments, voulez-vous : * compter ce nombre d’éléments (et on retrouve les cas intéressants 0, 1 ou N) conserver une liste à l’arrivée, transformée d’une certaine manière : les trier (renvoyer la même liste mais rangée différemment) appliquer à tous les éléments le même traitement (appliquer une remise, une taxe) conserver ou retirer uniquement les éléments selon une certaine règle (publiés ou non par exemple) avoir un seul résultat, comme voir le premier ou dernier élément (selon un certain critère) agréger : faire un traitement de groupe pour ressortir un résultat (une somme par exemple) travailler avec plusieurs listes pour les “additionner”, disons plutôt faire l’union des deux listes ressortir la liste des éléments communs, ou différents de ces listes faire un traitement se basant sur plusieurs listes, par exemple le zip qui prend, comme une fermeture éclair (“zip”) le 1er élément de la liste A et de la liste B pour travailler sur cette paire, puis le 2e de chaque et ainsi de suite… Bien sûr ce dernier cas a autant de variantes que vous voulez, mais à part zip ça commence à devenir très dur d’en parler dans un podcast. Et les structures de données de base de tant de langages sont alors - le tableau (qui associe un élément à un nombre, sa position dans le tableau) - le dictionnaire, souvent appelé Hash (qui associe un élément “clé” à un élément “valeur”) et parfois des structures plus exotiques, qui vont proposer différentes propriétés. Dans mon univers de Rubyiste, je recommande toujours de lire intégralement les pages de documentation de Array , Hash et Enumerable , qui aideront à faire de vous meilleur développeur, capable d’utiliser au bon moment le bon outil de base. Mais chaque langage a les siens. La base de données Je vais passer rapidement sur la base de donnés, qui a aussi ces constructions, et sur chacune de vos requêtes vous allez vous retrouver à prendre le premier, le dernier, trier dans un sens ou l’autre, compter les nombre d’éléments qui sont dans un certain cas, limiter vos recherches pour prendre seulement les 10 ou 100 premiers, proposer une pagination en BDD ou dans votre interface… Expérience utilisateur, ergonomie, métier… Pour recentrer tout cela et ressortir du code, revenons aux questions pièges. On a vu au début de l’épisode qu’elles peuvent lancer une discussion sur le métier et les cas à gérer, donc dessiner le périmètre de votre travail, des évolutions très ou peu probables (je dis peu probable car je ne vous crois presque jamais quand vous me dites “impossible, ça n’arrivera jamais”) et donc d’une possible architecture logicielle. Ça marche aussi sur des écrans ou dessins, et pour l’ergonomie : devant une belle image de votre future appli, dessinée avec un cas moyen ou idéal en tête, il est très utile de poser ce genre de questions. Et si on a plus ou moins d’informations ? Et si on doit caler une liste de plusieurs numéros de téléphone au lieu d’un seul ? Bref, n’hésitez pas à utiliser cette technique à fond, pour l’instant je n’ai perdu que très peu de temps cumulé à envisager des cas tordus, qu’on a très vite identifiés comme “inutiles, à voir plus tard, à voir tout de suite”, ou “critiques”. Expression Pour finir, on ne fait que répéter que le code est une activité humaine et la qualité principale d’un ingénieur, la communication. Dijkstra disait que la qualité principale d’un programmeur est une excellente maîtrise de sa langue natale. “À part un léger goût pour les mathématiques,” disait-il, ce dont personnellement je ne suis même pas sûr. J’ai longtemps été pédant sur la langue française, allant jusqu’à dire qu’un mail avec trop de fautes était éliminatoire. Je n’en suis plus là, même si écrire un français correct est une marque de respect et d’attention, et qu’un mail plein de fautes note un manque de l’un et/ou de l’autre. Prenez vos responsabilités. Ce que je tiens à dire sur le sujet, en revanche, c’est que je reste attentif aux fautes d’accord. Oui, c’est aussi simple que mettre ou oublier des S au pluriel : car si quand vous écrivez, vous ne savez même pas si vous parlez d’un ou de plusieurs objets, comment voulez-vous programmer correctement ? Et même plus fondamental : comment voulez-vous raisonner correctement ? Bref : zéro, Un, ou Plusieurs. Ne perdez jamais cela de vue. Ruby on Rails et les associations Et voilà, c’est tout pour aujourd’hui ! Autant j’étais peu inspiré par la philosophie la dernière fois, autant j’ai écrit aujourd’hui de quoi faire deux épisodes et j’ai dû couper. Alors, prochain épisode : les associations dans Rails.…
Bonjour, bienvenue pour l’épisode 5 et premier épisode business ! Parler business est un peu plus loin de la ligne éditoriale technique de ce podcast, mais 100% dans la ligne des questions que j’ai et auxquelles je réponds très souvent. De plus dans mes communautés Ruby, Rails et Web c’est un sujet clé car tout le monde semble vouloir devenir entrepreneur. Je partais sur une métaphore avec la voiture, mais j’en ai écrit assez pour presque trois épisodes, du coup je vais parler uniquement de l’étape achat aujourd’hui. Alors voici quelques rappels (forcément incomplets mais on pourra étendre la discussion si ça vous intéresse) sur l’achat de logiciels B2B, c’est à dire par des entreprises, et pas du B2C, par des particuliers. Quel véhicule pour quel besoin ? La plupart des voitures suffiront pour un transport de quelques personnes, bagages et meubles. Pourtant on peut acheter des voitures individuelles ou familiales ; on n’a pas les mêmes besoins pour faire des courses ou un déménagement. Là encore, beaucoup de logiciels sont suffisamment adaptables pour aller un peu au-delà de leurs usages de départ : pour nous ce serait l’adaptation d’un logiciel sur étagère, ou d’aller un tout petit peu plus loin que prévu en tenue de charge ou en volumétrie par exemple. Mais parfois on ne peut plus tricher : il faut un camion voire un convoi exceptionnel, ou à l’inverse le poids, la vitesse limite et le prix font que votre camion est l’outil le moins pratique pour ce que vous vouliez faire. Il semble tout à fait normal de choisir un logiciel en fonction du besoin le plus attendu, et les clients dont on se moque facilement qui demandent à “pouvoir tout faire plus tard quand ils voudront” sans rien prévoir n’aurait jamais fait cette erreur d’appréciation en achetant un véhicule. De même il n’y a pas de mal pour le vendeur à chercher à connaître votre budget assez tôt : on craint certes que le vendeur vous propose uniquement des voitures de luxe au lieu d’une berline, mais des heures d’explications à comparer toutes les berlines pour voir au final un budget qui vous condamne au vélo ou au métro, n’est pas très productif. [NOTE : ça a parfois des avantages de se libérer des contraintes, par exemple monétaires : on pourra vous proposer un chauffeur ou de prendre l’avion, ce qu’on se serait interdit avec un budget “normal”, et à l’inverse s’imposer des contraintes, comme éviter de considérer l’avion, peut gagner du temps et… débloquer la créativité !] Pareil ou différent ? Il n’y a pas de honte non plus à choisir dans le haut de gamme ou bas de gamme, et vous verrez qu’au final les raisons de l’achat sont souvent similaires : soit un besoin très étudié, soit… comme tout le monde, un achat impulsif pour impressionner les copains. Oui, ça existe dans le monde du logiciel, mais je ne donnerai pas de noms ;) La leçon plus pragmatique à tirer quand vous faites ce choix : il y a un coût à ne pas faire comme les autres (par exemple choisir l’électrique ou le GPL quand les stations et les expertises sont encore rares), mais il y a aussi un coût à faire comme tout le monde, car vous ne pourrez pas être franchement différent du concurrent si vous avez le même véhicule, alors que vous pourriez jouer sur vos forces si vous aviez un scooter et lui un camion. Quel genre d’achat ? Parlons budget. Sur une voiture, il y a de très nombreuses variables sur lesquelles on s’imagine pouvoir intervenir facilement : payer comptant ou récurrent, c’est le choix du plan de financement ; payer sa voiture en leasing, c’est le SaaS (Software as a Service) sauf qu’à la fin il ne vous appartiendra jamais… … et quelque part votre obligation d’innover et continuer la R&D c’est de s’assurer que régulièrement, vos clients souhaiteront passer aux nouveaux produits qui sont tellement mieux que les anciens. [Attention aux coûts de transition] Achat impulsif ou longue recherche ? Idem, chaque personne ou entreprise peut décider de faire l’achat d’un logiciel A, et fera tout pour, ou au contraire lister ses fonctionnalités souhaitées X, Y et Z et chercher ensuite le produit qui correspondra le mieux à ses attentes. Illusion des métriques ? Là encore, les vendeurs vont faire une compétition à grand renfort de 3, 5, 7 places, V6, V8 et autres options de motorisation, nombre d’options et grand renfort de superlatifs comme “suréquipée”. Au final on vous jette de la poudre aux yeux alors que votre besoin était soit de faire attention à la consommation (quand les chiffres annoncés sont exacts) soit, pour reprendre les mots légendaires du cahier des charges de la 2CV : “transporter 4 passagers et 50kg de patates”. Coûts cachés et transition Ça semble étrange de faire du logiciel neuf ou d’occasion ? C’est pourtant le choix de beaucoup d’équipes pour savoir si elles vont adapter un ancien logiciel ou lancer une refonte, et les arguments sont similaires : “repartir de zéro” (en oubliant qu’on aura plein d’habitudes à réapprendre), “ajouter une rustine” (en oubliant qu’on est parfois au-delà de tout espoir). En prime on oublie les périodes de transition : la période sans voiture si la nouvelle arrive un peu tard, et parfois presque pire la période avec deux voitures (mais toujours un seul parking), les rendez-vous à la préfecture pour la carte grise, les changements d’assurance… Dans le logiciel comme dans la vraie vie, ceux qui l’ont vécu plusieurs fois sont plus prévoyants que ceux qui le vivent pour la première fois, c’est un biais à connaître. Les dangers de la métaphore Mais attention : la métaphore nous permet de comprendre rapidement la situation et se poser de nouvelles questions en considérant plusieurs angles, qui semblent évidents dans l’image et qu’on aurait oublié dans le cas réel. La métaphore a toutefois ses limites, même si elle reste utile pour qu’on puisse se poser la question à chaque fois : est-ce que ma comparaison a toujours du sens ou est-ce que c’est justement le moment de raisonner par opposition. Ici, la plus grande erreur des patrons, RH, managers… est de croire que toutes les voitures sont identiques. Que l’on peut les ranger par marque, modèle, caractéristiques et qu’elles se valent. Pour un bête produit physique, ça marche, et on va pouvoir utiliser un process achat genre achat de gros et négociation pour faire baisser le prix. Pour un métier cognitif et des personnes, ça semble illusoire. Mais on peut rattraper cette erreur : il est impossible de comparer des développeurs et même des humains à des voitures neuves. On arrive chacun avec son historique, on est donc tous (désolé la connotation n’est pas voulue) des voitures d’occasion : on peut et on doit chercher vos forces et faiblesses (vous devriez en parler en entretien). De même, un changement dans l’équipe a forcément des conséquences. Il est de votre devoir de mettre un maximum en place pour minimiser les risques (tests, documentation etc) mais remplacer un membre d’équipe a forcément plus de conséquences que remplacer une pièce ou changer de voiture. Et voilà ! Vous voilà un peu mieux armé pour comprendre les achats de logiciel B2B. Je garde un prochain épisode avec la même métaphore, ou comme disait @Phairupegiont sur Twitter, la méta-métaphore, pour parler non des achats mais du métier de développeur et des interactions avec votre manager… ou à l’inverse avec votre équipe. Merci et à bientôt !…
Bonjour, bienvenue pour l’épisode 4 ! Beaucoup de gens y compris des devs expérimentés ont des soucis de CSS. Il y a l’attitude défaitiste qui dit que vous n’y arriverez jamais, il y a l’attitude “pas mon problème” qui refile le bébé à quelqu’un d’autre, et il y a l’attitude snob qui méprise carrément le problème. … et bien sûr il y a l’attitude qui consiste à tester, à apprendre, et à livrer de la valeur à ses utilisateurs et ses clients :) OK, c’est dur C’est vrai que ce n’est pas simple. De manière générale, HTML et CSS c’est dur. Il y a eu des tas de normes qui s’empilent les unes sur les autres, mais le vrai souci était la variété des navigateurs qui ne gèraient pas tout pareil. Ça va un peu mieux et ça va me permettre de ne pas vous parler des astuces IE6, difficiles à contourner mais qu’on connaissait bien, ou IE7, un peu mieux a priori mais que finalement on connaissait moins. Pourquoi c’est dur ? L’intention est louable : on veut séparer la forme et le fond. Vous avez un contenu HTML, que j’aime visualiser comme des boîtes dans des boîtes dans des boîtes… etc. On souhaite garder les informations d’affichage à côté pour pouvoir changer de design sans changer le code, et vice-versa. On veut alors ajouter des informations sur ce que représentent ces boîtes, essentiellement son tag, sa classe, et son identifiant. À partir de tout cela, vous faites un autre fichier, une CSS pour Cascading Style Sheets, Feuille de Style qui s’appliquent en Cascade (pour une fois qu’on a un nom explicite !) qui contient une liste de règles, des directives CSS. Elles sont toutes à prendre en compte, mais pas aussi séquentiellement que du code où il y a un ordre précis, mais plutôt “toutes ensembles”. C’est comme si tout le monde venait parler en même temps dans une conversation ! Du coup la moindre règle modifie les autres, ce que l’on appelle des “effets de bord”, et c’est exactement ce qu’on essaie d’éviter de faire quand on code. Comment faire du sens dans ce bruit ? Dans la vraie vie, quand vous avez des gens qui parlent ensemble, quand vous avez plusieurs consignes au travail qui semblent en conflit, vous rangez aussi par priorités. Imaginez : on vous dit un jour de traiter tous les dossiers d’une certaine manière, mais s’ils sont bleus d’une autre. On vous dit que si un dossier traîne depuis trop longtemps, il est prioritaire. Que si le client est VIP, c’est prioritaire. Que si le patron le veut de suite, c’est ultra prioritaire. Qu’est-ce que vous faites ? Comme tout le monde : quand tout est prioritaire, rien n’est prioritaire, et vous tentez de retrouver un ordre décent dans tout cela. (D’ailleurs petite parenthèse : c’est pour cela que je refuse d’utiliser la directive CSS !important et que je ne la recommande pas.) On s’arrête, on réfléchit, et on décide qu’on traitera le dossier du patron en premier, puis les VIP, puis les anciens, puis les dossiers normaux, qui passent en bas de la pile. La règle de priorisation CSS marche pareil : qui le dit, quand est-ce qu’on le dit, mais surtout à propos de quoi on le dit. Qui parle quand ? Certaines pages Web n’ont pas d’information CSS. Elles sont très rares, mais il y a bien une information qui existe : quand vous écrivez une page HTML pure avec des titres H1 et H2, ils sont grands et en gras quand vous mettez une liste OL ou UL, ses éléments sont en retrait et avec un chiffre ou une puce quand vous utilisez une balise P pour paragraphe, il y a un espace vide autour (padding) les liens non visités sont bleus, les visités sont violets On voit qu’il existe une CSS par défaut du navigateur, mais c’est la moins importante de toutes. Ensuite, vous pouvez utiliser des CSS que vous importez via @import, link, ou dans le header, ou en ouvrant des balises Enfin, vous pouvez utiliser le style “inline” (écrit directement dans le HTML sur l’attribut style de l’élément, mais ce n’est vraiment pas propre) : c’est le dernier à parler, il est exactement là où vous voulez l’appliquer, on considère que c’est celui qui écrase tout le reste et qui aura raison au final. Qui parle de quoi ? On a cinq manière d’identifier des éléments HTML, cinq sélecteurs disponibles dans nos règles CSS : l’élément, ou le tag, c’est le type de boîte HTML (DIV par exemple) la classe, précédée par un point, quelque chose que vous pouvez ajouter pour noter la similarité entre plusieurs éléments (sur mes dossiers, la couleur rouge ou bleu, écrit au marqueur ou au stylo, le fait que ce soit un client VIP…) l’identifiant, précédé par un dièse, quand le dossier est nommé (le cas de Mr Tartempion) des pseudo-sélecteurs, avec des symboles “deux points” et des sélecteurs par attributs (avec des crochets) depuis CSS3 Si vous utilisez ces deux derniers vous savez un peu comment ça marche, alors je vais me concentrer sur les bases : élément, classe, identifiant. En plus, on peut les enchaîner : tous les dossiers bleus à condition qu’ils soient dans une armoire, voire expressément les dossiers bleus dans une armoire bleue. L’élément vaut un point : UL LI A vaut alors trois points. Une classe vaut dix points : UL.menu ou .menu LI valent onze points. L’identifiant vaut cent points. On donne ainsi une “prime à la précision” : plus le sélecteur est précis, plus votre règle monte en priorité, et plus c’est elle qui aura raison. Qui dit quoi ? Enfin, on sait de quoi vous parler, mais il faut savoir quoi faire dessus. Vous listez des propriétés CSS que vous voulez appliquer. Certaines s’appliqueront à tous ses enfants (toutes les boîtes dans cette boîte), d’autres non. Et tout finit par s’appliquer en même temps ! Dans la vraie vie, un humain l’oublierait probablement, mais pas un ordinateur : si une règle très peu prioritaire dit d’écrire en vert et toutes les règles plus prioritaires ne changent que la taille et les bordures de l’élément, le texte est toujours vert. Si vous voulez changer cela, vous allez réécrire cette propriété plus tard, prendre la précédence sur ce qui a été dit avant. On dit que le droit est le métier des exceptions, mais le développement aussi : je vous demande de faire un certain traitement, sauf dans tel cas, mais sauf dans tel cas encore plus précis, auquel cas on réécrit encore par dessus les deux règles moins importantes. Boni On vient de voir que c’est un sujet complexe. Il y a de plus en plus d’outils pour vous aider, c’est bien, et de pratiques à apprendre, ce qui peut porter à confusion et ajoute à la complexité ambiante. Je voulais garder l’épisode “low-tech” pour ne perdre personne et parce que je crois qu’il y a de la valeur dans les bases et l’historique. J’avais parlé d’un épisode philosophique, l’écriture n’est pas venue aussi naturellement que je pensais, je le garde au chaud pour plus tard. De même j’hésite à faire des épisodes business, ce qui sort clairement de la ligne annoncée mais qui a également beaucoup de valeur. De plus, à mon sens, on ne peut se contenter de faire son job, il y a toujours de vastes considérations à prendre en compte autour de votre périmètre précis, que ce soit pour progresser, pour maximiser les opportunités, ou pour deviner ce qui va vous tomber dessus et anticiper un peu. Bref, n’hésitez pas, je suis ouvert aux commentaires sur Twitter @zen_m4 :) Merci et à bientôt !…
Velkommen til Player FM!
Player FM scanner netter for høykvalitets podcaster som du kan nyte nå. Det er den beste podcastappen og fungerer på Android, iPhone og internett. Registrer deg for å synkronisere abonnement på flere enheter.
Bli med på verdens beste podcastapp for å håndtere dine favorittserier online og spill dem av offline på vår Android og iOS-apper. Det er gratis og enkelt!