<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://cygal.info/blog/index.php/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>Dissidents - python</title>
  <link>http://cygal.info/blog/index.php/</link>
  <description></description>
  <language>fr</language>
  <pubDate>Tue, 01 Apr 2008 21:56:24 +0200</pubDate>
  <copyright></copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Les property</title>
    <link>http://cygal.info/blog/index.php/post/Les-property</link>
    <guid isPermaLink="false">urn:md5:4c90537e04262440dbe6fe5525630683</guid>
    <pubDate>Sat, 01 Sep 2007 16:27:00 +0000</pubDate>
    <dc:creator>Pmol</dc:creator>
        <category>Script</category>
        <category>python</category>    
    <description>&lt;p&gt;Ou comment appeler une fonction lorsque l'on accède à un attribut.&lt;/p&gt;    &lt;p&gt;Prenons un exemple.
Vous avez une classe &lt;code&gt;Rectangle&lt;/code&gt; qui a deux attributs&amp;nbsp;: &lt;code&gt;longueur&lt;/code&gt; et &lt;code&gt;largeur&lt;/code&gt;. Vous pouvez les redéfinir à volonté, bien.&lt;/p&gt;

&lt;pre&gt;
&amp;gt;&amp;gt;&amp;gt; class Rectangle(object):
...     def __init__(self, longueur, largeur):
...             self.longueur = longueur
...             self.largeur = largeur
... 
&amp;gt;&amp;gt;&amp;gt; a = Rectangle(10, 1)
&amp;gt;&amp;gt;&amp;gt; a.longueur
10
&amp;gt;&amp;gt;&amp;gt; a.longueur = 15
&amp;gt;&amp;gt;&amp;gt; a.longueur
15
&lt;/pre&gt;


&lt;p&gt;Mais s'il vous prend l'idée subite et stupide d'ajouter un attribut &lt;code&gt;aire&lt;/code&gt;, comment allez-vous faire pour que sa valeur soit toujours exacte&amp;nbsp;? Si vous modifiez la longueur du rectangle, il y aura un problème.&lt;/p&gt;
&lt;pre&gt;
&amp;gt;&amp;gt;&amp;gt; a.aire = a.longueur * a.largeur
&amp;gt;&amp;gt;&amp;gt; a.aire
15
&amp;gt;&amp;gt;&amp;gt; a.largeur = 3
&amp;gt;&amp;gt;&amp;gt; a.aire
15
&lt;/pre&gt;

&lt;p&gt;Bien que la largueur du rectangle ait changée, l'aire n'a pas bougé d'un poil. C'est un comportement normal (c'est une simple variable), mais ce n'est pas le comportement souhaité. On peut utiliser une fonction &lt;code&gt;trouverAire()&lt;/code&gt; ou &lt;code&gt;aire()&lt;/code&gt;, mais c'est nettement moins sex' qu'une variable non&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;Mais Python nous offre (comme d'autres langages) une solution adaptée à notre problème&amp;nbsp;: les &lt;em&gt;properties&lt;/em&gt;. Grâce au type prédéfini &lt;code&gt;property&lt;/code&gt;, on va pouvoir créer un attribut spécial de la classe Rectangle, qui sera (du côté utilisateur de la classe) identique à un attribut simple.
Cet attribut est spécial dans le sens où, lorsqu'on veut accéder à sa valeur, la modifier ou le supprimer, on passe part des fonctions.
Même si vous vous en foutez sûrement, voici  la signature de &lt;code&gt;property&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;
property(fget = None, fset = None, fdel = None, doc = None) -&amp;gt; property attribute
&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;fget&lt;/code&gt; est appelé quand on demande la valeur de l'attribut, &lt;code&gt;fset&lt;/code&gt; lorsqu'on affecte à l'attribut une valeur et &lt;code&gt;fdel&lt;/code&gt; quand on veut supprimer l'attribut. &lt;code&gt;doc&lt;/code&gt; est l'éventuelle docstring de l'attribut.&lt;/p&gt;


