<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" > <channel> <title>Sam & Max » recher</title> <atom:link href="http://sametmax.com/author/recher/feed/" rel="self" type="application/rss+xml" /> <link>http://sametmax.com</link> <description>Du code, du cul</description> <lastBuildDate>Sat, 07 Nov 2015 10:56:13 +0000</lastBuildDate> <language>en-US</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=4.1</generator> <item> <title>Des idées que j’aurai jamais le temps de faire. 30</title> <link>http://sametmax.com/des-idees-que-jaurais-jamais-le-temps-de-faire/</link> <comments>http://sametmax.com/des-idees-que-jaurais-jamais-le-temps-de-faire/#comments</comments> <pubDate>Wed, 05 Nov 2014 11:01:08 +0000</pubDate> <dc:creator><![CDATA[recher]]></dc:creator> <category><![CDATA[Gadget]]></category> <category><![CDATA[Philo et culture]]></category> <category><![CDATA[chocolat]]></category> <category><![CDATA[github]]></category> <category><![CDATA[glauque]]></category> <category><![CDATA[idées en vrac]]></category> <category><![CDATA[internet]]></category> <category><![CDATA[minecraft]]></category> <category><![CDATA[poils de cul]]></category> <category><![CDATA[savatage]]></category> <category><![CDATA[tolkien]]></category> <guid isPermaLink="false">http://sametmax.com/?p=12601</guid> <description><![CDATA[Idées en vrac de trucs à créer, pour se faire un start-up, ou juste pour s'amuser. Il y a de tout : du potentiellement intéressant, du bien débile, et du carrément glauque.]]></description> <content:encoded><![CDATA[<blockquote><p>Ceci est un post invité de <a href="http://recher.wordpress.com" target="_blank">Réchèr</a> sous licence <a href="http://creativecommons.org/licenses/by/3.0/" target="_blank">creative common 3.0 unported.</a></p></blockquote> <p>Mon cerveau est absolument génial. Il trouve tout le temps un tas de projets super. Le problème c’est que mon corps est une grosse feignasse, et ne prend jamais le temps ni le courage de les réaliser. Du coup, je me retrouve avec un tas de bazar dans la tête dont je ne ferais jamais rien. Le mieux, c’est de l’offrir au monde.</p> <p>Il y a un peu de tout : du potentiellement intéressant, du bien débile, et du carrément glauque. C’est en vrac, faites en ce que vous voulez.</p> <p>Et puisque ça semble être une tradition pour les articles longs : un peu de musique.</p> <p><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='1170' height='689' src='http://www.youtube.com/embed/TboNW5AiHA8?version=3&rel=1&fs=1&showsearch=0&showinfo=1&iv_load_policy=1&wmode=transparent' frameborder='0' allowfullscreen='true'></iframe></span></p> <h2>Chocolate DB</h2> <p><em>“Maintenant, vous savez sur quoi vous allez tomber”</em></p> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/ipad_chocolate_ichocolates.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/ipad_chocolate_ichocolates-300x256.jpg" alt="ipad_chocolate_ichocolates" width="300" height="256" class="alignnone size-medium wp-image-12603" /></a></p> <p>Repas de Noël en famille. Au moment du café, votre grand-mère pose la traditionnelle boîte de chocolat sur la table. Votre tante est allergique aux noix, votre cousin converti à l’islam ne boit plus d’alcool, y compris sous forme de liqueur, et vous, vous voudriez éviter le caramel car ça colle aux dents. Comme chaque année, votre grand-mère a jeté le papier de description de la boîte, parce que “c’est écrit trop petit dessus”.</p> <p>Le site de recensement Chocolate DB est là pour vous sortir de ce genre de situation délicate, avec des informations détaillées et individuelles de chaque chocolat, dans chaque boîte. Bien évidemment, le site comporte le bataclan habituel : tags, fonctions de recherche, avis des consommateurs, …</p> <p>Si ça marche bien, on peut ensuite mettre en place un service d’échange entre personnes habitants à proximité. Deux machins dégeux à la noix de coco contre un succulent praliné au gianduja ? Ça marche !</p> <p>Le concept est généralisable à tous ce qui se vend sous forme d’assortiment : yaourts aux fruits, sachets de thé, bonbons, bières, …</p> <h2>Pub’homme</h2> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/toilet-paper-ad.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/toilet-paper-ad-300x225.jpg" alt="toilet-paper-ad" width="300" height="225" class="alignnone size-medium wp-image-12605" /></a></p> <p>Site web de contre-pouvoir à la publicité.</p> <p>Au début, il y aurait juste des analyses et des recensements, pour mettre en lumière les techniques de fourbe régulièrement utilisées par la publicité :</p> <ul> <li>hyperréalité</li> <li>misandrie</li> <li>sexualisation injustifiée</li> <li>flatterie</li> <li>association arbitraire avec une célébrité</li> <li>…</li> </ul> <p>Sérieusement, quelqu’un pourrait me dire ce qu’il y a de sexuel dans un <a href="http://www.youtube.com/watch?v=9DIH-WYf9MY">putain de clacos</a> ?</p> <p>Ensuite, il serait envisageable de créer des structures de soutien aux victimes de la publicité. Par exemple :</p> <ul> <li>Les techniciens Carglass. Il y a certainement beaucoup de clients qui se foutent de leur gueule, et les plus extrêmes ont peut-être même envie de leur cogner dessus.</li> <li>Les gens qui s’appellent Mégane Renault ou Zoé Renault.</li> <li>Les parents dont les enfants font des caprices à cause des jouets qu’ils voient dans les publicités.</li> </ul> <p>(Parce que tout le monde n’est pas capable de se défendre aussi bien que <a href="http://www.liberation.fr/societe/2000/05/16/les-leneuf-entendus-par-la-justice-la-campagne-de-pub-de-9telecom-va-etre-temperee_326539">les Leneuf</a>).</p> <p>Pour finir, on pourrait s’offrir quelques flash mobs. 500 personnes se retrouvant à une finale de Rolland-Garros pour balancer des Kinder Buenos à la gueule de Jo-Wilfried Tsonga, ça vous tente ?</p> <h2>Un jeu web avec une économie déflationniste</h2> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/WoW_stats.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/WoW_stats-300x146.jpg" alt="WoW_stats" width="300" height="146" class="alignnone size-medium wp-image-12608" /></a></p> <p>Si vous lisez ce blog, vous connaissez déjà les bitcoins et les crypto-monnaies. L’une des raisons pour laquelle ce type de monnaie ne se démocratise pas, c’est qu’elles sont déflationnistes, un fonctionnement assez inhabituel. Un jeu web permettrait de le faire découvrir, d’expérimenter des situations, de détecter des comportements émergents, etc.</p> <p>Pour le jeu en lui-même, pas la peine de se prendre la tête, il suffirait de reprendre un thème classique : gestion d’une ferme / d’un héros / d’un bar à gigolos … L’économie du jeu aurait les particularités suivantes :</p> <ul> <li>La quantité totale d’argent ne change jamais. Au départ, tout est dans la caisse commune du jeu. Pour l’exemple, mettons qu’il y ait un million de pièce d’or.</li> <li>Les premiers joueurs inscrits reçoivent 100 pièces d’or, les suivants 50, les suivants-suivants 5, etc. (Au passage, ça incite à s’inscrire le plus tôt possible). Au bout d’un moment, les nouveaux arrivés ne reçoivent rien. Ce n’est pas grave, ça ne les empêche pas de jouer, et de se constituer un capital de départ en produisant et vendant des objets de base aux autres joueurs.</li> <li>Une pièce d’or est divisible à l’infini. Vous pouvez acheter une caisse de patates à 0.0000001 pièce d’or.</li> <li>Pour que l’expérience soit complète, il faut que les joueurs puissent également faire du troc.</li> </ul> <p>Ce dernier point comporte un risque, car les joueurs pourront décider d’utiliser une ressource de base pour leurs échanges, à la place de la monnaie déflationniste. Par exemple, ils définiront leurs prix en caisse de patates, plutôt qu’en pièces d’or. Ce risque est toutefois limité. Si la caisse de patate devient de fait la monnaie universelle, tous les joueurs chercheront à en fabriquer. Comme c’est une ressource de base, elle est très facile à produire, et elle deviendra donc une monnaie hautement inflationniste, en laquelle il sera difficile de faire confiance. Il y aura peut-être cohabitation de plusieurs monnaies. On ne sait pas, mais je pense que ça vaudrait le coup de tester.</p> <h2>YourCryptoCoins</h2> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/crypto-coins.jpeg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/crypto-coins.jpeg" alt="crypto-coins" width="300" height="180" class="alignnone size-full wp-image-12606" /></a></p> <p>Un logiciel simple pour créer sa propre crypto-monnaie, avec pleins de paramètres à ajuster, histoire de tester s’il y a plus efficace que le bitcoin :</p> <ul> <li>masse monétaire totale.</li> <li>coût de transaction.</li> <li>récompense par preuve de travail et/ou preuve de participation. Montant des récompenses.</li> <li>difficulté de minage.</li> <li>diminution automatique. (Tous les X jours, le solde de tous les comptes existants baissent de Y%, afin d’inciter les gens à dépenser leur argent)</li> </ul> <p>Ça permettrait aux gens de se créer leur petite crypto-monnaie locale, ce qui est peut-être un peu plus fiable que des bouts de papier imprimés à l’arrache avec écrit “Soleil” dessus.</p> <h2>Un réseau de communication vraiment décentralisé.</h2> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/semaphore.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/semaphore-300x195.jpg" alt="semaphore" width="300" height="195" class="alignnone size-medium wp-image-12610" /></a></p> <p>Le problème d’internet, c’est que les adresses IP sont attribuées par des autorités centrales. Et le support de communication (les fils téléphoniques et le spectre radio) est également sous contrôle central. Je ne sais pas trop comment y remédier, mais ça mérite réflexion.</p> <p>On pourrait mettre des capteurs et des petites lumières clignotantes sur les toits des maisons, qui se transmettraient les informations entre eux. Concrètement, vous ne pouriez communiquer qu’avec vos voisins, mais des messages pourraient transiter de maison en maison. Et on utiliserait des uuid pour identifier chaque point du réseau. Avec un système de clé publique-machin-truc pour garantir l’identifiant de chaque point et éviter les usurpations d’identité.</p> <p>Et pour les zones peu densément peuplée, on utiliserait des successions de petites lumières, ou des fils mais gérés de manière décentralisée.</p> <p>Ce serait sûrement très lent et pas fiable (si vos voisins n’ont pas allumé leurs transmetteurs, vous ne pouvez plus communiquer). Mais ce serait “libre”. Et du coup, pas d’abonnement à payer, juste de l’électricité.</p> <p>C’est vraiment brumeux comme idée, parce que j’y connais rien en bidouilleries réseau. Si d’autres gens ont des améliorations à proposer, qu’ils n’hésitent pas.</p> <h2>Poilatout</h2> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/cousin_machin.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/cousin_machin-214x300.jpg" alt="cousin_machin" width="214" height="300" class="alignnone size-medium wp-image-12611" /></a></p> <p>Algorithme, qui, à partir d’une phrase donnée, renvoie le “poil au” correspondant.<br /> Exemple :<br /> <em>“Quand l’imbécile montre la Lune”</em><br /> -> <em>“poil aux burnes”</em><br /> <em>“Le sage lui met un doigt”</em><br /> -> <em>“poil au foie”</em></p> <p>Y’a plus qu’à plugger ça avec Siri, et votre smartphone vous permettra de spammer toutes vos conversations de “poil au”.</p> <p>Si ça sert à rien, c’est que c’est indispensable.</p> <h2>Mi-tik</h2> <p><em>“Trouvez votre moitié”.</em></p> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/half_man_Andy_Gross.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/half_man_Andy_Gross.jpg" alt="half_man_Andy_Gross" width="186" height="159" class="alignnone size-full wp-image-12613" /></a></p> <p>Vous êtes unijambiste de la jambe gauche. Vous vous inscrivez sur le site Mi-tik. Vous avez alors la possibilité d’être mis en relation avec des unijambistes de la jambe droite. Si vous trouvez quelqu’un qui vous correspond, vous obtenez 50% de réduction sur tous vos achats de chaussures.</p> <p>Le site permet également de faire se rencontrer les manchots d’un bras, les borgnes, les “Van Gogh”, les hémiplégiques, …</p> <h2>HarDis (Harcèlement Distribué).</h2> <p><em>“Pensez dystopie globale, agissez dystopie locale”.</em></p> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/dented-car-chuck-norris.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/dented-car-chuck-norris.jpg" alt="dented-car-chuck-norris" width="250" height="165" class="alignnone size-full wp-image-12614" /></a></p> <p>La loi française ne vous interdit pas de chier sur le palier de votre voisin, de rayer sa voiture ou de l’appeler à 2 heures du matin. Mais elle vous interdit de le faire de manière répétée. Ça s’appelle du harcèlement.</p> <p>Le “réseau d’entraide HarDis” permet de s’affranchir de ce détail. Vous vous y inscrivez en déclarant un périmètre géographique d’action. Vous recevez ensuite des missions, vous demandant d’agir chez une personne-cible. Vous ne recevez jamais deux missions sur une même personne. À chaque fois que vous en effectuez une, vous envoyez une preuve de réalisation (photo, vidéo, …) et vous gagnez des points. Vous pouvez dépenser ces points pour créer des missions sur des gens que vous n’aimez pas.</p> <p>L’identité et l’adresse des personnes-cibles est révélée le plus tard possible. Chaque compte a un indice de confiance, visible par tous, qui augmente lorsqu’on effectue une mission et diminue lorsqu’on en prend une et qu’on ne l’effectue pas. Le but étant de limiter les “espions” (des personnes qui ne veulent pas réaliser de missions, mais qui veulent juste surveiller si elles ne sont pas la cible de missions existantes).</p> <p>Bien entendu, vous pouvez acheter des points, et bien entendu tous les outils d’anonymat sont disponibles : réseau Tor, crypto-monnaie, …</p> <h2>ADN-Fuck</h2> <p><em>“Là où y’a des gènes, y’a du plaisir”.</em></p> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/ensalada-de-pasta.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/ensalada-de-pasta-300x212.jpg" alt="ensalada-de-pasta" width="300" height="212" class="alignnone size-medium wp-image-12615" /></a></p> <p>La société ADN-Fuck rachète vos petits déchets corporels : salive, poils, sang, peaux mortes, urine, sperme… Elle les mélange avec ceux de centaines de personnes, et revend le tout sous forme de petit sachet.</p> <p>Quelqu’un souhaitant commettre un acte illégal peut acheter l’un de ces sachet d’anonymisation, et le répandre sur les lieux de son acte. Bonne chance à la police scientifique pour retrouver l’ADN du coupable !</p> <p>La société ADN-Fuck en elle-même ne commet rien d’illégal. Le commerce de poils de cul est, à priori, toujours autorisé dans la plupart des régions du globe.</p> <h2>RoboCraft</h2> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/minecraft_robot.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/minecraft_robot-300x168.jpg" alt="minecraft_robot" width="300" height="168" class="alignnone size-medium wp-image-12616" /></a></p> <p>Un jeu vidéo comme Minecraft, mais avec des robots programmables (en python, évidemment !). On peut les faire miner, construire, explorer, transformer des ressources, etc.</p> <p>Il y a déjà un add-on de Minecraft pour ça (ComputerCraft), mais c’est pas quelque chose de très officiel. Du coup, tout l’équilibrage du jeu est fait sans tenir compte de ComputerCraft. Un jeu conçu spécialement avec des robots, ce serait super chouette.</p> <p>Ça rejoint le concept d’automatic-play, dont on parle ici ou là : <a href="http://gamestudies.org/1301/articles/depaoli_automatic_play">http://gamestudies.org/1301/articles/depaoli_automatic_play</a></p> <p>Et il faudrait une économie déflationniste dans le jeu. Et des robots à reconnaissance vocale qui disent “poil au cul”.</p> <h2>Multi-versus</h2> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/multi_versus.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/multi_versus-300x102.jpg" alt="multi_versus" width="300" height="102" class="alignnone size-medium wp-image-12617" /></a></p> <p>Un jeu vidéo composé de mini-jeux, dans lequel deux joueurs ou plus s’affrontent, chacun avec un mini-jeux différent.</p> <p>Par exemple, le joueur 1 (Tetris) affronte le joueur 2 (Puzzle Bobble). Lorsque le joueur 1 effectue des actions valorisantes, (détruire plusieurs lignes à la fois), il envoie de la difficulté au Puzzle Bobble du joueur 2 (des bulles noires impossible à détruire). Et vice-versa : si le joueur 2 détruit plus de 3 bulles d’un coup, il envoie des lignes de cochonnerie sur l’aire de Tetris du joueur 1.</p> <p>Ce n’est faisable qu’avec des mini-jeux ou chacun joue sur son terrain (pas de Bomberman ni de Pong, par exemple), et ce serait une galère monumentale pour les équilibrer entre eux, mais ça serait vraiment fun.</p> <h2>Un format de fichier pour décrire des dessins animés.</h2> <p>Ce serait un format human-readable. C’est très important, car ça augmente la potentialité de bidouillage par n’importe qui, y compris des gamins de 8 ans.<br /> Ça pourrait ressembler à ceci par exemple :</p> <pre> img_balle = http://s2.postimg.org/w709hznpx/balle.png img_balle_ecrase = http://s18.postimg.org/hy41jochx/balle_ecrase.png area = 147, 275 default_time = 5 ms ball = Sprite(img_balle, 20, 0) ball.move(0, 10) ball.move(0, 10) ball.move(0, 10) ball.change_img(img_balle_ecrase) ball.move(0, -10) ball.move(0, -10) ball.move(0, -10) </pre> <p>Et ça donnerait quelque chose de ce genre :</p> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/bounce_147.gif" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/bounce_147.gif" alt="bounce_147" width="147" height="275" class="alignnone size-full wp-image-12619" /></a></p> <p>Et ensuite, on pourrait faire plein de trucs avec ce format de fichier :</p> <ul> <li>des players web, des players desktop, des éditeurs, des extracteurs d’images,</li> <li>des vidéos online (les images et les sons sont indiqués par des urls de téléchargement) et des vidéos stand-alone (tout est embarqué dans un .zip),</li> <li>des options de sous-titres, de commentaires, d’audio-description, d’adaptation aux daltoniens et aux épileptiques,</li> <li>des convertisseurs vers des fichiers vidéos classiques et vers du gif animé,</li> <li>des méta-données pour les credits, la licence, le rating ESRB,</li> <li>et bien d’autres choses encore !</li> </ul> <p>Vous allez me dire : “mais il y a déjà plein de trucs qui font ça : le flash, les gifs animés, Blender…”</p> <p>Oui, sauf que le flash c’est pas libre, les gifs c’est pas optimisé et c’est super compliqué à reprendre et à bidouiller, et Blender, il faut des mois de pratique avant de savoir faire quelque chose de correct.</p> <p>Ce format de fichier permettrait de créer rapidement des petits trucs à l’arrache, des cartes de vœux, des memes animés, etc. Et comme c’est du texte, c’est versionable et éditable collaborativement.</p> <h2>Githubiser pleins de trucs.</h2> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/github-octocat.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/github-octocat-300x244.jpg" alt="github-octocat" width="300" height="244" class="alignnone size-medium wp-image-12620" /></a></p> <p>Alors voilà, vous êtes un musicien et vous faites un solo de flûte à bec comme ça pour déconner. Vous le mettez sur gitsound. Quelqu’un d’autre arrive et ajoute une ligne de basse. Un autre y met quelques paroles. Un autre refait votre air initial avec une guitare électrique. Un autre reprend le tout en accéléré. Un autre y ajoute un “Cher effect” et colle un flow de rap par dessus. Et ainsi de suite.</p> <p>Ou alors, vous êtes un modéliseur 3D et vous commencez à créer un arbre géant. Quelqu’un arrive et ajoute des mini-branches pour lui donner un air plus détaillé. Un autre met des textures plus belles pour les feuilles. Un autre creuse un trou à l’intérieur. Un autre le recopie en 1000 exemplaires sur un quadrillage pour en faire un décor de clip de Mark Gormley. Et ainsi de suite.</p> <p>Il y a plein d’autres trucs qu’on pourrait githubiser afin de faciliter la création collaborative : les images (vectorielles ou pas), les recettes de cuisine, les règles de jeux de société, les dessins animés, les positions du kama-sutra, … Et pour certains médias, le github de base, qui ne permet de traiter que du texte, ne suffit pas.</p> <h2>Un Tolkien de la culture africaine</h2> <p><a href="http://sametmax.com/wp-content/uploads/2014/11/blackfoot-medicine-man-right.jpg" class="grouped_elements" rel="tc-fancybox-group12601"><img src="http://sametmax.com/wp-content/uploads/2014/11/blackfoot-medicine-man-right-250x300.jpg" alt="blackfoot-medicine-man-right" width="250" height="300" class="alignnone size-medium wp-image-12621" /></a></p> <p>Tolkien connaissait toutes les légendes de son pays et d’ailleurs. Il a défini la plupart des éléments de l’heroic fantasy. Sans lui, pas de Donjons et Dragons, de World of Warcraft, ou de Harry Potter. Maintenant, l’heroic fantasy vole de ses propres ailes et emprunte des éléments à d’autres cultures : momies égyptiennes, ninjas asiatiques, doppelgängers teutons, mind flayer lovecraftien, …</p> <p>Mais à part les zombis, on trouve très peu de choses empruntés à la mythologie africaine. C’est vraiment dommage, car avec le foisonnement culturel de ce continent, on pourrait créer des mondes imaginaires de dingue, peuplés de créatures étranges et de magie aux règles complexes, très différent de l’heroic fantasy.</p> <p>Il faudrait une personne qui connaisse tous ces trucs (l’animisme, le vaudou, les totems, les esprits, …) et qui s’en inspire pour écrire une chiée de bouquins. Ensuite, les rôlistes, les gamers et J.K. Rowling feront le reste.</p> <p><br/></p> <p>Voilà, ce sera tout pour le moment. Phosphorez mes braves, phosphorez !! Et si l’une de ces idées existe déjà réellement, prévenez-moi, ça m’intéresse.</p> ]]></content:encoded> <wfw:commentRss>http://sametmax.com/des-idees-que-jaurais-jamais-le-temps-de-faire/feed/</wfw:commentRss> <slash:comments>30</slash:comments> <enclosure url="http://sametmax.com/wp-content/uploads/2014/11/giant_brain_phone_booth.jpg" length="50804" type="image/jpg" /> </item> <item> <title>Télécharger les vidéos de Youtube 10</title> <link>http://sametmax.com/telecharger-les-videos-de-youtube/</link> <comments>http://sametmax.com/telecharger-les-videos-de-youtube/#comments</comments> <pubDate>Wed, 02 Oct 2013 07:51:58 +0000</pubDate> <dc:creator><![CDATA[recher]]></dc:creator> <category><![CDATA[Cul]]></category> <category><![CDATA[Web]]></category> <category><![CDATA[patcholle]]></category> <category><![CDATA[ssyoutube]]></category> <category><![CDATA[télécharger]]></category> <category><![CDATA[url]]></category> <category><![CDATA[vidéos]]></category> <category><![CDATA[youtube]]></category> <guid isPermaLink="false">http://sametmax.com/?p=7251</guid> <description><![CDATA[Il existe une vidéo sur youtube... Si vous la regardez... Au bout de 7 jours, vous mourrez. (Sauf si vous la regardez sur un smartphone, auquel cas l'écran sera trop petit pour faire passer la fille chelou).]]></description> <content:encoded><![CDATA[<blockquote><p> Ceci est un post invité de <a href="http://recher.wordpress.com/">Recher</a> posté sous licence <a href="http://creativecommons.org/licenses/by/3.0/">creative common 3.0 unported</a>. </p></blockquote> <p> – Assistance informatique, bonjour.</p> <p> – Salut les moines bouddhistes. Comment je fais pour aller sur Youtube ? Votre stupide filtre à puceaux me bloque l’accès ! </p> <p> – C’est lié à la politique de l’entreprise. Le site est totalement interdit.</p> <p> – Mais bordel, c’est la pause de midi ! Je suis toute seule dans mon service, et je suis excitée ! Pas un seul stagiaire à me mettre sous la dent ! J’ai besoin de mes vidéos pornos ! Et quand je dis “besoin”, c’est VRAIMENT besoin !</p> <p> – Veuillez m’excuser Madame, mais je ne peux rien pour vous. </p> <p> – J’ai la patcholle qui palpite à la vitesse d’une levrette au galop ! C’est urgent !</p> <p> – La patcholle ? Mais enfin Madame, ce mot n’existe même pas !</p> <p> – Le mot n’existe peut-être pas, mais ma patcholle, elle, elle existe ! Et elle est pas loin de la combustion spontanée ! </p> <p> – La seule solution serait que vous achetiez des DVD, et que vous les rameniez à votre bureau. On ne contrôle que ce que vous faites sur internet, pas ce que vous visionnez en local.</p> <p> – Merci pour le conseil, mon p’tit chou, j’ai tout ce qu’il faut à la maison. Mais là, c’est d’une vidéo spécifique dont j’ai envie. Celle avec le nain et les ballons de baudruche. Et elle n’est que sur Youtube !</p> <p> – Vous pouvez la télécharger. Changez l’URL, ajoutez les lettres “ss” devant le mot “youtube”, sélectionnez ensuite la qualité parmi celles disponibles, et vous récupérerez le fichier sur votre disque. Par exemple : <a href="http://www.ssyoutube.com/watch?v=uSGnmCTkIfE">http://www.ssyoutube.com/watch?v=uSGnmCTkIfE</a>. Avec un peu de chance, l’accès par la connexion de l’entreprise n’est même pas bloqué. </p> <p> – Attendez j’essaye. Je connais l’adresse de ma vidéo par cœur. … Oh putain, ça marche ! Et ça passe même le filtre à puceaux de Youtube ! Ooouiiiii !! Va y avoir de la cyprine plein les murs !</p> <p> – Cela m’a fait plaisir d’avoir pu vous aider, Madame.</p> <p> – De même. Dites, pendant que ça télécharge, vous voulez pas venir me rendre visite ? On se trouverait bien quelques corpuscules de Krause avec lesquels s’occuper. </p> <p> – Merci Madame, mais ça ne m’intéresse pas.</p> <p> – Je vous propose du sexe gratuit et vous n’en voulez pas ? Ah d’accord, vous êtes homosexuel. J’aurais dû m’en douter, à votre petite voix fluette. De toutes façons, ils sont tous pédés dans l’informatique.</p> <p> – Au contraire Madame, je suis hétérosexuelle. En revanche, je suis une femme. Bon après-midi à vous.</p> <p><a href="http://sametmax.com/wp-content/uploads/2013/09/sofia-rose-07.jpg" class="grouped_elements" rel="tc-fancybox-group7251"><img src="http://sametmax.com/wp-content/uploads/2013/09/sofia-rose-07.jpg" alt="Sofia the Rose en secrétaire sexy" title="Sofia the Rose en secrétaire sexy" width="400" height="600" class="alignnone size-full wp-image-7253" /></a> </p> ]]></content:encoded> <wfw:commentRss>http://sametmax.com/telecharger-les-videos-de-youtube/feed/</wfw:commentRss> <slash:comments>10</slash:comments> <enclosure url="http://sametmax.com/wp-content/uploads/2013/09/ring_cosplay.jpg" length="70271" type="image/jpg" /> </item> <item> <title>Comment le Revenu de Base Inconditionnel pourrait maximiser le bonheur. 42</title> <link>http://sametmax.com/comment-le-revenu-de-base-inconditionnel-pourrait-maximiser-le-bonheur/</link> <comments>http://sametmax.com/comment-le-revenu-de-base-inconditionnel-pourrait-maximiser-le-bonheur/#comments</comments> <pubDate>Fri, 10 May 2013 11:31:50 +0000</pubDate> <dc:creator><![CDATA[recher]]></dc:creator> <category><![CDATA[Philo et culture]]></category> <category><![CDATA[argent]]></category> <category><![CDATA[bonheur]]></category> <category><![CDATA[humains]]></category> <category><![CDATA[Initiative Citoyenne Européenne]]></category> <category><![CDATA[interdépendance]]></category> <category><![CDATA[Revenu de Base Inconditionnel]]></category> <category><![CDATA[viande de mammouth]]></category> <guid isPermaLink="false">http://sametmax.com/?p=6028</guid> <description><![CDATA[Réflexion sur le bonheur, l'interdépendance entre humains et l'argent. Cette réflexion nuagesque aboutit à une proposition pour débugger le système monétaire actuel, et optimiser le bonheur global. Featuring Albert Jacquard.]]></description> <content:encoded><![CDATA[<blockquote><p> Ceci est un post invité de <a href="http://sametmax.com/author/recher/">Recher</a> posté sous licence <a href="http://creativecommons.org/licenses/by/3.0/">creative common 3.0 unported</a>.</p> <p>Recher est un des premiers lecteurs (et soutient) du blog, donc nous avons choisi de le laisser exprimer des idées qui lui sont chères. Notez que ce n’est PAS la marque d’un changement de ligne éditoriale du blog et que ce n’est PAS l’annonce de plus d’articles sur des thèmes politiques sur Sam et Max.</p> <p>Ceci dit, un de temps en temps ne fait pas de mal. Ne vous battez pas trop en comments :-) </p></blockquote> <h2>Quelques faits amusants concernant les humains</h2> <h3>La viande, c’est la force</h3> <p>Lorsque les hommes préhistoriques tuaient une grosse bestiole, ils ne pouvaient ni manger toute la viande d’un coup, ni la conserver. La meilleure solution qu’ils ont trouvé a été de donner cette viande à d’autres hommes préhistoriques, qui se sentaient alors redevable, et qui partageraient la viande de leurs chasses futures.</p> <p>Le placement bancaire de l’homme préhistorique, c’était l’estomac des autres. </p> <p>D’ailleurs, selon de nombreux scientifiques, ce qui a fait que l’homo sapiens soit devenu ce que nous sommes aujourd’hui, c’est que pour survivre, ils s’échangeaient leur savoir. Sans cela, on aurait certainement très vite disparu. Comparé aux autres espèces, l’homo sapiens est une pauvre lopette qui n’a rien pour lui.</p> <p><a href="http://web.archive.org/web/20060627055742/http://culturelibre.net/article.php3?id_article=247">Source approximative (webarchivée, et qui elle-même ne cite pas ses sources)</a></p> <p><a href="http://sametmax.com/wp-content/uploads/2013/05/geico_caveman.jpg" class="grouped_elements" rel="tc-fancybox-group6028"><img src="http://sametmax.com/wp-content/uploads/2013/05/geico_caveman.jpg" alt="Le cours du tigre à dents de sabre a chuté de 3 points. Groumf !" title="Le cours du tigre à dents de sabre a chuté de 3 points. Groumf !" width="250" height="125" class="alignnone size-full wp-image-6038" /></a></p> <h3>Une expérience un peu glauque du 13ème siècle</h3> <p>Frédéric 2, Suprême Tôlier du Saint-Empire romain germanique, voulait savoir quelle serait la langue que parlerait naturellement un homme n’ayant pas reçu d’influences extérieures. Il prit plusieurs bébés, et demanda à des nourrices de s’en occuper avec beaucoup de soin, mais sans jamais leur parler. Il s’attendait à ce qu’ils finissent par parler grec ou latin. </p> <p>Ça a méchamment échoué. Les bébés ont dépéris et ils sont tous morts.</p> <h3>Géant vert, nain jaune, etc.</h3> <p>Il y a une expression à la mode, qui dit : “Nous sommes des nains sur des épaules de géants”. Les géants représentent nos ancêtres, qui ont accumulé des connaissances et construit des trucs pour que les générations suivantes vivent mieux. Les nains représentent les humains actuels, qui contribuent eux aussi à améliorer la condition humaine, pas autant que les géants, mais un peu quand même. L’ensemble géant + nain étant plus haut que le géant tout seul.</p> <h3>Les pensées d’un philosophe-généticien-mathématicien-humaniste</h3> <p>Albert Jacquard dit : “je suis les liens que je tisse avec d’autres”.</p> <p>C’est une phrase bizarre. Ce n’est pas : “les liens que je tisse avec d’autres révèlent ma nature profonde”. C’est : “ma nature profonde, ce sont les liens”.</p> <p>Ça veut dire qu’on construit sa personnalité par les relations qu’on a avec les autres. Ça ressemble à une idée hippie-new-age-cucul-la-praline, mais en fait non. Si on a des relations de merde et qu’on insulte tous le monde, on se construit une personnalité de merde. On fait ce qu’on veut de soi-même.</p> <p><a href="http://sametmax.com/wp-content/uploads/2013/05/albert_jacquard-03.jpg" class="grouped_elements" rel="tc-fancybox-group6028"><img src="http://sametmax.com/wp-content/uploads/2013/05/albert_jacquard-03.jpg" alt="C'est lui Albert Jacquard. Il peut créer un seau rempli de chromosomes par la seule force de sa volonté." title="C'est lui Albert Jacquard. Il peut créer un seau rempli de chromosomes par la seule force de sa volonté." width="373" height="501" class="alignnone size-full wp-image-6039" /></a></p> <h2>Le fonctionnement de l’humanité.</h2> <p>À partir de ces quelques faits amusants, il me semble être possible de déduire deux principes globaux :</p> <p><b>Les humains sont interdépendants avec leurs contemporains, ainsi qu’avec les générations passées et futures.</b></p> <p>Cette interdépendance est inévitable. Vous n’avez pas le choix, à moins d’être un ermite habitant une grotte et chassant pour se nourrir. Et si vous décidez de vivre comme ça, surtout, ne partagez pas votre viande de mammouth, vous reprendriez votre interdépendance.</p> <p>Même quelqu’un de très riche est interdépendant, car il a besoin d’un pool d’humain “de bonne qualité”, à qui il pourra acheter des biens et services de bonnes qualités : un bon comptable, un bon cuisinier, un bon chauffeur, un bon constructeur de piscine, un bon médecin, un bon chirurgien esthétique… Ce riche quelqu’un ne pourra pas former son pool d’humain par lui-même. Ça nécessite beaucoup de temps, plus que le temps d’une seule vie, fût-elle de riche.</p> <p><a href="http://sametmax.com/wp-content/uploads/2013/05/interdependance.jpg" class="grouped_elements" rel="tc-fancybox-group6028"><img src="http://sametmax.com/wp-content/uploads/2013/05/interdependance.jpg" alt="Interdépendance des gens riches entre eux-même. Source : http://www.cairn.info/revue-societes-contemporaines-2007-4-page-105.htm (tl;dnr)" title="Interdépendance des gens riches entre eux-même. Source : http://www.cairn.info/revue-societes-contemporaines-2007-4-page-105.htm (tl;dnr)" width="500" height="331" class="alignnone size-full wp-image-6040" /></a></p> <p><b>Plus on développe des liens de bonne qualité avec les autres, plus on est heureux.</b></p> <p>Voici un graphique exprimant le bonheur d’une personne en fonction de son argent</p> <p><a href="http://sametmax.com/wp-content/uploads/2013/05/fonction_argent_bonheur.png" class="grouped_elements" rel="tc-fancybox-group6028"><img src="http://sametmax.com/wp-content/uploads/2013/05/fonction_argent_bonheur.png" alt="Des courbes comme ça mériteraient clairement un petit coup de xkcdify." title="Des courbes comme ça mériteraient clairement un petit coup de xkcdify." width="467" height="333" class="alignnone size-full wp-image-6041" /></a></p> <p>Et un autre exprimant le bonheur d’une personne en fonction de la qualité et de la quantité de liens qu’elle a tissé avec d’autres.</p> <p><a href="http://sametmax.com/wp-content/uploads/2013/05/fonction_argent_liens.png" class="grouped_elements" rel="tc-fancybox-group6028"><img src="http://sametmax.com/wp-content/uploads/2013/05/fonction_argent_liens.png" alt="Mais j'avais la flemme et je sais pas me servir de xkcdify, désolé !" title="Mais j'avais la flemme et je sais pas me servir de xkcdify, désolé !" width="544" height="388" class="alignnone size-full wp-image-6042" /></a></p> <p>Le bonheur total d’une personne étant, à peu de choses près, la somme de ces deux bonheurs.</p> <p>Cette théorie rejoint plus ou moins celle de la pyramide de Maslow. Sauf que le grand Wikipedia dit que des tas de gens ont invalidé la pyramide de Maslow. Je vais donc pas trop m’attarder dessus, et faire comme si on n’était pas au courant. (Un peu de mauvaise foi, ça aide toujours les argumentations).</p> <p>À partir de ces 2 graphiques, mon conseil en tant que coach du sens de la vie, est le suivant :</p> <p>Si vous êtes vraiment pauvres, essayez d’abord de récupérez de l’argent, plutôt que de vous faire des amis. Ça vous rendra heureux plus vite. Une fois que vous avez atteint un seuil de revenu suffisamment satisfaisant et régulier, ce sera devenu moins rentable, en terme de bonheur, de chercher à gagner encore plus. À partir de là, essayez de vous faire des amis et de créer des liens. </p> <p>Au passage, cela me permet de rappeler <a href="http://sametmax.com/deux-conneries-a-la-seconde/">qu’il faut conserver la neutralité d’internet</a>, car c’est une formidable machine à fabriquer des liens.</p> <p>Et au passage bis, je ne pense pas que l’être humain soit “naturellement bon”. Les concepts “bon” et “mauvais” me semblent trop compliqués pour qu’ils puissent être implémentés dans la nature.</p> <p><a href="http://sametmax.com/wp-content/uploads/2013/05/le-bien-et-le-mal.jpg" class="grouped_elements" rel="tc-fancybox-group6028"><img src="http://sametmax.com/wp-content/uploads/2013/05/le-bien-et-le-mal.jpg" alt="J'ai hésité entre ça et une image de South Park épisode 10 saison 1. Et je me suis dit que South Park, c'était tellement conventionnel." title="J'ai hésité entre ça et une image de South Park épisode 10 saison 1. Et je me suis dit que South Park, c'était tellement conventionnel." width="550" height="330" class="alignnone size-full wp-image-6044" /></a></p> <p>En fait, l’humain cherche à maximiser son bonheur personnel, sans forcément se soucier des autres. Mais en plus de ça, une bonne partie des humains a pris conscience du graphique “liens tissés -> bonheur”, ce qui va les amener à vouloir développer des liens de bonne qualité avec les autres : rendre service, discuter, échanger des idées, … Ça donne l’impression qu’ils sont naturellement bon, alors qu’en fait, ils cherchent juste à être heureux eux-même, le plus efficacement possible.</p> <p>Toute la question est de savoir comment faire prendre conscience aux humains de la relation entre le bonheur et les liens tissés. Je n’ai pas de réponse précise (éducation ? liens initiaux ?)</p> <h2>Où veux-je donc en venir ?</h2> <p>Il vaut mieux pour vous-même que les humains proches de vous soient pas trop cons, pas trop pauvres et un minimum heureux. Ceci pour 2 raisons :</p> <ul> <li> Afin de maximiser votre bonheur personnel, vous devez développer des liens de bonne qualité. Or c’est plus facile à faire avec des gens “de bonne qualité”. </li> <p><br/></p> <li> Dans “interdépendance inévitable” il y a “dépendance inévitable”. C’est moins inquiétant d’être dépendant de gens de bonne qualité, plutôt que d’un ramassis de crève-la-faim dépressifs qui ne savent rien faire. </li> <p><br/></ul> <p>Il existe un moyen simple pour s’assurer que tous les humains autour de vous soient un minimum heureux, et aient la possibilité matérielle d’être d’une qualité minimale : le graphique “argent -> bonheur”.</p> <p>Si on s’assure que tout le monde a la possibilité de s’avancer un peu dans ce graphique, afin d’arriver à peu près au point “Appartement”, on augmentera énormément le bonheur de beaucoup de gens, à peu de frais.</p> <p>Si on s’assure que tout le mode peut s’avancer encore plus dans le graphique (par exemple, jusqu’au point “Rolex”), ce sera moins rentable. Il faudrait beaucoup plus d’argent, pour une augmentation de bonheur plutôt faible. Autant donc rester dans des sommes raisonnables.</p> <p>L’idée qui en résulte s’appelle le Revenu de Base Inconditionnel.</p> <p><a href="http://sametmax.com/wp-content/uploads/2013/05/ban_bart.jpg" class="grouped_elements" rel="tc-fancybox-group6028"><img src="http://sametmax.com/wp-content/uploads/2013/05/ban_bart.jpg" alt="J'ai jamais compris comment Kurt Cobain pouvait chanter sous l'eau." title="J'ai jamais compris comment Kurt Cobain pouvait chanter sous l'eau." width="450" height="225" class="alignnone size-full wp-image-6045" /></a></p> <h3>Explication du Revenu de Base Inconditionnel en un paragraphe </h3> <p>Cela consiste à donner la même somme d’argent, tous les mois, à toutes les personnes d’un pays ou d’une région. Ce Revenu continue d’être perçu même lorsqu’on commence à travailler, et quel que soit le type de contrat de travail. La somme donnée est calculée de façon à ce que chaque personne puisse vivre “dignement”, c’est à dire : bouffer, se loger et éventuellement acquérir certains biens culturels de base.</p> <p>Cette idée (pas si nouvelle que ça) est actuellement en train de susciter des réflexions ici et là. C’est alors que des gens se sont dit que ce serait bien de lancer une Initiative Citoyenne Européenne, pour également faire réflexionner les gens qui nous gouvernent.</p> <h3>Explication de l’Initiative Citoyenne Européenne (ICE) en un paragraphe, avec mes propres termes, donc simplifiée à outrance</h3> <p>Une ICE est créée par un petit groupe de gens, qui demandent que soit mis en place un “truc dans la loi” (Ça peut être un peu tout, mais pas complètement n’importe quoi). Les citoyens de l’Union Européenne qui sont d’accord avec le truc en question signent une pétition. Si au bout d’un an, un million de signature est récupéré, la Commission Européenne est obligée de venir écouter le groupe initiateur de l’ICE, de réfléchir au truc et de donner un avis. La Commission Européenne peut répondre “on ne fera pas votre truc, GTFO LOL”, mais cela doit être accompagné d’arguments détaillés.</p> <p>C’est là où je voulais en venir. Je vous invite à signer l’ICE pour le Revenu de Base Inconditionnel, afin de réfléchir à cette technique d’optimisation du bonheur humain. Pour en savoir plus, pour des infos pratiques et concrètes, et pour finalement signer en ligne, ça se passe par ici : <a href="http://revenudebase.info/initiative-citoyenne-europeenne/">http://revenudebase.info/initiative-citoyenne-europeenne/</a></p> <h3>Si vous pensez que c’est une idée de merde parce que <pleins de raisons>.</h3> <p>Le Revenu de Base Inconditionnel modifierait en profondeur notre façon de nous comporter en société, en modifiant notre rapport à l’argent, au travail et aux autres. C’est pourquoi, il suscite beaucoup de réactions, parfois assez fortes, de refus ou d’acceptation.</p> <p>Les raisons de refuser cette idée sont assez diverses, mais on retombe souvent sur les mêmes. Des gens les ont alors rassemblées, et y ont opposés des arguments pour refuser ce refus. Je vous laisse quelques liens à ce sujet. Rassurez-vous, le propos y est bien plus concret que la réflexion nuagesque que j’ai faite en début d’article.</p> <p>“Les chômeurs vont jouer à la Playstation”<br /> <a href="http://revenudebase.info/2013/04/revenu-base-pas-outil-lutte-contre-chomage/">http://revenudebase.info/2013/04/revenu-base-pas-outil-lutte-contre-chomage/</a></p> <p>“C’est une idée libérale / de communiste”<br /> “Cela poussera les gens à l’oisiveté”<br /> “Plus personne ne voudra effectuer les tâches ingrates”<br /> “Le revenu de base va provoquer de l’inflation”<br /> “C’est une idée utopiste”<br /> “C’est impossible à financer”<br /> “L’état est déjà très généreux en France, ça ne va rien changer”<br /> “L’immigration va encore plus augmenter”<br /> “La société n’est pas prête, il faut d’abord réformer le système”<br /> <a href="http://www.tetedequenelle.fr/2011/04/mauvaises-raisons-revenu-de-vie/">http://www.tetedequenelle.fr/2011/04/mauvaises-raisons-revenu-de-vie/</a></p> <p><a href="http://sametmax.com/wp-content/uploads/2013/05/Trialsale-10pcs-magic-tricks-money-printer-hotsale-magic-paper-make-real-money-toy-free-shipping.jpg" class="grouped_elements" rel="tc-fancybox-group6028"><img src="http://sametmax.com/wp-content/uploads/2013/05/Trialsale-10pcs-magic-tricks-money-printer-hotsale-magic-paper-make-real-money-toy-free-shipping.jpg" alt="It prints money !" title="It prints money !" width="310" height="310" class="alignnone size-full wp-image-6046" /></a></p> <h3>Si vous pensez toujours que c’est une idée de merde.</h3> <p>C’est votre droit. Et si ça se trouve, c’est vous qui avez raison.</p> <p>Mais même dans ce cas, je vous invite à signer l’ICE. Celle-ci n’oblige pas l’Europe à instaurer le Revenu de Base. Elle oblige <strong>à réfléchir</strong> à l’idée du Revenu de Base. </p> <p>Si c’est une idée de merde, les gens de la Commission Européenne auront tôt fait de s’en apercevoir, car ils sont certainement plus calés que moi en économie, géopolitique, psychohistoire et autres. Ils pourront alors expliquer à tout le monde, et avec des arguments valables, en quoi c’est de la merde. Si c’est le cas, je promets de ne plus embêter personne avec cette idée. Une toute petite signature en échange de votre tranquilité future, ça vaut le coup non ?</p> <p>Le bonheur vaincra !</p> ]]></content:encoded> <wfw:commentRss>http://sametmax.com/comment-le-revenu-de-base-inconditionnel-pourrait-maximiser-le-bonheur/feed/</wfw:commentRss> <slash:comments>42</slash:comments> <enclosure url="http://sametmax.com/wp-content/uploads/2013/05/money.jpg" length="32660" type="image/jpg" /> </item> <item> <title>Union d’un ensemble d’intervalles 15</title> <link>http://sametmax.com/union-dun-ensemble-dintervalles/</link> <comments>http://sametmax.com/union-dun-ensemble-dintervalles/#comments</comments> <pubDate>Sun, 17 Feb 2013 06:42:43 +0000</pubDate> <dc:creator><![CDATA[recher]]></dc:creator> <category><![CDATA[Programmation]]></category> <category><![CDATA[algorithme]]></category> <category><![CDATA[bonhomme sur un mur]]></category> <category><![CDATA[bourrin]]></category> <category><![CDATA[intersection]]></category> <category><![CDATA[intervalle]]></category> <category><![CDATA[jeux de plate-forme]]></category> <category><![CDATA[matheux]]></category> <category><![CDATA[optimisation]]></category> <category><![CDATA[python]]></category> <category><![CDATA[sort]]></category> <category><![CDATA[sperme]]></category> <category><![CDATA[tri]]></category> <category><![CDATA[union]]></category> <guid isPermaLink="false">http://sametmax.com/?p=4572</guid> <description><![CDATA[Un algo simple et classe pour fusionner et classer des intervalles qui se chevauchent, s'intersectionnent, etc.]]></description> <content:encoded><![CDATA[<blockquote><p>Ceci est un post invité de <a href="http://recher.wordpress.com" target="_blank">Réchèr</a> posté sous licence <a href="http://creativecommons.org/licenses/by/3.0/" target="_blank">creative common 3.0 unported.</a></p></blockquote> <p>Kikoo amis matheux ou pas. Aujourd’hui, on va se faire un petit algo de derrière les fagots. Vous n’en aurez peut-être jamais besoin dans le monde réel, mais, qui a dit qu’on allait se contenter uniquement de ce dont on a besoin ? De plus, je présenterais, à la fin, une astuce générique d’algorithmiciens.</p> <h2>Pré-requis</h2> <ul> <li>Connaître très vaguement la notion des O(n²), O(truc), … qui définissent le temps d’exécution d’un algorithme en fonction de la quantité de données à traiter. (Si ça vous parle pas c’est pas grave). </li> <li>Savoir que le pluriel d’intervalle n’est pas “intervaux”.</li> </ul> <p>Petite précision : pour définir des intervalles d’entiers, j’emploierais la convention pythonienne : le dernier élément n’est pas inclus. C’est à dire que [2, 7] correspond à 5 éléments : 2, 3, 4, 5, 6. </p> <h2>Énoncé</h2> <p>Soit une liste de couple de nombres, représentant des intervalles. Ils sont tout en vrac, y’en a qui se chevauchent, d’autres qui s’inclusent, etc. Bref, l’ensemble fait penser à une partouse animale multi-espèces. </p> <p>exemple : [ [2, 7], [3, 7], [1, 5], [9, 10], [8, 9] ]<br /> <a href="http://sametmax.com/wp-content/uploads/2013/02/intervalle-1.png" class="grouped_elements" rel="tc-fancybox-group4572"><img src="http://sametmax.com/wp-content/uploads/2013/02/intervalle-1.png" alt="Les crochets d'intervalles ont une tronche bizarre. C'est pour bien montrer que le dernier élément n'est pas inclus." title="Les crochets d'intervalles ont une tronche bizarre. C'est pour bien montrer que le dernier élément n'est pas inclus." width="455" height="255" class="alignnone size-full wp-image-4575" /></a></p> <p>Vous voulez une méthode pour rassembler tout ça, et obtenir une liste d’intervalles, triée, sans chevauchement, correspondant à la fusion de tous les intervalles de départ. En maths, on appelle cette opération une union. En partouse animale multi-espèces, on appelle aussi ça une union, mais ce n’est pas le sujet.</p> <p>résultat souhaité : [ [1, 7], [8, 10] ]<br /> <a href="http://sametmax.com/wp-content/uploads/2013/02/intervalle-2.png" class="grouped_elements" rel="tc-fancybox-group4572"><img src="http://sametmax.com/wp-content/uploads/2013/02/intervalle-2.png" alt="Toujours cet éternel problème de nombre de poteaux versus nombre d'intervalles. Je suis sûr que si on était dans un univers non-eucliden on serait pas emmerdé avec ce genre de détail à la con." title="Toujours cet éternel problème de nombre de poteaux versus nombre d'intervalles. Je suis sûr que si on était dans un univers non-eucliden on serait pas emmerdé avec ce genre de détail à la con." width="449" height="160" class="alignnone size-full wp-image-4577" /></a></p> <h2>Solutions auxquelles on pense en premier</h2> <h3>Le bourrin pas-à-pas</h3> <p>On récupère le début d’intervalle le plus à gauche, et la fin la plus à droite. On boucle entre ces deux valeurs. À chaque itération, on effectue le traitement suivant : </p> <ul> <li>Vérifier si la valeur courante est dans au moins un intervalle. </li> <li>Si oui, et que juste avant on était dans aucun intervalle, alors on marque cette valeur comme un début d’intervalle. </li> <li>Si non, et que juste avant on était dans au moins un intervalle, alors on marque cette valeur comme une fin d’intervalle.</li> </ul> <h4>Désavantages</h4> <p>Si, au départ, on a deux intervalles très éloignés, par exemple [0, 2] et [1000000, 1000002] on va faire une boucle de 1000002 itérations. Pour traiter 2 intervalles, c’est un peu lourd.</p> <p>Ça ne marche qu’avec des entiers. Si on a des intervalles de réels, on itère comment ? En avançant de 0.0000000001 en 0.0000000001 ? Même problème avec des intervalles de date-heure.</p> <h3>Le bourrin cumulatif</h3> <p>On crée une liste géante de booléens, tous à False, qui s’étend du premier début d’intervalle à la fin du dernier. Chaque booléen indiquera si le nombre correspondant se trouve dans au moins un intervalle. On met les bons booléens à True en parcourant les intervalles de la liste initiale. Puis, on construit la liste finale d’intervalles, en se basant sur les booléens.</p> <h4>Désavantages</h4> <p>Si on a en entrée un million de fois l’intervalle [10, 210], on va mettre un million de fois à True la même suite de 200 booléens. 200 millions d’opérations pour ressortir un unique intervalle [10, 210].</p> <p>Même problème que précédemment. Ça ne marche qu’avec des nombres entiers.</p> <p><a href="http://sametmax.com/wp-content/uploads/2013/02/881911164.jpg" class="grouped_elements" rel="tc-fancybox-group4572"><img src="http://sametmax.com/wp-content/uploads/2013/02/881911164.jpg" alt="Du bourrin et du cumulatif : serait-ce l'occasion d'invoquer une grand-mère à moustache ?" title="Du bourrin et du cumulatif : serait-ce l'occasion d'invoquer une grand-mère à moustache ?" width="210" height="300" class="alignnone size-full wp-image-4579" /></a></p> <h3>L’enfileur de perles</h3> <p>On a d’un côté la liste finale des intervalles (initialisée à vide), et de l’autre, la liste initiale, en bordel. On passe les intervalles d’une liste à l’autre, un par un, en testant les cas suivants :</p> <ul> <li>Le début et la fin de l’intervalle en cours n’est dans aucun intervalle final -> ça fait un nouvel intervalle final. </li> <li>Le début est dans un intervalle final, mais pas la fin -> ça rallonge l’interval final existant.</li> <li>La fin est dans un intervalle final, mais pas le début -> ça rallonge l’intervalle final existant, mais par l’autre côté.</li> <li>La fin et le début sont dans le même intervalle final -> l’intervalle en cours ne sert à rien.</li> <li>La fin et le début sont dans deux intervalles finaux différents. -> il faut fusionner les deux intervalles finaux.</li> </ul> <p>Et en plus de tout ça, il faut également tester s’il n’y a pas des intervalles finaux entièrement inclus dans l’intervalle en cours. Auquel cas, ils ne servent plus à rien, et doivent être enlevé de la liste.</p> <h4>Désavantages</h4> <p>Une bonne grosse prise de tête à coder tous les cas possibles, sans rien oublier, sans bug. </p> <p>Le fait de chercher si un nombre se trouve dans une liste d’intervalles, fut-elle triée, est une opération qui prend un certain temps. Ça peut s’optimiser avec de la dichotomie ou des trucs du genre, mais quand même. </p> <p>Par contre, cette algo marche avec des nombres réels et des date-heure. Youpi.</p> <p><a href="http://sametmax.com/wp-content/uploads/2013/02/JB333.jpg" class="grouped_elements" rel="tc-fancybox-group4572"><img src="http://sametmax.com/wp-content/uploads/2013/02/JB333.jpg" alt="Je pige même pas comment ce jouet est censé fonctionner. Faut mettre les perles dans le trou de la machine ? Comment le trou de perle se met en face du fil ? Est-ce que ça serait pas encore plus galère qu'à la main ?" title="Je pige même pas comment ce jouet est censé fonctionner. Faut mettre les perles dans le trou de la machine ? Comment le trou de perle se met en face du fil ? Est-ce que ça serait pas encore plus galère qu'à la main ?" width="359" height="275" class="alignnone size-full wp-image-4581" /></a></p> <h2>Et si on arrêtait les conneries ?</h2> <p>Dans ces premières solutions, on considère les intervalles comme des objets immuables. Il faut en traiter un entièrement avant de passer au suivant. Mais on peut aussi les voir comme deux événements distincts (un début et une fin), que l’on peut dissocier totalement, et traiter dans leur ordre d’arrivée. On ne sera plus capable de retrouver quel début correspond à quelle fin, mais ça on s’en fout, y’a rien qui ressemble plus à un intervalle qu’un autre intervalle.</p> <p>Imaginez un petit bonhomme (ou une petite bonne femme, respectons la parité). Au départ, il est au niveau du sol. Il avance vers la droite. Quand il rencontre un début d’intervalle, il monte sur un mur d’un étage. Quand il rencontre une fin, il descend d’un étage. Il peut être sur plusieurs étages superposés. Au fur et à mesure qu’il se déplace, on note les endroits où il se retrouve sur le sol. Ces endroits correspondent à des zones sans aucun intervalle. </p> <p><a href="http://sametmax.com/wp-content/uploads/2013/02/jill-of-the-jungle_3crop.png" class="grouped_elements" rel="tc-fancybox-group4572"><img src="http://sametmax.com/wp-content/uploads/2013/02/jill-of-the-jungle_3crop.png" alt="Je vous laisse retrouver de quel jeu vidéo est tiré ce screenshot. Je l'avais beaucoup aimé. Je trouvais l'univers très onirique, et très "compte de fée mais pas cucul, parce que y'a quand même dedans des aventures qui poutrent de la rascasse particulaire avec un chandelier dans la véranda."" title="Je vous laisse retrouver de quel jeu vidéo est tiré ce screenshot. Je l'avais beaucoup aimé. Je trouvais l'univers très onirique, et très "compte de fée mais pas cucul, parce que y'a quand même dedans des aventures qui poutrent de la rascasse particulaire avec un chandelier dans la véranda."" width="258" height="138" class="alignnone size-full wp-image-4582" /></a></p> <p><a href="http://sametmax.com/wp-content/uploads/2013/02/gfs_29955_2_14_mid.jpg" class="grouped_elements" rel="tc-fancybox-group4572"><img src="http://sametmax.com/wp-content/uploads/2013/02/gfs_29955_2_14_mid.jpg" alt="Mes parents n'arrêtaient pas de me dire que mes jeux se ressemblaient tous. Puis ils m'emmenaient visiter des églises et des châteaux qui se ressemblaient tous. Bizarre..." title="Mes parents n'arrêtaient pas de me dire que mes jeux se ressemblaient tous. Puis ils m'emmenaient visiter des églises et des châteaux qui se ressemblaient tous. Bizarre..." width="270" height="169" class="alignnone size-full wp-image-4583" /></a></p> <h3>Le code</h3> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> tri_bonhomme_sur_un_mur<span style="color: black;">(</span>list_intervalle_en_bordel<span style="color: black;">)</span>: <span style="color: #483d8b;">""" Effectue une union de tous les intervalles indiqués en paramètre. Données d'entrée : une liste de liste de deux éléments, représentant des intervalles. - Le type des éléments n'est pas imposé. Il faut juste qu'on puisse les ordonner et les trier. - Dans chaque liste de deux éléments, le premier doit être plus petit que le second. La fonction ne vérifie pas ces contraintes. Si elles ne sont pas respectées, le comportement est indéterminé. Ça peut planter, ça peut renvoyer un résultat faux sans avertissement, etc. Sortie : une liste de liste de deux éléments, unionnisée et triée comme il faut. """</span> <span style="color: #808080; font-style: italic;"># On extrait tous les débuts d'intervalles, et toutes les fins.</span> list_debut <span style="color: #66cc66;">=</span> <span style="color: black;">[</span> interv<span style="color: black;">[</span><span style="color: #ff4500;">0</span><span style="color: black;">]</span> <span style="color: #ff7700;font-weight:bold;">for</span> interv <span style="color: #ff7700;font-weight:bold;">in</span> list_intervalle_en_bordel <span style="color: black;">]</span> list_fin <span style="color: #66cc66;">=</span> <span style="color: black;">[</span> interv<span style="color: black;">[</span><span style="color: #ff4500;">1</span><span style="color: black;">]</span> <span style="color: #ff7700;font-weight:bold;">for</span> interv <span style="color: #ff7700;font-weight:bold;">in</span> list_intervalle_en_bordel <span style="color: black;">]</span> <span style="color: #808080; font-style: italic;"># On les trie, pour pouvoir les traiter de gauche à droite.</span> list_debut.<span style="color: black;">sort</span><span style="color: black;">(</span><span style="color: black;">)</span> list_fin.<span style="color: black;">sort</span><span style="color: black;">(</span><span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># Cette liste contiendra les intervalles unionnisés et triés.</span> list_intervalle_final <span style="color: #66cc66;">=</span> <span style="color: black;">[</span><span style="color: black;">]</span> <span style="color: #808080; font-style: italic;"># indique le nombre d'invervalle superposés dans lesquels on se trouve</span> <span style="color: #808080; font-style: italic;"># actuellement. (C'est à dire : le nombre d'étages sur lequel</span> <span style="color: #808080; font-style: italic;"># marche le bonhomme).</span> nb_superposition <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span> <span style="color: #808080; font-style: italic;"># Lorsqu'on est dans un ou plusieurs intervalles superposés, on doit</span> <span style="color: #808080; font-style: italic;"># se souvenir à quelle position on est entré dans le premier.</span> <span style="color: #808080; font-style: italic;"># Cela permettra de créer l'intervalle final, lorsqu'on sera </span> <span style="color: #808080; font-style: italic;"># complètement sorti de la superposition en cours.</span> debut_intervalle_courant <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span> <span style="color: #808080; font-style: italic;"># C'est parti ! Le petit bonhomme avance. On lui fait traiter les</span> <span style="color: #808080; font-style: italic;"># événements d'entrée et de sortie d'intervalle au fur et à mesure </span> <span style="color: #808080; font-style: italic;"># qu'ils arrivent.</span> <span style="color: #ff7700;font-weight:bold;">while</span> list_debut: <span style="color: #808080; font-style: italic;"># Le premier élément de list_debut, c'est le premier début </span> <span style="color: #808080; font-style: italic;"># d'intervalle qu'on rencontrera. Le premier élément de list_fin,</span> <span style="color: #808080; font-style: italic;"># c'est la première fin d'intervalle qu'on rencontrera. On </span> <span style="color: #808080; font-style: italic;"># détermine, parmi ces deux événements, lequel on rencontrera en </span> <span style="color: #808080; font-style: italic;"># tout premier.</span> <span style="color: #808080; font-style: italic;">#</span> <span style="color: #808080; font-style: italic;"># La fonction cmp renvoie -1, 0, ou 1, selon la comparaison </span> <span style="color: #808080; font-style: italic;"># effectuée entre les deux valeurs passées en paramètre.</span> <span style="color: #808080; font-style: italic;"># Faire un petit help(cmp) pour connaître les détails.</span> ordre_debut_fin <span style="color: #66cc66;">=</span> <span style="color: #008000;">cmp</span><span style="color: black;">(</span>list_debut<span style="color: black;">[</span><span style="color: #ff4500;">0</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> list_fin<span style="color: black;">[</span><span style="color: #ff4500;">0</span><span style="color: black;">]</span><span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">if</span> ordre_debut_fin <span style="color: #66cc66;">==</span> -<span style="color: #ff4500;">1</span>: <span style="color: #808080; font-style: italic;"># L'événement rencontré est un début d'intervalle.</span> <span style="color: #808080; font-style: italic;"># On enlève l'événement de la liste, puisqu'on va le traiter,</span> <span style="color: #808080; font-style: italic;"># là, tout de suite.</span> pos_debut <span style="color: #66cc66;">=</span> list_debut.<span style="color: black;">pop</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span><span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">if</span> nb_superposition <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span>: <span style="color: #808080; font-style: italic;"># On était dans aucun intervalle, et on vient d'en </span> <span style="color: #808080; font-style: italic;"># rencontrer un. Dans la liste finale d'intervalles, </span> <span style="color: #808080; font-style: italic;"># ça va donc compter comme un début. On retient </span> <span style="color: #808080; font-style: italic;"># cette info.</span> debut_intervalle_courant <span style="color: #66cc66;">=</span> pos_debut <span style="color: #808080; font-style: italic;"># Dans tous les cas, on ajoute une superposition d'intervalle</span> <span style="color: #808080; font-style: italic;"># (le bonhomme monte d'un étage).</span> nb_superposition +<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">elif</span> ordre_debut_fin <span style="color: #66cc66;">==</span> +<span style="color: #ff4500;">1</span>: <span style="color: #808080; font-style: italic;"># L'événement rencontré est une fin d'intervalle.</span> <span style="color: #808080; font-style: italic;"># On l'enlève de la liste.</span> pos_fin <span style="color: #66cc66;">=</span> list_fin.<span style="color: black;">pop</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span><span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># On enlève une superposition d'intervalle.</span> nb_superposition -<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">if</span> nb_superposition <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span>: <span style="color: #808080; font-style: italic;"># Après avoir enlevé la superposition, on se retrouve</span> <span style="color: #808080; font-style: italic;"># avec 0 intervalle superposé. </span> <span style="color: #808080; font-style: italic;"># (Le bonhomme est redescendu jusqu'au niveau du sol).</span> <span style="color: #808080; font-style: italic;"># Il faut donc enregistrer ça comme une fin d'intervalle </span> <span style="color: #808080; font-style: italic;"># final. Tant qu'on y est, on crée tout de suite ce nouvel</span> <span style="color: #808080; font-style: italic;"># intervalle final et on le met dans la liste.</span> nouvel_intervalle <span style="color: #66cc66;">=</span> <span style="color: black;">(</span>debut_intervalle_courant<span style="color: #66cc66;">,</span> pos_fin<span style="color: black;">)</span> list_intervalle_final.<span style="color: black;">append</span><span style="color: black;">(</span>nouvel_intervalle<span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">else</span>: <span style="color: #808080; font-style: italic;"># On rencontre à la fois un début et une fin d'intervalle.</span> <span style="color: #808080; font-style: italic;"># Rien de spécial à faire. Faut juste virer les 2 événements </span> <span style="color: #808080; font-style: italic;"># traités de leur liste respectives.</span> list_debut.<span style="color: black;">pop</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span><span style="color: black;">)</span> list_fin.<span style="color: black;">pop</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span><span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># Durant toute cette boucle, la variable nb_superposition augmente</span> <span style="color: #808080; font-style: italic;"># et diminue. Mais elle n'est jamais censée devenir négative.</span> <span style="color: #808080; font-style: italic;"># Si ça arrive, c'est que les données d'entrées sont mal foutues.</span> <span style="color: #808080; font-style: italic;"># On entre dans un cas d'indétermination. </span> <span style="color: #808080; font-style: italic;"># Arrivé à la fin de la boucle, il peut rester, ou pas des éléments</span> <span style="color: #808080; font-style: italic;"># dans list_fin. Ce qui est sûr, c'est que list_debut se vide</span> <span style="color: #808080; font-style: italic;"># avant list_fin. Si ce n'est pas le cas, c'est encore un cas</span> <span style="color: #808080; font-style: italic;"># d'indétermination.</span> <span style="color: #ff7700;font-weight:bold;">if</span> list_fin: <span style="color: #808080; font-style: italic;"># On a passé tous les débuts d'intervalle, mais il reste des</span> <span style="color: #808080; font-style: italic;"># fins. Ça veut dire qu'on est encore dans un ou plusieurs</span> <span style="color: #808080; font-style: italic;"># intervalles. On devrait normalement avoir :</span> <span style="color: #808080; font-style: italic;"># len(list_fin) == nb_superposition. Si c'est pas le cas, c'est</span> <span style="color: #808080; font-style: italic;"># un cas d'indétermination.</span> <span style="color: #808080; font-style: italic;">#</span> <span style="color: #808080; font-style: italic;"># On pourrait traiter les événements de fin d'intervalle un par un,</span> <span style="color: #808080; font-style: italic;"># et diminuer progressivement nb_superposition. Mais on s'en fout,</span> <span style="color: #808080; font-style: italic;"># c'est pas nécessaire. On prend juste la fin d'intervalle qui </span> <span style="color: #808080; font-style: italic;"># supprimera la dernière superposition (c'est à dire la dernière</span> <span style="color: #808080; font-style: italic;"># fin d'intervalle), et on construit un dernier intervalle final</span> <span style="color: #808080; font-style: italic;"># avec ça.</span> pos_fin <span style="color: #66cc66;">=</span> list_fin<span style="color: black;">[</span>-<span style="color: #ff4500;">1</span><span style="color: black;">]</span> nouvel_intervalle <span style="color: #66cc66;">=</span> <span style="color: black;">(</span>debut_intervalle_courant<span style="color: #66cc66;">,</span> pos_fin<span style="color: black;">)</span> list_intervalle_final.<span style="color: black;">append</span><span style="color: black;">(</span>nouvel_intervalle<span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">return</span> list_intervalle_final</pre></td></tr></table></div> <h3>Les avantages (parce que y’a aucun désavantages)</h3> <p>Ça marche avec des réels, des dates, et de manière générale, <a href="http://sametmax.com/ordonner-en-python/" target="_blank">tout ce qu’on peut trier</a>.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">>>></span>tri_bonhomme_sur_un_mur<span style="color: black;">(</span><span style="color: black;">[</span> <span style="color: black;">[</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">7</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">7</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">5</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span><span style="color: #ff4500;">9</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">10</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span><span style="color: #ff4500;">8</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">9</span><span style="color: black;">]</span> <span style="color: black;">]</span><span style="color: black;">)</span> <span style="color: black;">[</span><span style="color: black;">(</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">7</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">(</span><span style="color: #ff4500;">8</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">10</span><span style="color: black;">)</span><span style="color: black;">]</span> <span style="color: #808080; font-style: italic;"># Testez pas ça chez vous ! Ça prend trois plombes ! Mettez juste 1000.</span> <span style="color: #66cc66;">>>></span>tri_bonhomme_sur_un_mur<span style="color: black;">(</span> <span style="color: black;">[</span> <span style="color: black;">[</span><span style="color: #ff4500;">10</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">210</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">]</span> * <span style="color: #ff4500;">1000000</span> <span style="color: black;">)</span> <span style="color: black;">[</span><span style="color: black;">(</span><span style="color: #ff4500;">10</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">210</span><span style="color: black;">)</span><span style="color: black;">]</span> <span style="color: #808080; font-style: italic;"># Voyons voir ce que ça donne avec des réels </span> <span style="color: #808080; font-style: italic;"># (dont certains sont négatifs, tant qu'à faire).</span> <span style="color: #66cc66;">>>></span>tri_bonhomme_sur_un_mur<span style="color: black;">(</span><span style="color: black;">[</span> <span style="color: black;">[</span>-<span style="color: #ff4500;">7.2</span><span style="color: #66cc66;">,</span> -<span style="color: #ff4500;">6.9</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span>-<span style="color: #ff4500;">8.4</span><span style="color: #66cc66;">,</span> -<span style="color: #ff4500;">5.3</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span>-<span style="color: #ff4500;">10.5</span><span style="color: #66cc66;">,</span> -<span style="color: #ff4500;">5.25</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span>-<span style="color: #ff4500;">1.7</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0.01</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span><span style="color: #ff4500;">0.0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4.0</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span><span style="color: #ff4500;">12.125</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">13.9</span><span style="color: #66cc66;">,</span> <span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span><span style="color: #ff4500;">13.9</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">15.0</span><span style="color: black;">]</span><span style="color: black;">]</span><span style="color: black;">)</span> <span style="color: black;">[</span><span style="color: black;">(</span>-<span style="color: #ff4500;">10.5</span><span style="color: #66cc66;">,</span> -<span style="color: #ff4500;">5.25</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">(</span>-<span style="color: #ff4500;">1.7</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4.0</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">(</span><span style="color: #ff4500;">12.125</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">15.0</span><span style="color: black;">)</span><span style="color: black;">]</span> <span style="color: #808080; font-style: italic;"># et avec des dates</span> <span style="color: #66cc66;">>>></span><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">datetime</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">datetime</span> <span style="color: #66cc66;">>>></span>tri_bonhomme_sur_un_mur<span style="color: black;">(</span><span style="color: black;">[</span> <span style="color: black;">[</span><span style="color: #dc143c;">datetime</span><span style="color: black;">(</span><span style="color: #ff4500;">2012</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">12</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">21</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">16</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">54</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">datetime</span><span style="color: black;">(</span><span style="color: #ff4500;">2013</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">02</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">16</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">12</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">59</span><span style="color: black;">)</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">[</span><span style="color: #dc143c;">datetime</span><span style="color: black;">(</span><span style="color: #ff4500;">2013</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">02</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">14</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">datetime</span><span style="color: black;">(</span><span style="color: #ff4500;">2069</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">01</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">01</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">13</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">37</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">]</span> <span style="color: black;">]</span> <span style="color: black;">)</span> <span style="color: black;">[</span><span style="color: black;">(</span><span style="color: #dc143c;">datetime</span>.<span style="color: #dc143c;">datetime</span><span style="color: black;">(</span><span style="color: #ff4500;">2012</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">12</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">21</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">16</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">54</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">datetime</span>.<span style="color: #dc143c;">datetime</span><span style="color: black;">(</span><span style="color: #ff4500;">2069</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">13</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">37</span><span style="color: black;">)</span><span style="color: black;">)</span><span style="color: black;">]</span></pre></td></tr></table></div> <p>En ajoutant à peine 2-3 lignes de code à la fonction, on peut récupérer le nombre maximal d’intervalles superposés.</p> <p>En re-ajoutant quelques autres lignes, on peut récupérer les zones dans lesquelles ce maximum est atteint. Ce qui pourrait servir pour effectuer l’opération mathématique d’intersection. (Je vous laisse chercher ça par vous mêmes).</p> <p>L’algorithme est principalement constitué d’une bi-boucle, c’est à dire une boucle unique, qui avance dans deux listes différentes (je viens d’inventer ce terme, ne m’embêtez pas). C’est encore plus simple que deux boucles imbriquées. Le nombre d’itérations à effectuer est égal au nombre d’intervalle multiplié par deux, c’est tout. Dans tous les cas limites présentés ci-dessus, ça fait une solution acceptable, demandant un temps d’exécution peu pharaonique.</p> <p><a href="http://sametmax.com/wp-content/uploads/2013/02/resize.jpg" class="grouped_elements" rel="tc-fancybox-group4572"><img src="http://sametmax.com/wp-content/uploads/2013/02/resize.jpg" alt="Exemple de deux bi-boucles imbriquées au niveau de la vis. Cette image vous a été offerte par les Scissor Sisters." title="Exemple de deux bi-boucles imbriquées au niveau de la vis. Cette image vous a été offerte par les Scissor Sisters." width="370" height="370" class="alignnone size-full wp-image-4587" /></a></p> <h2>Mais ou est passé la complexité ?</h2> <p>Les premières solutions avaient l’air de demander énormément de temps d’exécution, surtout avec beaucoup d’intervalles en entrée. Ça ne semble pas être le cas pour la solution du “bonhomme sur un mur”. Pourtant, la complexité d’une tâche, ça ne disparaît pas comme par magie. Y’aurait-il une entourloupe quelque part ?</p> <p>Il y en a une. Ce sont les deux opérations de tri effectuées au début de la fonction. Un tri, ce n’est pas anodin, et son temps d’exécution peut augmenter très beaucoup et très vite. La complexité n’a pas disparue, on n’a fait que la déplacer vers des tris. Alors finalement, ma solution n’est pas si bien que ça ?</p> <p>Eh bien si. Parce que le tri, même s’il reste coûteux en temps et en ressource, est un problème archi-connu, archi-réglé, et archi-optimisé. Le python, comme beaucoup d’autres langages, profite pleinement du travail réalisé par des centaines de matheux algorithmologues, qui se sont masturbés l’esprit sur des centaines de méthodes de tri différentes.</p> <div id="attachment_4589" style="width: 510px" class="wp-caption alignnone"><a href="http://sametmax.com/wp-content/uploads/2013/02/P1060165-resize1.jpg" class="grouped_elements" rel="tc-fancybox-group4572"><img src="http://sametmax.com/wp-content/uploads/2013/02/P1060165-resize1.jpg" alt="Y'a des fois, on sait que l'image dont on a besoin ne sera pas trouvable sur l'internet. Alors on est obligé de la créer soi-même. (Mais je me suis fait aider)." title="Y'a des fois, on sait que l'image dont on a besoin ne sera pas trouvable sur l'internet. Alors on est obligé de la créer soi-même. (Mais je me suis fait aider)." width="500" height="375" class="size-full wp-image-4589" /></a><p class="wp-caption-text">Photo prise dans le bureau d'un chercheur en algorithmologie.</p></div> <p>C’est ça l’astuce générique dont je vous parlais au début. Face à un nouveau problème, le matheux <del datetime="2013-02-17T02:34:17+00:00">sort son zguègue</del> tente de trouver des équivalents à un ou plusieurs problèmes connus, que lui et ses amis matheux ont déjà réglés. C’est souvent bien plus simple que de tenter de régler le problème directement, en partant de rien. </p> <p><em>“Un nain éjacule bien plus loin lorsqu’il est perché sur les épaules d’un géant.”</em> Et pour respecter la parité, j’ajouterais qu’une naine femme-fontainise bien plus loin lorqu’elle est perchée sur les épaules d’une géante.</p> ]]></content:encoded> <wfw:commentRss>http://sametmax.com/union-dun-ensemble-dintervalles/feed/</wfw:commentRss> <slash:comments>15</slash:comments> <enclosure url="http://sametmax.com/wp-content/uploads/2013/02/intervillesinternational_06.jpg" length="52807" type="image/jpg" /> </item> <item> <title>Faire des enums en python 59</title> <link>http://sametmax.com/faire-des-enums-en-python/</link> <comments>http://sametmax.com/faire-des-enums-en-python/#comments</comments> <pubDate>Wed, 19 Dec 2012 17:41:10 +0000</pubDate> <dc:creator><![CDATA[recher]]></dc:creator> <category><![CDATA[Programmation]]></category> <category><![CDATA[animaux zoophiles]]></category> <category><![CDATA[bbw]]></category> <category><![CDATA[enum]]></category> <category><![CDATA[fesses]]></category> <category><![CDATA[python]]></category> <category><![CDATA[seins]]></category> <category><![CDATA[type]]></category> <guid isPermaLink="false">http://sametmax.com/?p=3741</guid> <description><![CDATA[Dans le C++, il existe quelque chose que j'avais trouvé bien sympa : les enums. Nous allons voir dans cet article comment créer des variables de ce type en python. Cet article comporte des nichons, des feux rouges et des chanteurs pas encore morts.]]></description> <content:encoded><![CDATA[<blockquote><p>Ceci est un post invité de <a href="http://recher.wordpress.com/" target="_blank">Réchèr </a>posté sous licence <a href="http://creativecommons.org/licenses/by/3.0/" target="_blank">creative common 3.0 unported</a>.</p></blockquote> <p><em>“Moi, je viens du C++”</em></p> <p>Voilà un propos qui fait classe. Ça donne un air de vieux de la vieille, à qui on ne la fait pas, et qui connaît des langages que c’est pas des langages de taffioles. “<em>De mon temps, fallait savoir ce qu’on faisait, sinon tout plantait. On ciselait notre code à la main dans des blocs de granit. Vous les gosses de maintenant, vous connaissez plus rien. Eh ! Sale jeune, au lieu d’importer des lib de feignasses, vient donc me changer ma poche à urine.</em>”</p> <p>Ça aurait été encore plus classe de dire que je viens de l’Assembleur, mais je suis pas assez vieux pour ça. Et de toutes façons, en vrai, je viens du Pascal. Bref, passons.</p> <p>Tout ça pour dire que dans le C++, il existe quelque chose que j’avais trouvé bien sympa : les enums.</p> <h3>Comment ça marche ?</h3> <p>Un enum est un type de variables ayant un domaine de valeur fixe et prédéfini, que l’on spécifie lors de la déclaration du type.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #000000; font-weight: bold;">enum</span> <span style="color: #009900;">{</span> Pique<span style="color: #339933;">,</span> Coeur<span style="color: #339933;">,</span> Trefle<span style="color: #339933;">,</span> Carreau <span style="color: #009900;">}</span> ECouleursCartes<span style="color: #339933;">;</span></pre></td></tr></table></div> <p>Ensuite, on peut déclarer une variable de ce type, et lui affecter l’une des valeurs autorisées.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="c" style="font-family:monospace;">ECouleursCartes vMaCouleurCarte<span style="color: #339933;">;</span> vMaCouleurCarte <span style="color: #339933;">=</span> Trefle<span style="color: #339933;">;</span></pre></td></tr></table></div> <p>Concrètement, chaque valeur correspond à un entier. Le compilateur fait les correspondances tout seul comme un grand.</p> <h3>À quoi ça sert ?</h3> <p>À avoir du code plus parlant quand on veut représenter des notions concrètes de la vraie vie, ou quand on implémente une machine à état. </p> <p>Par exemple, vous créez une classe <code>FeuCirculation</code>. Vous avez besoin d’une variable renseignant sa couleur. Vous pouvez utiliser un int à l’arrache, et noter en commentaire quelque part : “0 c’est rouge, 1 c’est vert, 2 c’est orange.”. Mais c’est chiant. Il faut toujours garder en tête les correspondances. On risque d’attribuer des valeurs non documentées. Bref, y’a n’importe quoi dedans et ça pue, (un peu comme une poche à urine).</p> <p>Avec un enum, tout est plus clair, aussi bien dans le code définissant la classe <code>FeuCirculation</code>, que dans le code qui l’utilise. Et c’est plus robuste.</p> <p>L’exemple qui est donné très souvent dans les tutoriaux, c’est un enum <code>Animal</code>, contenant les valeurs <code>chien, chat, bœuf musqué, ...</code> Ça fonctionne, mais personnellement cet exemple me gêne un peu. Chaque animal est un objet à part entière. Dans ce cas, il vaudrait mieux créer une classe générique <code>Animal</code>, et la faire hériter. Ce qui permettra ensuite de créer des méthodes telles que <code>manger(), crier(), péter(), ...</code></p> <p><a href="http://sametmax.com/faire-des-enums-en-python/fuck-a-duck/" rel="attachment wp-att-3744"><img src="http://sametmax.com/wp-content/uploads/2012/12/fuck-a-duck.jpg" class="grouped_elements" rel="tc-fancybox-group3741" alt="If it quacks like a duck, it may have noticed you are fucking it." title="If it quacks like a duck, it may have noticed you are fucking it." width="320" height="240" class="alignnone size-full wp-image-3744" /></a></p> <p>Pour décrire plusieurs objets, utilisez des classes. Pour décrire les différents états d’un même objet, utilisez un enum. Pour décrire plusieurs objets simples, utilisez l’un ou l’autre, c’est à vous de choisir.</p> <h3>Comment faire un enum en python ?</h3> <p>Il n’y a, à ma connaissance, pas de structure syntaxique dédiée. Mais c’est pas grave, on va bien trouver quelque chose.</p> <p>Le plus simple, pour commencer, c’est de garder l’idée de la correspondance avec des entiers. Ça offre plein d’avantages :</p> <ul> <li>On sait exactement comment ça marche à l’intérieur.</li> <li>On peut très facilement enregistrer des enums dans un fichier ou une base de donnée, puisque ce ne sont que des nombres.</li> <li>On peut ordonner les valeurs. À utiliser avec prudence, car ça n’a pas toujours de sens. (Dire que l’état “feu rouge” est inférieur à l’état “feu vert”, qu’est-ce que cela signifie exactement ?)</li> </ul> <p>La première idée qui vient à l’esprit, c’est de créer une classe avec les valeurs dedans, et de ne plus jamais les changer par la suite.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># On l'appelle FeuCirculation et non pas FeuRouge. </span> <span style="color: #808080; font-style: italic;"># Parce qu'un feu n'est pas forcément rouge.</span> <span style="color: #808080; font-style: italic;"># (Putain de langue française à la con qui fait n'importe quoi).</span> <span style="color: #ff7700;font-weight:bold;">class</span> FeuCirculation: ROUGE <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span> ORANGE <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span> VERT <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">2</span> ORANGE_CLIGNOTANT <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">3</span> TOUT_ETEINT <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">4</span> feuActuel <span style="color: #66cc66;">=</span> FeuCirculation.<span style="color: black;">ORANGE</span></pre></td></tr></table></div> <p>C’est bien, mais chiant à maintenir. Si on veut ajouter un autre état (par exemple, <code>FLECHE_DROITE_ORANGE_CLIGNOTANTE</code>), et qu’on se plante dans les valeurs numériques, il y a un risque d’avoir des doublons, et ça fiche tout en l’air.</p> <p>Voici un petit peu mieux :</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> FeuCirculation: <span style="color: black;">(</span>ROUGE<span style="color: #66cc66;">,</span> ORANGE<span style="color: #66cc66;">,</span> VERT<span style="color: #66cc66;">,</span> ORANGE_CLIGNOTANT<span style="color: #66cc66;">,</span> TOUT_ETEINT<span style="color: #66cc66;">,</span> <span style="color: black;">)</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">range</span><span style="color: black;">(</span><span style="color: #ff4500;">5</span><span style="color: black;">)</span></pre></td></tr></table></div> <p><code>range(5)</code> renvoie un tuple (0, 1, 2, 3, 4). Des entiers différents sont attribués aux valeurs de l’enum. Si on veut en rajouter une et qu’on oublie de remplacer <code>range(5)</code> par <code>range(6)</code>, ça va balancer une exception. Tout va bien.</p> <p>Au cas où vous demanderiez : “qu’est-ce qui m’empêche de redéfinir l’une des valeurs, à un autre endroit du code, et de foutre le bordel ?”, je répondrais <em>“We are all consenting adults here”</em>. (Se référer à la philosophie du python. Si besoin, ce sera l’occasion d’un autre article).</p> <p><a href="http://sametmax.com/wp-content/uploads/2012/12/Lexxxi_Luxe_Sapphire_Cotton_Candi_2394hsp_10.jpg" class="grouped_elements" rel="tc-fancybox-group3741"><img src="http://sametmax.com/wp-content/uploads/2012/12/Lexxxi_Luxe_Sapphire_Cotton_Candi_2394hsp_10.jpg" alt="Some consenting adults. (Je peux venir ?)" title="Some consenting adults. (Je peux venir ?)" width="375" height="250" class="alignnone size-full wp-image-3765" /></a></p> <h3>Le code est beau, mais pour débugger ?</h3> <p>C’est un peu lourdingue. Lorsqu’on fait <code>print feuActuel</code> (ou lorsqu’on tape directement <code>feuActuel</code> dans <a href="http://sametmax.com/debugger-en-python-les-bases-de-pdb/" target="_blank">une console pdb</a>), c’est une valeur numérique pas claire qui va s’afficher, au lieu d’un joli “ORANGE”, “ROUGE”, …</p> <p>Un petit dictionnaire de correspondance “valeur numérique” -> “nom à afficher” serait de bon aloi. Quelque chose de ce genre, à placer dans la définiton de la classe <code>FeuCirculation </code>:</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"> dictReverse <span style="color: #66cc66;">=</span> <span style="color: black;">{</span> ROUGE : <span style="color: #483d8b;">"ROUGE"</span><span style="color: #66cc66;">,</span> ORANGE : <span style="color: #483d8b;">"ORANGE"</span><span style="color: #66cc66;">,</span> VERT : <span style="color: #483d8b;">"VERT"</span><span style="color: #66cc66;">,</span> ORANGE_CLIGNOTANT : <span style="color: #483d8b;">"ORANGE_CLIGNOTANT"</span><span style="color: #66cc66;">,</span> TOUT_ETEINT : <span style="color: #483d8b;">"TOUT_ETEINT"</span><span style="color: #66cc66;">,</span> <span style="color: black;">}</span></pre></td></tr></table></div> <p>Fort bien. Mais n’est-ce pas un peu casse-couille ? Eh si. Des répétitions à la pelle, et dictReverse doit rester synchro avec les définitions des valeurs. C’est redevenu chiant à maintenir.</p> <p><a href="http://sametmax.com/wp-content/uploads/2012/12/dick_rivers2.jpg" class="grouped_elements" rel="tc-fancybox-group3741"><img src="http://sametmax.com/wp-content/uploads/2012/12/dick_rivers2.jpg" alt="Hey, je suis Dict-Reverse, et je suis chiant à maintenir. bi-boppe eu loulaaaa." title="Hey, je suis Dict-Reverse, et je suis chiant à maintenir. bi-boppe eu loulaaaa." width="240" height="333" class="alignnone size-full wp-image-3766" /></a></p> <h3>Définition dynamique de nouveaux types</h3> <p>Soyons franc, j’ai piqué cette astuce ici :<br /> <a href="http://stackoverflow.com/questions/36932/whats-the-best-way-to-implement-an-enum-in-python" target="_blank">http://stackoverflow.com/questions/36932/whats-the-best-way-to-implement-an-enum-in-python</a></p> <p>Vous connaissez certainement déjà la fonction native <code>type()</code>. Elle renvoie le type du truc passé en paramètre. Youpi.</p> <p>Mais saviez-vous qu’elle permet également de créer de nouveaux types ? Pour ce faire, il faut l’appeler avec 3 paramètres : </p> <ul> <li>Le nom.</li> <li>Une liste indiquant les types de base (dans le cas où on veut que le type soit hérité).</li> <li>Un dictionnaire contenant les attributs. Les clés sont des chaînes de caractère, et correspondront aux noms des attributs.</li> </ul> <p>La création de l’enum <code>FeuCirculation </code>pourrait donc se faire de cette manière :</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">FeuCirculation <span style="color: #66cc66;">=</span> <span style="color: #008000;">type</span><span style="color: black;">(</span> <span style="color: #483d8b;">"FeuCirculation"</span><span style="color: #66cc66;">,</span> <span style="color: black;">(</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">{</span> <span style="color: #483d8b;">"ROUGE"</span> : <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ORANGE"</span> : <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"VERT"</span> : <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ORANGE_CLIGNOTANT"</span> : <span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"TOUT_ETEINT"</span> : <span style="color: #ff4500;">4</span> <span style="color: black;">}</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> FeuCirculation <span style="color: #66cc66;"><</span><span style="color: #ff7700;font-weight:bold;">class</span> <span style="color: #483d8b;">'__main__.FeuCirculation'</span><span style="color: #66cc66;">></span> <span style="color: #66cc66;">>>></span> FeuCirculation.<span style="color: black;">VERT</span> <span style="color: #ff4500;">2</span></pre></td></tr></table></div> <p>On peut également ajouter le dictReverse dans le dictionnaire des attributs. (Ça fait un dictionnaire dans un dictionnaire, c’est lol).</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">FeuCirculation <span style="color: #66cc66;">=</span> <span style="color: #008000;">type</span><span style="color: black;">(</span> <span style="color: #483d8b;">"FeuCirculation"</span><span style="color: #66cc66;">,</span> <span style="color: black;">(</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">{</span> <span style="color: #483d8b;">"ROUGE"</span> : <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ORANGE"</span> : <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"VERT"</span> : <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ORANGE_CLIGNOTANT"</span> : <span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"TOUT_ETEINT"</span> : <span style="color: #ff4500;">4</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"dictReverse"</span> : <span style="color: black;">{</span> <span style="color: #ff4500;">0</span> : <span style="color: #483d8b;">"ROUGE"</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span> : <span style="color: #483d8b;">"ORANGE"</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span> : <span style="color: #483d8b;">"VERT"</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span> : <span style="color: #483d8b;">"ORANGE_CLIGNOTANT"</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span> : <span style="color: #483d8b;">"TOUT_ETEINT"</span><span style="color: black;">}</span> <span style="color: black;">}</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> FeuCirculation <span style="color: #66cc66;"><</span><span style="color: #ff7700;font-weight:bold;">class</span> <span style="color: #483d8b;">'__main__.FeuCirculation'</span><span style="color: #66cc66;">></span> <span style="color: #66cc66;">>>></span> feuxActuel <span style="color: #66cc66;">=</span> FeuCirculation.<span style="color: black;">VERT</span> <span style="color: #66cc66;">>>></span> feuxActuel <span style="color: #ff4500;">2</span> <span style="color: #66cc66;">>>></span> FeuCirculation.<span style="color: black;">dictReverse</span><span style="color: black;">[</span>feuxActuel<span style="color: black;">]</span> <span style="color: #483d8b;">'VERT'</span></pre></td></tr></table></div> <p>Et maintenant y’a plus qu’à coder une petite fonction qui fait tout ça génériquement.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> enum<span style="color: black;">(</span>enumName<span style="color: #66cc66;">,</span> *listValueNames<span style="color: black;">)</span>: <span style="color: #808080; font-style: italic;"># Une suite d'entiers, on en crée autant</span> <span style="color: #808080; font-style: italic;"># qu'il y a de valeurs dans l'enum.</span> listValueNumbers <span style="color: #66cc66;">=</span> <span style="color: #008000;">range</span><span style="color: black;">(</span><span style="color: #008000;">len</span><span style="color: black;">(</span>listValueNames<span style="color: black;">)</span><span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># création du dictionaire des attributs.</span> <span style="color: #808080; font-style: italic;"># Remplissage initial avec les correspondances : valeur d'enum -> entier</span> dictAttrib <span style="color: #66cc66;">=</span> <span style="color: #008000;">dict</span><span style="color: black;">(</span> <span style="color: #008000;">zip</span><span style="color: black;">(</span>listValueNames<span style="color: #66cc66;">,</span> listValueNumbers<span style="color: black;">)</span> <span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># création du dictionnaire inverse. entier -> valeur d'enum</span> dictReverse <span style="color: #66cc66;">=</span> <span style="color: #008000;">dict</span><span style="color: black;">(</span> <span style="color: #008000;">zip</span><span style="color: black;">(</span>listValueNumbers<span style="color: #66cc66;">,</span> listValueNames<span style="color: black;">)</span> <span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># ajout du dictionnaire inverse dans les attributs</span> dictAttrib<span style="color: black;">[</span><span style="color: #483d8b;">"dictReverse"</span><span style="color: black;">]</span> <span style="color: #66cc66;">=</span> dictReverse <span style="color: #808080; font-style: italic;"># création et renvoyage du type</span> mainType <span style="color: #66cc66;">=</span> <span style="color: #008000;">type</span><span style="color: black;">(</span>enumName<span style="color: #66cc66;">,</span> <span style="color: black;">(</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> dictAttrib<span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">return</span> mainType <span style="color: #66cc66;">>>></span> FeuCirculation <span style="color: #66cc66;">=</span> enum<span style="color: black;">(</span> <span style="color: #483d8b;">"FeuCirculation"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ROUGE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ORANGE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"VERT"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ORANGE_CLIGNOTANT"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"TOUT_ETEINT"</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> FeuCirculation.<span style="color: black;">TOUT_ETEINT</span> <span style="color: #ff4500;">4</span> <span style="color: #66cc66;">>>></span> FeuCirculation.<span style="color: black;">dictReverse</span><span style="color: black;">[</span>FeuCirculation.<span style="color: black;">TOUT_ETEINT</span><span style="color: black;">]</span> <span style="color: #483d8b;">'TOUT_ETEINT'</span></pre></td></tr></table></div> <p>Une petite précision : d’habitude, quand on crée des classes ou des types, c’est pour les instancier. Là on ne le fait pas, on se contente d’utiliser des valeurs statiques contenues dans le type. Vous pourriez faire <code>feuDuCarrefour = FeuCirculation()</code>. Ça va fonctionner, mais ça ne vous servira à rien.</p> <p><a href="http://sametmax.com/wp-content/uploads/2012/12/weird_stuff_cool_crazy_offbeat_traffic-light-tree-06_200907241442222897.jpg" class="grouped_elements" rel="tc-fancybox-group3741"><img src="http://sametmax.com/wp-content/uploads/2012/12/weird_stuff_cool_crazy_offbeat_traffic-light-tree-06_200907241442222897.jpg" alt="Le code de la route a parfois besoin de refactoring" title="Le code de la route a parfois besoin de refactoring" width="400" height="300" class="alignnone size-full wp-image-3767" /></a></p> <h3>Mais si on mélange les enums ?</h3> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">>>></span> FeuCirculation <span style="color: #66cc66;">=</span> enum<span style="color: black;">(</span> <span style="color: #483d8b;">"FeuCirculation"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ROUGE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ORANGE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"VERT"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ORANGE_CLIGNOTANT"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"TOUT_ETEINT"</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> etatMatiere <span style="color: #66cc66;">=</span> enum<span style="color: black;">(</span> <span style="color: #483d8b;">"etatMatiere"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"SOLIDE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"LIQUIDE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"GAZEUX"</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> etatMatiere.<span style="color: black;">dictReverse</span><span style="color: black;">[</span>FeuCirculation.<span style="color: black;">VERT</span><span style="color: black;">]</span> <span style="color: #483d8b;">'GAZEUX'</span></pre></td></tr></table></div> <p>Mince alors. Ça fait n’importe quoi, sans signaler aucune erreur. C’est normal. D’un enum à l’autre, on ne fait que manipuler des entiers, qui restent les mêmes. Les correspondances se font joyeusement, même si ça n’a aucun sens. Dans le même ordre d’idée : <code>FeuCirculation.ROUGE == etatMatiere.SOLIDE</code> renverra <code>True</code>, ce qui ne veut rien dire. Comment régler ce problème ?</p> <p><a href="http://sametmax.com/wp-content/uploads/2012/12/iced_traffic_lights.jpg" class="grouped_elements" rel="tc-fancybox-group3741"><img src="http://sametmax.com/wp-content/uploads/2012/12/iced_traffic_lights.jpg" alt="Better have traffic ice than traffic jam." title="Better have traffic ice than traffic jam." width="426" height="284" class="alignnone size-full wp-image-3772" /></a></p> <h3>Solution 1 : ne pas régler le problème</h3> <p><em>“We are all consenting adults here”</em>, on ne va donc pas compliquer le code en rajoutant des sécurités de partout, sous prétexte d’empêcher des erreurs. Le seule moyen valable de se prémunir de faire n’importe quoi quand on code, c’est tout bêtement de rester concentré et de faire gaffe à ce qu’on fait.</p> <p>Honnêtement, ça ne m’est jamais arrivé de mélanger des enums entre eux. Pourtant, je n’ai pas la prétention de tout faire juste et sans bugs du premier coup. Parmi mes bourdes préférées : copier-coller la ligne du dessus et ne pas faire les bons remplacements (les “x” par des “y”, les “1” par des “2”, etc.), ou encore : déclarer une fonction, lui faire renvoyer un résultat bidon parce que je préfère la coder plus tard, et oublier que je ne l’ai pas codé.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> calculDist<span style="color: black;">(</span>point1<span style="color: #66cc66;">,</span> point2<span style="color: black;">)</span>: distX <span style="color: #66cc66;">=</span> point1.<span style="color: black;">x</span> - point1.<span style="color: black;">x</span> distY <span style="color: #66cc66;">=</span> point2.<span style="color: black;">x</span> - point2.<span style="color: black;">x</span> <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">math</span>.<span style="color: black;">sqrt</span><span style="color: black;">(</span>distX * distX + distY * distY<span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># ami lecteur, sauras-tu trouver tous les fails</span> <span style="color: #808080; font-style: italic;"># présents dans cette fonction ?</span> <span style="color: #ff7700;font-weight:bold;">def</span> RemoveDoubleLetters<span style="color: black;">(</span>strValue<span style="color: black;">)</span>: <span style="color: #808080; font-style: italic;"># TODO : coder le truc. Mais là, j'ai la flemme.</span> <span style="color: #ff7700;font-weight:bold;">return</span> strValue</pre></td></tr></table></div> <p><a href="http://sametmax.com/wp-content/uploads/2012/12/bsod.jpg" class="grouped_elements" rel="tc-fancybox-group3741"><img src="http://sametmax.com/wp-content/uploads/2012/12/bsod.jpg" alt="BSOD !!" title="BSOD !!" width="351" height="461" class="alignnone size-full wp-image-3773" /></a></p> <p>Pour limiter les risques de mélange, voici quelques conseils :</p> <ul> <li>Préfixez les variables contenant une valeur d’enum : <code>feu</code> pour <code>FeuCirculation</code>, <code>emat</code> pour <code>etatMatiere</code>, etc. De cette manière, les erreurs de code sautent aux yeux. (<a href="http://www.joelonsoftware.com/articles/Wrong.html" target="_blank">making wrong code look wrong</a>, tout ça…) </li> <li>Il est important de ne pas polluer inutilement l’espace de nommage. Dans un fichier donné, n’importez pas les enums dont vous n’avez pas besoin. De cette manière, une erreur sera renvoyée si jamais vous utilisez une valeur d’enum imprévue. Je doute que vous ayez besoin, dans un même fichier de code, de renseigner des états de feux rouge et des états de matière. </li> <li>Si vous faites exprès de mélanger des enums, en pensant que vous n’avez aucun moyen de faire autrement, c’est qu’il y a, dès l’origine, un problème de conception dans votre code.</li> </ul> <p><a href="http://sametmax.com/wp-content/uploads/2012/12/cabrel.jpg" class="grouped_elements" rel="tc-fancybox-group3741"><img src="http://sametmax.com/wp-content/uploads/2012/12/cabrel.jpg" alt="Vieng fayre toi-même leu mélainge des enums, sur les muuuurs deu la cabaneu du côdeur. Vieng t'assouar." title="Vieng fayre toi-même leu mélainge des enums, sur les muuuurs deu la cabaneu du côdeur. Vieng t'assouar." width="350" height="238" class="alignnone size-full wp-image-3774" /></a></p> <h3>Solution 2 : des enums fortement typés.</h3> <p>Au lieu que les valeurs internes des enums soient de simples entiers, on crée un type pour chacune d’elle. Comme ça, on est sûr que ça renverra une erreur si on se confusionne. Par contre, on perd en simplicité, et ce n’est plus aussi simple pour la sérialisation.</p> <p>Soyons fous, et voyons ce que ça donne !</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> strongTypedEnum<span style="color: black;">(</span>enumName<span style="color: #66cc66;">,</span> *listValueNames<span style="color: black;">)</span>: <span style="color: #808080; font-style: italic;"># création d'une liste de type. sans attribut, sans héritage.</span> <span style="color: #808080; font-style: italic;"># le nom du type est composé du nom de l'enum et du nom de la valeur,</span> <span style="color: #808080; font-style: italic;"># séparés par un point.</span> listValueTyped <span style="color: #66cc66;">=</span> <span style="color: black;">[</span> <span style="color: #008000;">type</span><span style="color: black;">(</span><span style="color: #483d8b;">"."</span>.<span style="color: black;">join</span><span style="color: black;">(</span><span style="color: black;">(</span>enumName<span style="color: #66cc66;">,</span> nameValue<span style="color: black;">)</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">(</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">{</span><span style="color: black;">}</span><span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">for</span> nameValue <span style="color: #ff7700;font-weight:bold;">in</span> listValueNames <span style="color: black;">]</span> <span style="color: #808080; font-style: italic;"># Ensuite, c'est tout pareil que la fonction d'avant.</span> dictAttrib <span style="color: #66cc66;">=</span> <span style="color: #008000;">dict</span><span style="color: black;">(</span> <span style="color: #008000;">zip</span><span style="color: black;">(</span>listValueNames<span style="color: #66cc66;">,</span> listValueTyped<span style="color: black;">)</span> <span style="color: black;">)</span> dictReverse <span style="color: #66cc66;">=</span> <span style="color: #008000;">dict</span><span style="color: black;">(</span> <span style="color: #008000;">zip</span><span style="color: black;">(</span>listValueTyped<span style="color: #66cc66;">,</span> listValueNames<span style="color: black;">)</span> <span style="color: black;">)</span> dictAttrib<span style="color: black;">[</span><span style="color: #483d8b;">"dictReverse"</span><span style="color: black;">]</span> <span style="color: #66cc66;">=</span> dictReverse mainType <span style="color: #66cc66;">=</span> <span style="color: #008000;">type</span><span style="color: black;">(</span>enumName<span style="color: #66cc66;">,</span> <span style="color: black;">(</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> dictAttrib<span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">return</span> mainType <span style="color: #66cc66;">>>></span> FeuCirculation <span style="color: #66cc66;">=</span> strongTypedEnum<span style="color: black;">(</span><span style="color: #483d8b;">"FeuCirculation"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ROUGE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ORANGE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"VERT"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"ORANGE_CLIGNOTANT"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"TOUT_ETEINT"</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> etatMatiere <span style="color: #66cc66;">=</span> strongTypedEnum<span style="color: black;">(</span> <span style="color: #483d8b;">"etatMatiere"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"SOLIDE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"LIQUIDE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"GAZEUX"</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> etatMatiere.<span style="color: black;">LIQUIDE</span> <span style="color: #66cc66;"><</span><span style="color: #ff7700;font-weight:bold;">class</span> <span style="color: #483d8b;">'__main__.etatMatiere.LIQUIDE'</span><span style="color: #66cc66;">></span> <span style="color: #66cc66;">>>></span> etatMatiere.<span style="color: black;">dictReverse</span><span style="color: black;">[</span>FeuCirculation.<span style="color: black;">ROUGE</span><span style="color: black;">]</span> Traceback <span style="color: black;">(</span>most recent call last<span style="color: black;">)</span>: File <span style="color: #483d8b;">"<pyshell#20>"</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;"><</span>module<span style="color: #66cc66;">></span> etatMatiere.<span style="color: black;">dictReverse</span><span style="color: black;">[</span>FeuCirculation.<span style="color: black;">ROUGE</span><span style="color: black;">]</span> <span style="color: #008000;">KeyError</span>: <span style="color: #66cc66;"><</span><span style="color: #ff7700;font-weight:bold;">class</span> <span style="color: #483d8b;">'__main__.FeuCirculation.ROUGE'</span><span style="color: #66cc66;">></span></pre></td></tr></table></div> <p>Mais est-ce bien nécessaire ?</p> <h3>Y’a une lib pour ça</h3> <p>Comme toujours, avec cette foutue prolifération de code libre, dès que quelque chose de cool peut potentiellement exister, un connard de geek l’a déjà fait, vous privant de l’occasion de le faire vous-même et de retirer la gloire qui en décombe. <a href="http://packages.python.org/flufl.enum/README.html" target="_blank">La lib flufl.enum</a> permet donc de créer et manipuler des enums, avec autant et même plus de fonctionnalités que ce que je viens de décrire ici. (Connards de geeks qui viennent manger le pain des français).</p> <p>Par contre, j’ai regardé le code, et j’ai pas pigé comment ça fonctionnait à l’intérieur. Ça fera peut-être l’objet d’un autre article, si j’ai le courage de me plonger dedans, et que je trouve ça intéressant et rigolo.</p> <p>De toutes façons, les libs c’est chiant, ça ajoute des dépendances, <a href="http://sametmax.com/vous-en-pensez-quoi-de-cette-idee/" target="_blank">il vaut mieux tout coder à la main</a>.</p> <h3>Disgression 1 : quelle classe ce type !</h3> <p>Déclarer un type avec la fonction <code>type()</code>, et déclarer une classe, ça ne fait pas exactement la même chose.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">>>></span> <span style="color: #ff7700;font-weight:bold;">class</span> MaClasse: <span style="color: #ff7700;font-weight:bold;">pass</span> <span style="color: #66cc66;">>>></span> MaClasse <span style="color: #66cc66;"><</span><span style="color: #ff7700;font-weight:bold;">class</span> <span style="color: #dc143c;">__main__</span>.<span style="color: black;">MaClasse</span> at <span style="color: #ff4500;">0x011CB270</span><span style="color: #66cc66;">></span> <span style="color: #66cc66;">>>></span> instanceClasse <span style="color: #66cc66;">=</span> MaClasse<span style="color: black;">(</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> instanceClasse <span style="color: #66cc66;"><</span><span style="color: #dc143c;">__main__</span>.<span style="color: black;">MaClasse</span> instance at <span style="color: #ff4500;">0x011C8BC0</span><span style="color: #66cc66;">></span> <span style="color: #66cc66;">>>></span> MonType <span style="color: #66cc66;">=</span> <span style="color: #008000;">type</span><span style="color: black;">(</span><span style="color: #483d8b;">"Le_Nom_De_Mon_Type"</span><span style="color: #66cc66;">,</span> <span style="color: black;">(</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">{</span><span style="color: black;">}</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> MonType <span style="color: #66cc66;"><</span><span style="color: #ff7700;font-weight:bold;">class</span> <span style="color: #483d8b;">'__main__.Le_Nom_De_Mon_Type'</span><span style="color: #66cc66;">></span> <span style="color: #808080; font-style: italic;"># Hey ! Le nom est dans une string, et y'a pas d'adresse mémoire !</span> <span style="color: #66cc66;">>>></span> instanceType <span style="color: #66cc66;">=</span> MonType<span style="color: black;">(</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> instanceType <span style="color: #66cc66;"><</span><span style="color: #dc143c;">__main__</span>.<span style="color: black;">Le_Nom_De_Mon_Type</span> <span style="color: #008000;">object</span> at <span style="color: #ff4500;">0x011C1B30</span><span style="color: #66cc66;">></span> <span style="color: #808080; font-style: italic;"># Hey ! C'est un object, et pas une instance !</span></pre></td></tr></table></div> <p>Ça a peut-être quelque chose à voir avec une histoire de old-style class et new-style class. J’ai pas cherché plus loin pour l’instant. Ça fera peut-être l’objet d’un autre-autre article, si j’ai le courage de me plonger dedans, et que je trouve ça intéressant et rigolo.</p> <h3>Disgression 2 : Restons dans les règles</h3> <p>J’avais trouvé un autre exemple de machine à état, plus rigolo que des feux de circulation ou de la matière. Je ne m’en suis pas servi durant mes explications, parce que ça aurait distrait le lecteur / la lectrice (<a href="http://sametmax.com/bien-expliquer-quelque-chose-les-regles-de-base/" target="_blank">charge cérébrale</a>, tout ça…). Mais ce serait vraiment dommage de ne pas vous en faire profiter. Le voici donc :</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">>>></span> PhaseCycleUterin <span style="color: #66cc66;">=</span> enum<span style="color: black;">(</span> <span style="color: #483d8b;">"PhaseCycleUterin"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"PREPUBERE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"MENSTRUELLE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"OVULATION"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"PROLIPERATIVE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"SECRETRICE"</span> <span style="color: #483d8b;">"ENCEINTE"</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">"MENOPAUSE"</span><span style="color: black;">)</span> <span style="color: #66cc66;">>>></span> etatMatiere.<span style="color: black;">dictReverse</span><span style="color: black;">[</span>PhaseCycleUterin.<span style="color: black;">MENSTRUELLE</span><span style="color: black;">]</span> <span style="color: #483d8b;">'LIQUIDE'</span></pre></td></tr></table></div> <p>Voilà, ce sera tout pour aujourd’hui. La prochaine fois, nous redéfinirons le type “object” en utilisant uniquement les picots du langage Braille.</p> <p><a href="http://sametmax.com/wp-content/uploads/2012/12/femme_avec_regles.jpg" class="grouped_elements" rel="tc-fancybox-group3741"><img src="http://sametmax.com/wp-content/uploads/2012/12/femme_avec_regles.jpg" alt="Une femme qui a ses règles." title="Une femme qui a ses règles." width="470" height="671" class="alignnone size-full wp-image-3775" /></a></p> ]]></content:encoded> <wfw:commentRss>http://sametmax.com/faire-des-enums-en-python/feed/</wfw:commentRss> <slash:comments>59</slash:comments> <enclosure url="http://sametmax.com/wp-content/uploads/2012/12/numismate.jpg" length="48256" type="image/jpg" /> </item> <item> <title>id(), None et bidouilleries mémoire en python. 20</title> <link>http://sametmax.com/id-none-et-bidouilleries-memoire-en-python/</link> <comments>http://sametmax.com/id-none-et-bidouilleries-memoire-en-python/#comments</comments> <pubDate>Sat, 10 Nov 2012 17:37:54 +0000</pubDate> <dc:creator><![CDATA[recher]]></dc:creator> <category><![CDATA[Programmation]]></category> <category><![CDATA[fesse]]></category> <category><![CDATA[id]]></category> <category><![CDATA[is]]></category> <category><![CDATA[None]]></category> <category><![CDATA[nsfw]]></category> <category><![CDATA[python]]></category> <guid isPermaLink="false">http://sametmax.com/?p=2947</guid> <description><![CDATA[Mon maître-ninja python, entre deux riffs sur sa contrebasse électrique, m'avait un jour dit : "il ne faut pas écrire if a == None:, mais if a is None:". Il m'avait ensuite donné une justification pertinente, que je n'ai pas retenue, car j'étais en train de penser à des nichons. Puis il avait conclu par "on n'est pas égal au vide. On EST le vide." Rien que pour vous, ainsi que pour m'auto-déculpabiliser de penser souvent à des nichons, j'ai parcouru l'internet entier à dos de souris et j'ai retrouvé la justification. Mais avant de vous la livrer, quelques explications préliminaires.]]></description> <content:encoded><![CDATA[<blockquote><p><em>Ceci est un post invité de <a href="http://recher.wordpress.com" target="_blank">Réchèr</a> posté sous licence <a href="http://creativecommons.org/licenses/by/3.0/">creative common 3.0 unported</a>.</em></p></blockquote> <p>Mon maître-ninja python, entre deux riffs sur sa contrebasse électrique, m’avait un jour dit : “il ne faut pas écrire <code>if a == None:</code>, mais <code>if a is None:</code>“. Il m’avait ensuite donné une justification pertinente, que je n’ai pas retenue, car j’étais en train de penser à des nichons. Puis il avait conclu par “on n’est pas égal au vide. On <em>EST</em> le vide.”</p> <p>Rien que pour vous, ainsi que pour m’auto-déculpabiliser de penser souvent à des nichons, j’ai parcouru l’internet entier à dos de souris et j’ai retrouvé la justification. Mais avant de vous la livrer, quelques explications préliminaires.</p> <h3>On n’a pas de pétrole, mais on a des id()</h3> <p><a title="Et quand on n'a pas d'id, on a des fix !" href="http://sametmax.com/wp-content/uploads/2012/11/idfix2.jpg" class="grouped_elements" rel="tc-fancybox-group2947"><img class="size-full wp-image-2968" src="http://sametmax.com/wp-content/uploads/2012/11/idfix2.jpg" alt="Et quand on n'a pas d'id, on a des fix !" width="124" height="150" /></a></p> <p>La fonction <code>id()</code>, présente dans <code>__builtins__</code>, renvoie un entier, représentant l’identifiant interne de n’importe quel objet, quel que soit son type. Concrètement, il s’agit de l’adresse mémoire dans laquelle il est stocké. Jouons un peu avec.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» a <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>a<span style="color: black;">)</span> <span style="color: #ff4500;">19846928</span> »» b <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">"plop"</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>b<span style="color: black;">)</span> <span style="color: #ff4500;">33984800</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #ff4500;">2</span><span style="color: black;">)</span> <span style="color: #ff4500;">19846916</span></pre></td></tr></table></div> <p>Si vous faites cela chez vous, vous n’obtiendrez certainement pas les mêmes nombres. Ce qui est important à repérer, c’est que dans ce premier exemple, tous les id sont différents. Au passage, vous remarquerez que même les constantes ont un id. Je ne sais pas exactement comment cela fonctionne en interne, mais je suppose que lorsqu’on écrit le chiffre 2, on oblige le python à stocker cette valeur dans une sorte de monde magique contenant tout ce qui a été utilisé depuis le début de l’exécution, même si certaines de ces valeurs ne sont plus référencées nul part.</p> <p>Il est parfois intéressant de vérifier que deux id sont égaux ou différents. Mais vous ne pouvez pas faire grand chose de plus. Les caractères de la chaîne “plop” sont, à priori, stockés les uns à la suite des autres, dans une seule zone mémoire (tous les langages de programmation gèrent les strings de cette manière), mais vous ne pouvez pas mettre ce fait en évidence.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» <span style="color: #008000;">id</span><span style="color: black;">(</span>b<span style="color: black;">[</span><span style="color: #ff4500;">0</span><span style="color: black;">]</span><span style="color: black;">)</span> <span style="color: #ff4500;">19483368</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>b<span style="color: black;">[</span><span style="color: #ff4500;">1</span><span style="color: black;">]</span><span style="color: black;">)</span> <span style="color: #ff4500;">19989736</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>b<span style="color: black;">[</span><span style="color: #ff4500;">2</span><span style="color: black;">]</span><span style="color: black;">)</span> <span style="color: #ff4500;">19989760</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>b<span style="color: black;">[</span><span style="color: #ff4500;">0</span>:<span style="color: #ff4500;">2</span><span style="color: black;">]</span><span style="color: black;">)</span> <span style="color: #ff4500;">31983736</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>b<span style="color: black;">[</span><span style="color: #ff4500;">1</span>:<span style="color: #ff4500;">3</span><span style="color: black;">]</span><span style="color: black;">)</span> <span style="color: #ff4500;">31983424</span></pre></td></tr></table></div> <p>Les adresses ne se suivent pas, et ne sont même pas rangées dans l’ordre croissant. Ce n’est pas vraiment exploitable. En revanche, il y a quelque chose de rigolo à constater :</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» c <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">"pouet"</span> »» d <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">"pouet"</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>c<span style="color: black;">)</span> <span style="color: #ff4500;">33984768</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>d<span style="color: black;">)</span> <span style="color: #ff4500;">33984768</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #483d8b;">"pouet"</span><span style="color: black;">)</span> <span style="color: #ff4500;">33984768</span></pre></td></tr></table></div> <p>On a deux variables différentes, contenant la même chose, et elles pointent sur la même adresse mémoire. Mais alors, si je modifie c, ça va aussi modifier d ! Ohlala, Comment le python va faire ? Rassurez-vous, il s’en sort.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» c +<span style="color: #66cc66;">=</span> <span style="color: #483d8b;">"a"</span> »» c <span style="color: #483d8b;">'poueta'</span> »» d <span style="color: #483d8b;">'pouet'</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>c<span style="color: black;">)</span> <span style="color: #ff4500;">33855904</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>d<span style="color: black;">)</span> <span style="color: #ff4500;">33984768</span></pre></td></tr></table></div> <p>Le type string est immutable (ndm aussi: “immuable”). Cela signifie que vous ne pouvez rien changer dedans. Tout ce que vous pouvez faire, c’est réaffecter des variables (à une autre string, à n’importe quoi, …). Dans cet exemple, la réaffectation de c l’a fait pointer sur une autre zone de la mémoire. Mais sinon, la variable d n’a pas changé, ni son pointage, ni le contenu de ce qui est pointé. Ouf !!</p> <p><a title="Je te fais "pouet-pouet", tu me fais "pouet-pouet" ..." href="http://sametmax.com/wp-content/uploads/2012/11/schema1.png" class="grouped_elements" rel="tc-fancybox-group2947"><img class="alignnone wp-image-2995" src="http://sametmax.com/wp-content/uploads/2012/11/schema1.png" alt="Je te fais "pouet-pouet", tu me fais "pouet-pouet" ..." width="160" height="296" /></a></p> <p>Au passage, je rappelle que toutes les fonctions de traitement de chaîne de caractères (replace(), upper(), strip(), …) ne font jamais la modification “sur place”. Elles renvoient la valeur sous forme d’une nouvelle string. Si vous voulez modifier sur place, vous êtes obligés de faire une réaffectation explicite. Quelque chose comme : <code>c = c.upper()</code></p> <h3>Bidouilleries optimisatoires internes</h3> <p><a title="Je sens que vous redemandez encore du jeu de mots pourri. So, here comze da None !" href="http://sametmax.com/wp-content/uploads/2012/11/danone1742762776.jpg" class="grouped_elements" rel="tc-fancybox-group2947"><img class="alignnone wp-image-2974" src="http://sametmax.com/wp-content/uploads/2012/11/danone1742762776.jpg" alt="Je sens que vous redemandez encore du jeu de mots pourri. So, here comze da None !" width="281" height="180" /></a></p> <p>Le fait qu’un objet soit immutable n’oblige pas le python à créer une seule zone mémoire par valeur. Dans l’exemple précédent, lorsque j’ai affecté les variables c et d à “pouet”, leurs id auraient pu être différentes dès le départ, et les zones mémoires pointées auraient toutes les deux contenues “pouet”. Il se trouve que le python les a mises en commun, par souci d’optimisation. Cependant, je ne suis pas sûr que cette technique soit appliquée par tous les interpréteurs, toutes les versions, et dans tous les contextes. Mais “chez moi, ça marche”.</p> <p>Cette optimisation est également effectuée pour les valeurs booléennes et les valeurs numériques entières. Mais pas pour les floats, alors qu’à ma connaissance, ils sont eux aussi immutables.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #008000;">True</span><span style="color: black;">)</span> <span style="color: #ff4500;">505281316</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #008000;">True</span><span style="color: black;">)</span> <span style="color: #ff4500;">505281316</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #008000;">False</span><span style="color: black;">)</span> <span style="color: #ff4500;">505280988</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #008000;">False</span><span style="color: black;">)</span> <span style="color: #ff4500;">505280988</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #ff4500;">10</span><span style="color: black;">)</span> <span style="color: #ff4500;">19846820</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #ff4500;">10</span><span style="color: black;">)</span> <span style="color: #ff4500;">19846820</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #ff4500;">10.0</span><span style="color: black;">)</span> <span style="color: #ff4500;">19879104</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #ff4500;">10.0</span><span style="color: black;">)</span> <span style="color: #ff4500;">31338664</span> <span style="color: #808080; font-style: italic;"># Refaites des id(10.0), et vous aurez encore d'autres valeurs différentes.</span> <span style="color: #808080; font-style: italic;"># Mais peut-être pas à chaque fois. On ne peut pas le prévoir.</span></pre></td></tr></table></div> <p>En revanche, l’optimisation de la valeur None est garantie, quel que soit votre python et son contexte. <strong>Il n’y a toujours qu’une et une seule instance de None dans une exécution de python.</strong> Je n’ai pas trouvé d’annonce officielle concernant cette garantie, mais ça se dit un peu partout sur les forums. (Et si c’est sur internet, c’est forcément vrai).</p> <p>Jouons un peu avec la singletonitude du None.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» <span style="color: #008000;">id</span><span style="color: black;">(</span><span style="color: #008000;">None</span><span style="color: black;">)</span> <span style="color: #ff4500;">505255972</span> »» z <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span> »» <span style="color: #008000;">id</span><span style="color: black;">(</span>z<span style="color: black;">)</span> <span style="color: #ff4500;">505255972</span> »» zzzz <span style="color: #66cc66;">=</span> <span style="color: black;">[</span><span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: black;">]</span> * <span style="color: #ff4500;">30</span> »» zzzz <span style="color: black;">[</span><span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: black;">]</span> »» <span style="color: black;">[</span> <span style="color: #008000;">id</span><span style="color: black;">(</span>elem<span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">for</span> elem <span style="color: #ff7700;font-weight:bold;">in</span> zzzz <span style="color: black;">]</span> <span style="color: black;">[</span><span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">505255972</span><span style="color: black;">]</span></pre></td></tr></table></div> <p>Disgression : les mot-clés True et False peuvent être réaffectés. Mais pas le mot-clé None. Mais je m’égare. Revenons à nos agneaux, comme dirait Hannibal Lecter.</p> <h3>noir is noir. (Il n’y a plus d’ayspouuaaaarr).</h3> <p><a title=""Mmmmppff... psshhhh..." (#000000 Vador)" href="http://sametmax.com/wp-content/uploads/2012/11/joy-toy-2248596-star-wars.jpg" class="grouped_elements" rel="tc-fancybox-group2947"><img class="alignnone size-full wp-image-2975" src="http://sametmax.com/wp-content/uploads/2012/11/joy-toy-2248596-star-wars.jpg" alt=""Mmmmppff... psshhhh..." (#000000 Vador)" width="110" height="110" /></a></p> <p>Laissez-moi maintenant vous introduire (schlorrp) l’opérateur <code>is</code>. Il est présent nativement dans le python, et permet de comparer les id de deux objets. <code>A is B</code> renvoie un booléen, le même que celui que renverrait <code>id(A) == id(B)</code>.</p> <p>A quoi cela pourrait-il donc servir ? Eh bien … De même que la fonction <code>id</code> ne sert pas à grand chose, <code>is</code> est, lui aussi, d’une utilité discutable. Mais attendez, ne partez pas tout de suite.</p> <p>L’opérateur <code>is</code> est vraiment tout simple. Il ne peut pas être surchargé, et fait toujours la même chose quel que soit les opérandes : une comparaison d’id.</p> <p>L’opérateur <code>==</code> a l’air tout bête, vu comme ça, mais il peut être surchargé, et il effectue une suite d’actions pas forcément triviales. Il appelle la fonction <code>__eq__</code> si elle existe, sinon il essaie avec la fonction <code>__cmp__</code>, et peut-être encore d’autres choses que je ne détaillerai pas ici, parce que je ne me suis pas renseigné en détail sur le sujet. (Faut que je conserve une partie de mon temps pour le pensage à des nichons, vous comprenez bien).</p> <p>En règle générale, dès que c’est possible, il vaut mieux utiliser un truc simple plutôt qu’un truc compliqué. Malheureusement, comme on ne maîtrise pas vraiment la façon dont les id sont gérés et optimisés, l’utilisation du <code>is</code> serait trop risquée. Sauf dans un cas bien identifié. Devinez lequel ?</p> <p>Le None, qui n’a toujours qu’une et une seule id ! Joie ! Noël !</p> <p>Au fait, pendant qu’on y est, ne pourrait-on pas utiliser <code>is</code> avec les valeurs True et False ? A priori, ces deux valeurs sont gérées de la même manière que le None ?</p> <p>Certes, mais pour les booléens, on a encore plus simple. Au lieu de tester <code>if A is True:</code> ou <code>if A == True:</code>, on peut directement tester <code>if A:</code>. Pour False, on teste <code>if not A:</code>. Voili voilà.</p> <h3>Le béni oui-oui</h3> <p><a title="Un béni oui-oui !" href="http://sametmax.com/wp-content/uploads/2012/11/beni-oui-oui.jpg" class="grouped_elements" rel="tc-fancybox-group2947"><img class="alignnone wp-image-2976" src="http://sametmax.com/wp-content/uploads/2012/11/beni-oui-oui.jpg" alt="Un béni oui-oui !" width="222" height="202" /></a></p> <p>Pour finir, une petite justification supplémentaire, que je n’ai jamais rencontré dans la vraie vie, mais on va faire comme si.</p> <p>Alors voilà, vous êtes quelqu’un de bizarre, et vous avez besoin d’une classe qui est égale à tout. Donc vous surchargez la fonction <code>__eq__</code>.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» <span style="color: #ff7700;font-weight:bold;">class</span> BeniOuiOui: <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__eq__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> other<span style="color: black;">)</span>: <span style="color: #808080; font-style: italic;"># Je suis une classe magique, qui est égale à tout ce qui existe !</span> <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span> »» beniOuiOui <span style="color: #66cc66;">=</span> BeniOuiOui<span style="color: black;">(</span><span style="color: black;">)</span></pre></td></tr></table></div> <p>Un peu plus loin dans le code, vous avez une variable, récupérée d’on ne sait trop où, et vous voulez savoir si c’est None, ou si c’est une instance de béni-oui-oui. Pour faire cela, vous êtes obligés d’utiliser <code>is</code>, car <code>==</code> vous répondrait systématiquement True.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» beniOuiOui <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">2</span> <span style="color: #008000;">True</span> »» beniOuiOui <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">"n'importe quoi"</span> <span style="color: #008000;">True</span> »» beniOuiOui <span style="color: #66cc66;">==</span> <span style="color: #008000;">None</span> <span style="color: #008000;">True</span> »» beniOuiOui <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span> <span style="color: #008000;">False</span></pre></td></tr></table></div> <h3>this (is not) une pipe</h3> <p><a title="Ce serait même plutôt le contraire." href="http://sametmax.com/wp-content/uploads/2012/11/cuni0024405_004b.jpg" class="grouped_elements" rel="tc-fancybox-group2947"><img class="alignnone wp-image-2977" src="http://sametmax.com/wp-content/uploads/2012/11/cuni0024405_004b.jpg" alt="Ce serait même plutôt le contraire." width="259" height="194" /></a></p> <p>Comment fait-on pour vérifier que quelque chose n’est pas None ? La première réponse qui vient à l’esprit, c’est <code>not A is None</code>. Mais on peut aussi utiliser <code>A is not None</code>. C’est chouette, ça ressemble à du langage naturel.</p> <p>Oh, mais, attendez … Est-ce que cette écriture n’est pas un peu dangereuse ?</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span> <span style="color: #008000;">True</span></pre></td></tr></table></div> <p><code>not None</code> renvoie True. Pourquoi pas. C’est ce qui semble le plus logique.</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» <span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">True</span> <span style="color: #008000;">False</span></pre></td></tr></table></div> <p><code>1 is True</code> est faux. Ca semble correct aussi. La valeur numérique 1 et la valeur booléenne True sont égales, mais ce ne <em>SONT</em> pas les mêmes objets.</p> <p>Mais alors, si j’écris <code>1 is not None</code>, le python va transformer le <code>not None</code> en <code>True</code>, ça va faire <code>1 is True</code>, et ça va renvoyer faux. Ce n’est pas ce que je veux ! La valeur numérique 1, ce n’est pas None. Moi je veux que <code>1 is not None</code> me renvoie vrai.</p> <p>Arrggh ! Pleurons mes amis ! Et regardons avec horreur le python se désintégrer tout seul dans une bouffée de logique !</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» <span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span> <span style="color: #008000;">True</span></pre></td></tr></table></div> <p>Ah tiens non. Hmmm… Attendez voir…</p> <div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">»» <span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: black;">(</span><span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span><span style="color: black;">)</span> <span style="color: #008000;">False</span></pre></td></tr></table></div> <p>Qu’est-ce donc que cela ? Figurez-vous que <code>is not</code> est un opérateur. Il compare les id, et renvoie True s’ils sont différents. Je vous laisse confirmer cela en consultant la doc du python, ou en faisant un petit <code>help("is")</code> dans la console.</p> <p>Voilà, j’espère que ça vous a plu. La prochaine fois, nous essaierons de déceler dans le langage Brainfuck des éléments de la thèse existentialiste selon Jean-Paul Sartre.</p> ]]></content:encoded> <wfw:commentRss>http://sametmax.com/id-none-et-bidouilleries-memoire-en-python/feed/</wfw:commentRss> <slash:comments>20</slash:comments> <enclosure url="http://sametmax.com/wp-content/uploads/2012/11/nonne_redim.jpg" length="11757" type="image/jpg" /> </item> </channel> </rss>