&lt;p&gt;Si on reprend notre exemple de rectangles, lorsque l'utilisateur va demander la valeur de l'aire de notre rectangle, Python appellera une fonction prédéfinie qui va renvoyer, après calcul, la valeur de l'aire. Cette valeur sera toujours correcte, puisque recalculée à chaque demande. Exemple&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;gt;&amp;gt;&amp;gt; class Rectangle(object):
...     def __init__(self, largeur, hauteur):
...             self.largeur = largeur
...             self.hauteur = hauteur
...     def _getAire(self):
...             return self.largeur * self.hauteur
...     aire = property(_getAire)
... 
&amp;gt;&amp;gt;&amp;gt; a = Rectangle(10, 5)
&amp;gt;&amp;gt;&amp;gt; a.aire
50
&amp;gt;&amp;gt;&amp;gt; a.largeur = 3
&amp;gt;&amp;gt;&amp;gt; a.aire
15
&lt;/pre&gt;


&lt;p&gt;Ici, chaque instance la classe Rectangle a un attribut &lt;code&gt;aire&lt;/code&gt; en &lt;strong&gt;lecture seule&lt;/strong&gt; (si un des trois paramètres n'est pas donné, alors l'opération correspondante lève une exception), recalculé à chaque demande.&lt;/p&gt;</description>
    
    
    
          <comments>http://cygal.info/blog/index.php/post/Les-property#comment-form</comments>
      <wfw:comment>http://cygal.info/blog/index.php/post/Les-property#comment-form</wfw:comment>
      <wfw:commentRss>http://cygal.info/blog/index.php/feed/rss2/comments/37</wfw:commentRss>
      </item>
    
  <item>
    <title>Du code en Python</title>
    <link>http://cygal.info/blog/index.php/post/Du-code-en-Python</link>
    <guid isPermaLink="false">urn:md5:d33df24537929e09dcd02a575ab2d56f</guid>
    <pubDate>Sun, 22 Jul 2007 09:19:00 +0000</pubDate>
    <dc:creator>Poulet</dc:creator>
        <category>Script</category>
        <category>python</category>    
    <description>    &lt;p&gt;Parce que trop de sucre rend &lt;del&gt;idiot&lt;/del&gt; diabétique. &lt;a href=&quot;http://docs.python.org/lib/defaultdict-examples.html&quot;&gt;Visit my website&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
          <comments>http://cygal.info/blog/index.php/post/Du-code-en-Python#comment-form</comments>
      <wfw:comment>http://cygal.info/blog/index.php/post/Du-code-en-Python#comment-form</wfw:comment>
      <wfw:commentRss>http://cygal.info/blog/index.php/feed/rss2/comments/31</wfw:commentRss>
      </item>
    
  <item>
    <title>Debout les gars, réveillez-vous !</title>
    <link>http://cygal.info/blog/index.php/post/Debout-les-gars-reveillez-vous</link>
    <guid isPermaLink="false">urn:md5:b697ea589dc1e5c026862ac062ad70f7</guid>
    <pubDate>Mon, 02 Jul 2007 07:23:00 +0000</pubDate>
    <dc:creator>Poulet</dc:creator>
        <category>Script</category>
        <category>fonctionnel</category><category>python</category>    
    <description>&lt;p&gt;Salut les poulpes. &lt;q&gt;Ouaaaaais !&lt;/q&gt; firent les poulpes.&lt;/p&gt;


&lt;p&gt;Comme vous êtes un peu morts ces jours-ci, un petit truc pour vous détendre les zygomatiques, à vous, oui, vous qui ne pratiquez pas des langages pseudo-fonctionnels, mais des vrais langages de mâles.&lt;/p&gt;    &lt;p&gt;Dans un langage normal, disons, &quot;sympa&quot;, on aurait ça&amp;nbsp;: &lt;code&gt;let sommelong = map length&lt;/code&gt;. C'est lisible (sous réserve d'un peu d'habitude peut-être), c'est efficace. Après, on rigole bien, on a une fonction de type &lt;code&gt;[[a]] -&amp;gt; [Int]&lt;/code&gt;, on peut écrire &lt;code&gt;sommelong [[1, 2, 3], [3,4]]&lt;/code&gt; aussi bien que &lt;code&gt;sommelong [&quot;Foo&quot;, &quot;BarBarBar&quot;]&lt;/code&gt;, ce qui est totalement inutile (ça prouve bien que mon exemple est à chier), mais c'est bien et tout. Pour les étrangers incultes et barbares, c'est une application partielle&amp;nbsp;: map est de type &lt;code&gt;(a -&amp;gt; b) -&amp;gt; [a] -&amp;gt; [b]&lt;/code&gt;, c'est à dire que son premier argument est une fonction prenant un type a quelconque (enfin, je crois) et renvoyant un type b tout aussi quelconque (même pas forcément le même). Or si on écrit &lt;code&gt;map length&lt;/code&gt; (comme on l'a fait juste au début, ça n'est pas un hasard), on crée une nouvelle valeur fonctionnelle qui correspond à un map dont le premier argument est length - cependant cette valeur fonctionnelle est directement utilisable comme fonction. On peut donc lui nommer un nom (comme on a fait) et l'appliquer après à des listes (comme on a fait aussi), genre &lt;code&gt;sommelong uneliste&lt;/code&gt;. C'est comme si l'on avait fait &lt;code&gt;map length uneliste&lt;/code&gt;.&lt;/p&gt;


&lt;p&gt;Dans un langage moins sympa (zB. Python) mais qui essaye de se faire des potes poulpes (&lt;q&gt;Ouaaaaais !&lt;/q&gt;), on est bien emmerdé, parce que&amp;nbsp;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On a bien une fonction map, qui prend en argument une fonction et une liste (en fait, &quot;pas seulement&quot;, mais compliquons pas, tfaçon ça marche).&lt;/li&gt;
&lt;li&gt;On a bien une fonction len, qui sert à calculer la longueur d'une séquence^W liste.&lt;/li&gt;
&lt;li&gt;Mais on sait pas comment combiner les deux.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On pourrait faire une fonction chiante qui se tape ce rôle, mais ça sert à rien que je le fasse puisque la doc officielle donne de toute façon le code correspondant. Moi, je voulais juste vous dire que ça existe, sous le nom de functools.partial dans Python 2.5&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
&amp;gt;&amp;gt;&amp;gt; import functools
&amp;gt;&amp;gt;&amp;gt; sommelong = functools.partial(map, len)
&amp;gt;&amp;gt;&amp;gt; sommelong([[1,2,3], &amp;quot;foo&amp;quot;])
[3, 3]
&lt;/pre&gt;

&lt;p&gt;L'exemple est toujours foireux, mais vous êtes cultivé (ou hilare, ce qui est bien aussi).&lt;/p&gt;


&lt;p&gt;Voici donc &lt;a href=&quot;http://docs.python.org/lib/module-functools.html&quot; hreflang=&quot;en&quot;&gt;la page officielle de functools&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;C'est puissant.&lt;/p&gt;</description>
    
    
    
          <comments>http://cygal.info/blog/index.php/post/Debout-les-gars-reveillez-vous#comment-form</comments>
      <wfw:comment>http://cygal.info/blog/index.php/post/Debout-les-gars-reveillez-vous#comment-form</wfw:comment>
      <wfw:commentRss>http://cygal.info/blog/index.php/feed/rss2/comments/28</wfw:commentRss>
      </item>
    
  <item>
    <title>Des nouvelles de mon suicide.</title>
    <link>http://cygal.info/blog/index.php/post/Des-nouvelles-de-mon-suicide</link>
    <guid isPermaLink="false">urn:md5:f2d71aa49dbdb2a70fa1e19f1de8b8b2</guid>
    <pubDate>Mon, 04 Jun 2007 20:53:00 +0000</pubDate>
    <dc:creator>Poulet</dc:creator>
        <category>Divers</category>
        <category>python</category>    
    <description>&lt;p&gt;Non j'déconne.&lt;/p&gt;    &lt;p&gt;Un gens normal, il poste pas sur le blog, tu lui dis &quot;Hé, allez rolol va poster sur le blog&quot;. Moi c'est &quot;Ah au fait, tu postes plus ?&quot;  &quot;Non, pas d'inspiration&quot;   &quot;Ouais c'est ce qu'on se disait.&quot;. Hyper chaleureux, merci Cygal.&lt;/p&gt;


&lt;p&gt;Pour la peine, un &lt;a href=&quot;http://blogloufoque.free.fr/index.php/2005/11/14/7-ma-premiere-application-en-wxpython&quot; hreflang=&quot;fr&quot;&gt;lien inutile mais fendard&lt;/a&gt;. Peut éventuellement être utilisé pour la source qui se trouve au bout, même si je doute qu'elle présente de l'intérêt. En même temps je sais pas, je l'ai pas lue.&lt;/p&gt;


&lt;p&gt;Maintenant, un vrai contenu (parce qu'en fait des sujets j'en ai plein, hein, j'ai juste pas envie de les partager avec vous). Je vais vous parler d'un système de typage utilisable en Python, qui présente un intérêt moyen puisqu'il reste dynamique, mais quand même. Il s'agit de &lt;a href=&quot;http://python.fyxm.net/pycon/papers/traits.html&quot; hreflang=&quot;en&quot;&gt;traits&lt;/a&gt;, NON ne cliquez pas, lisez la suite (je comprends pourquoi vous foutez les liens à la fin maintenant :o).&lt;/p&gt;


&lt;p&gt;Pour paraphraser plus ou moins bluestorm et l'éditeur du papier officiel qui cause de traits, Python utilise un système de typage dynamique, et si c'est assez cool pour un langage de scripts, ça peut être chiant pour de plus gros projets. Ouais, y'a des gens qui font des gros projets en Python, faute de langage plus crédible, ou de compétence/sérieux. On en trouve cela dit des très biens, hein, et &lt;a href=&quot;http://www.rubyonrails.org/&quot; hreflang=&quot;en&quot;&gt;pas que des trucs de webeux&lt;/a&gt;, sans viser personne bien sûr. J'vous emmerde de toute façon.&lt;/p&gt;


&lt;p&gt;Un tel déchaînement de violence, ça fout les boules.&lt;/p&gt;


&lt;p&gt;Bref, parmis les gros projets Python, on compte &lt;a href=&quot;http://www.chacousa.com/&quot; hreflang=&quot;en&quot;&gt;Chaco&lt;/a&gt; (flash). Attention, lien rigolo, haha (&lt;a href=&quot;http://www.python.org/pycon/papers/chaco.pdf&quot; hreflang=&quot;en&quot;&gt;un vrai lien vers Chaco&lt;/a&gt; (pdf)). Au moment où j'écris j'ai plus trop l'impression que ça soit une killer app en Python, mais on va dire que si. Or donc, Chaco vous permet (à première vue) d'utiliser plot depuis Python, pour des raisons qui me dépassent vu que je n'utilise pas plot. Ça serait comme qui dirait bâti par dessus.&lt;/p&gt;


&lt;p&gt;Mais le problème, c'est que les utilisateurs de Chaco (et là on va faire le lien avec le &lt;del&gt;début&lt;/del&gt; milieu de l'article) peuvent être enclins à taper n'importe quoi pour, par exemple, changer un objet de couleur. Et faut bien les comprendre&amp;nbsp;: c'est pratique de pouvoir faire monObjet.color = &quot;red&quot; ou monObjet.color = (1.0, 0.0, 0.0, 1.0) (encore que le dernier est chiant à taper - heureusement que je l'ai directement copié-collé de la page que vous n'êtes pas allé voir). C'est ce qu'on appelle être flexible.&lt;/p&gt;


&lt;p&gt;Dans un langage qui l'est naturellement (et souvent un peu trop), c'est pas difficile à faire. Ce qui devient plus chiant, c'est quand on veut contrôler les valeurs que peut prendre color. Par exemple, un quatrain (mettons que ça s'appelle comme ça) avec des valeurs qui ne sont pas comprises entre 0 et 1, ça n'a aucun sens. On pourrait alors imaginer un système de contrôle de l'attribut color à l'aide des propriétés (oui on sait lasts, en définissant une méthode color= :]). Ça fait quand même pas mal de code à implémenter, avec à chaque fois pour seule éventuelle différence les types acceptés.&lt;/p&gt;


&lt;p&gt;Donc, autant utiliser un module qui le fait déjà, non&amp;nbsp;? Et qui, en passant, l'implémente certainement de cette façon (n'avez qu'à regarder). Bien. Passons à l'exemple d'utilisation (qui est encore une fois un exemple officiel), qui me permettra d'introduire quelques particularités liées à traits&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
from enthought.traits.api import Delegate, HasTraits, Int, Str, Instance

class Parent(HasTraits): # Le typage se fait en héritant... ce qui le restreint aux classes. Mais bon.
    first_name = Str('') # Sans surprise, on utilise deux chaînes (qu'on initialise aux chaînes vides
    last_name = Str('') 
                                 
class Child(HasTraits):
    age = Int # Ici, un âge entier, sans intialisation.
    father = Instance(Parent) # On peut utiliser des classes comme nouveaux types.
    first_name = Str('')

    last_name = Delegate('father') # Le nom est celui du père ;) 

    def _age_changed(self, old, new):  # Une particularité de traits (voir plus bas)
        print 'Age changed from %s to %s ' % (old, new)

joe = Parent()
joe.last_name = 'Johnson'

# Ici, on crée un enfant, et le nom de famille sera bel et bien transmis.
moe = Child()
moe.father = joe
print &amp;quot;Moe's last name is %s&amp;quot; % (moe.last_name)

# On change l'âge normalement, et... la méthode _age_changed sera appelée
moe.age = 10

# La ligne suivante provoquera une erreur
moe.age = 12.3
&lt;/pre&gt;


&lt;p&gt;Voilà voilà. Le code se comprend facilement, même pour les non-pythonnistes que sont en majorité les hérétiques qui lisent ce blog. On observe trois points importants, qui sont d'ailleurs signalés en commentaires dans le code source original, et que je vais retranscrire ici&amp;nbsp;: le rôle de traits ne se limite pas au typage. C'est son but premier, que les développeurs ont appelé la “validation”. C'est ce rôle qui fera que la dernière ligne provoquera une erreur (12.3 n'étant pas un entier). Ici, les exemples d'utilisation sont basiques, mais je vous invite à consulter le site officiel si vous souhaitez en voir des plus intéressants (on peut par exemple créer des types sommes, ou des types d'entiers compris dans un certain intervalle, ou des structures de données typées (List(Int) par exemple), etc.)&lt;/p&gt;


&lt;p&gt;Mais traits ne se limite pas à ça. Il propose aussi ce qu'on appelle la “délégation”. En l'occurence, on la voit assez facilement avec l'appel de Delegate&amp;nbsp;: une classe peut hériter certaines caractéristiques (on dira &quot;certains traits&quot;...) d'une autre, sans pourtant passer par un héritage habituel.&lt;/p&gt;


&lt;p&gt;Le troisième point présenté ici est la “notification”&amp;nbsp;: on peut définir un comportement qui sera adopté lors de la modification d'un trait. Cela se fait en passant par une méthode qui, si elle est implémentée, devra être prête à recevoir l'ancienne et la nouvelle valeur du trait.&lt;/p&gt;


&lt;p&gt;Bon, vous allez me dire que vous vous ennuyez vraiment, que tout ceci ne vous intéresse pas. Moi non plus, pas trop, en fait. Mais il reste un dernier point, que je n'ai pas présenté ici parce que le code d'exemple ne fonctionne pas chez moi, que les développeurs on appelé la “visualisation”. Via un module appelé traits.ui, on peut en effet définir une façon purement sémantique de représenter ses données dans une interface graphique. On donne alors la possibilité de construire une interaction avec l'utilisateur final du programme, standardisée et sans fioritures (du moins pour une utilisation basique), donc évidente et régulière. On peut interroger cet utilisateur sur la valeur qu'il souhaite donner à un certain trait, en profitant immédiatement des trois autres particularités développée précédemment. Bon, &lt;a href=&quot;http://code.enthought.com/images/traits_example.png&quot; hreflang=&quot;img&quot;&gt;ça a une gueule sacrément austère&lt;/a&gt;, mais comme je vous le disais je ne suis pas sûr que ça ne soit pas modifiable pour une utilisation avancée.&lt;/p&gt;


&lt;p&gt;Pour les personnes qui se sont vraiment emmerdées jusqu'à présent, je reviens juste quelques secondes sur le côté “délégation”. En effet, si ici les traits semblent être une joyeuse API visant à combler certaines lacunes du langage, ils sont en réalité un objet de recherche, qu'on veut utiliser dans des langages orientés objet qui pratiquent l'héritage multiple (et où, presque par définition, ça pose problème), ou même dans des langages plus raisonnables. Ils sont alors présentés comme une façon d'échapper aux problèmes de cet héritage multiple, et comme des entités dont l'utilisation permet de factoriser le code, de regrouper des comportements (mais pas des états) communs à plusieurs classes.&lt;/p&gt;


&lt;p&gt;Voici donc &lt;a href=&quot;http://www.dptinfo.ens-cachan.fr/STIC/Stages/Rapports04/spiwack04.pdf&quot; hreflang=&quot;fr&quot;&gt;un court article à ce sujet (caml inside)&lt;/a&gt; (pdf), qui pourra donner envie au lecteur de &lt;a href=&quot;http://www.iam.unibe.ch/~scg/Archive/Papers/Scha03aTraits.pdf&quot; hreflang=&quot;en&quot;&gt;lire un article un peu plus riche&lt;/a&gt; (pdf). Ils présentent notamment (surtout le deuxième) les faiblesses des mécanismes d'héritage multiple, et l'utilisation des traits en tant que solution.&lt;/p&gt;


&lt;p&gt;NB&amp;nbsp;: Vous comprenez pourquoi j'écris plus, ça sert vraiment à rien.&lt;/p&gt;</description>
    
    
    
          <comments>http://cygal.info/blog/index.php/post/Des-nouvelles-de-mon-suicide#comment-form</comments>
      <wfw:comment>http://cygal.info/blog/index.php/post/Des-nouvelles-de-mon-suicide#comment-form</wfw:comment>
      <wfw:commentRss>http://cygal.info/blog/index.php/feed/rss2/comments/19</wfw:commentRss>
      </item>
    
  <item>
    <title>Vlà une idée qu'elle est pas terrible</title>
    <link>http://cygal.info/blog/index.php/post/2007/05/19/7-vla-une-idee-qu-elle-est-pas-terrible</link>
    <guid isPermaLink="false">urn:md5:ac77a583358a61323cfd8a3c1f36edc0</guid>
    <pubDate>Sat, 19 May 2007 11:52:06 +0000</pubDate>
    <dc:creator>Poulet</dc:creator>
        <category>Script</category>
        <category>python</category>    
    <description>&lt;p&gt;La tarte, ça appelle le poulet. Ou “comment contre-attaquer avant qu'il se soit rien passé”.&lt;/p&gt;    &lt;p&gt;Bien le bonjour. Une fois n'est pas coutume, je viens de trouver le moyen d'être chiant, d'une part en étant plus productif que mes collègues, d'autre part en produisant de l'inutilité.&lt;/p&gt;


&lt;p&gt;Vlà-t'y pas que pas plus tard qu'hier, sur le canal où nous nous retrouvons pour le moment (#sdz-unix sur irc.epiknet.org), ArtMoonik a une super idée (comme ça lui arrive souvent d'ailleurs), et ne résiste pas au plaisir de nous en faire part&amp;nbsp;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;ArtMoonik: va falloir qu'on floode de ruby&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Si c'est pas génial, ça, madame.&lt;/p&gt;


&lt;p&gt;Donc moi, naturellement pas trop favorable à la chose, je prends sur moi, et réfléchis. Et là je me dis&amp;nbsp;: &quot;mais on n'a qu'à faire l'inverse !&quot;.&lt;/p&gt;


&lt;p&gt;Ce que j'essaye de dire au moyen de mon &lt;a href=&quot;http://jclat.typepad.com/think/2005/03/immarcescible.html&quot; hreflang=&quot;fr&quot;&gt;immarcescible&lt;/a&gt; talent de comédien-metteur en scène (si, on peut placer immarcescible dans cette phrase, je vois pas le problème), ce que désormais, tous les jours sauf le dimanche (d'où l'intérêt de commencer un samedi), j'aurai la joie de vous infliger “Le Truc En Python Du Jour”. Ça va être pénible, inutile, je doute tenir la longueur, mais ça me fera une raison pour faire de la pub pour le blog&amp;nbsp;: “Hé, toi qui kiffes le Python, tu savais ça&amp;nbsp;? Et ça ?”.&lt;/p&gt;


&lt;p&gt;Permettez-moi donc d'introduire le premier de cette longue liste de scripts (ou de bouts de) niaiseux&amp;nbsp;: &lt;a href=&quot;http://dashuhn.free.fr/kamoulox.rb.py&quot; hreflang=&quot;fr&quot;&gt;kamoulox.rb.py&lt;/a&gt;. C'est une traduction du &lt;a href=&quot;http://cygal.info/blog/index.php/2007/05/19/5-rubykamoulox-parce-que-une-tarte-ecarlate-ca-appelle-la-corne-contractuelle&quot; hreflang=&quot;fr&quot;&gt;script kamoulox d'ArtMoonik&lt;/a&gt;. Vous devriez pouvoir à peu près tout lire, mais détaillons un petit peu.&lt;/p&gt;


&lt;p&gt;Le début me semble à peu près compréhensible, on note la traduction de empty? des chaînes par une comparaison avec la chaîne vide, celle du mystérieux caractère 35 par un '#' (parce que oui ce sont les mêmes), un &quot;strippage&quot; quasi inutile (mais j'aime bien) sur clef et contenu, la traduction une nouvelle fois du empty? sur le hash par un truc un peu plus riche sémantiquement parlant (ne niez pas §§), et l'utilisation d'une fonction nommée (définie de façon interne) pour sub, là où Ruby utilise un bloc (encore une fois si on avait de vraies lambdas en Python...). De plus, plutôt que de rajouter une méthode à list (ce qui aurait été compliqué vu que c'est pas possible par défaut), on utilise choice du module random. On note également que ce que sub transmet à la fonction qu'il invoque, c'est un &lt;a href=&quot;http://www.python.org/doc/2.1.3/lib/match-objects.html&quot; hreflang=&quot;en&quot;&gt;objet match&lt;/a&gt;, pas une chaîne.&lt;/p&gt;


&lt;p&gt;La fonction sub permet donc d'appeler une fonction (ici, on peut aussi lui transmettre une chaîne de remplacement à la place) en lui passant le résultat d'une capture à l'aide d'une regex. Ici, la regex [(\w)_\|]* qu'elle est belle sert à capter tous les mots, plus les _ et les |.&lt;/p&gt;


&lt;p&gt;Voilà voilà, ce script est un peu plus compliqué que ce qui suivra (normalement), étant donné que je montrerai par la suite plus &quot;d'astuces&quot; Pythonniques que de vrais programmes, mais on ne sait jamais.&lt;/p&gt;</description>
    
    
    
          <comments>http://cygal.info/blog/index.php/post/2007/05/19/7-vla-une-idee-qu-elle-est-pas-terrible#comment-form</comments>
      <wfw:comment>http://cygal.info/blog/index.php/post/2007/05/19/7-vla-une-idee-qu-elle-est-pas-terrible#comment-form</wfw:comment>
      <wfw:commentRss>http://cygal.info/blog/index.php/feed/rss2/comments/6</wfw:commentRss>
      </item>
    
</channel>
</rss>