SQLite format 3@  ))m++ƒtableatomisator_linkatomisator_linkCREATE TABLE atomisator_link ( id INTEGER NOT NULL, url VARCHAR(300), atomisator_entry_id INTEGER, PRIMARY KEY (id), FOREIGN KEY(atomisator_entry_id) REFERENCES atomisator_entry (id) )l))ƒtableatomisator_tagatomisator_tagCREATE TABLE atomisator_tag ( id INTEGER NOT NULL, value VARCHAR(100), atomisator_entry_id INTEGER, PRIMARY KEY (id), FOREIGN KEY(atomisator_entry_id) REFERENCES atomisator_entry (id) )u--ƒtableatomisator_entryatomisator_entryCREATE TABLE atomisator_entry ( id INTEGER NOT NULL, link TEXT, date TIMESTAMP, updated TIMESTAMP, summary TEXT, summary_detail TEXT, title TEXT, title_detail TEXT, PRIMARY KEY (id) )úŠú‰đûöđȚ&^%$P8ûöńìçâĘŰÓÎÈÂŒ¶°Ș€ž˜’Œ†€ztnhb\VP‚ań‚UԂIĄ‚> ‚2‹‚&ą‚˜‚‚‰w…k€a{WvMrCm9i.b#\X SNxImDb?V6J+< /! LL…1 OAAˆYE-http://djangobook.zindep.com/1.0/2008-08-31 17:40:51.2416152008-08-21 19:30:08.000000
Extract from link :

...Django 7 Août 2008 Chapitre 2: Prise en main 7 Août 2008 Chapitre 3: Les bases des pages web dynamiques 7 Août 2008 Chapitre 4: Le systÚme de gabarit de Django 7 Août 2008 Chapitre 5: Interagir avec une base de données: les modÚles 7 Août 2008 Chapitre 6: Le site d ' administration de Django 7 Août 2008 Chapitre 7: Utilisation des formulaires 7 Août 2008 Chapitre 8: Vues et URLconfs avancés 7 Août 2008 Chapitre 9: Vues génériques 5 Août 2008 Chapitre 10:...


.[Delicious] Django Book (FR)Django Book (FR) ĂÆ: AA‰ yhttp://video.google.com/videoplay?docid=-2884501541077753488&hl=fr2008-08-31 17:40:51.5529262008-08-19 23:33:48.000000
Extract from link :

... Connexion Conférence Pycon Fr 2008 - Apprenez d ' abord le python Détails Commentaires D'autres vidéos de cet utilisateur Conférence Pycon Fr 2008 - Apprenez d ' abord le python - 29 mn - 26 mai 2008 () Note : Conférence Pycon Fr 2008 - Apprenez d ' abord le python Télécharger - iPod/PSP | Intégrer dans un site Lancement du téléchargement. Enregistrez le fichier sur votre ordinateur. Si le téléchargement n...


.[Delicious] ConfĂ©rence Pycon Fr 2008 - Apprenez d'abord le pythonConfĂ©rence Pycon Fr 2008 - Apprenez d'abord le python }}‡ cAAˆYG/http://kdl.nobugware.com/post/2007/12/04/La-liste-des-applications/lib-utiles-pour-un-nouveau-projet-Django2008-08-31 17:40:52.0538272008-08-11 11:23:48.000000
Extract from link :

...nouveau projet Django By AkH on Tuesday, December 4 2007, 15:02 - Dev - Permalink django Beaucoup d'outils facilitent la création d'un nouveau site web codé en Django: django-tagging Vous permet d'appliquer des tags à tous les objets de votre application. Exemples django-voting permet de comptabiliser des votes sur n'importe quel objet de votre model, fournit des template tags django-openid Ajoute l'authentification Openid à votre site django-r...


.[Delicious] La liste des applications/lib utiles pour un nouveau projet Django - Keep Da LinkLa liste des applications/lib utiles pour un nouveau projet Django - Keep Da Link őő† yAAƒ7ƒ‚}http://www.biologeek.com/django,traduction,web-frameworks/le-langage-de-template-django-pour-les-auteurs-de-templates/2008-08-31 17:40:52.5750212008-08-08 12:55:11.000000
Extract from link :

... Si vous avez déjà utilisé un autre langage de template, comme Smarty ou CheetahTemplate , vous n'aurez aucune difficulté à adopter les templates Django....


.[Delicious] Le langage de template Django : Pour les auteurs de templates " Django, Traduction, Web Frameworks " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution.Le langage de template Django : Pour les auteurs de templates " Django, Traduction, Web Frameworks " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution. €€†} ‚AAAƒ5ƒgƒOhttp://www.biologeek.com/django,traduction,web-frameworks/redaction-de-votre-premiere-appli-django-partie-4-conception-d-un-formulaire-et-vues-generiques/2008-08-31 17:40:53.3903282008-08-08 12:55:03.000000
Extract from link :

... Nous continuons notre application de sondage en ligne et allons nous intéresser à la génération d'un formulaire simple et au ré-arrangement de notre code....


.[Delicious] RĂ©daction de votre premiĂšre appli Django, partie 4 : Conception d'un formulaire et vues gĂ©nĂ©riques " Django, Traduction, Web Frameworks " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution.RĂ©daction de votre premiĂšre appli Django, partie 4 : Conception d'un formulaire et vues gĂ©nĂ©riques " Django, Traduction, Web Frameworks " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution. ­­†P ‚9AA‚wƒ]ƒEhttp://www.biologeek.com/django,traduction,web-frameworks/redaction-de-votre-premiere-appli-django-partie-3-creation-des-vues-de-l-interface-publique/2008-08-31 17:40:53.8667262008-08-08 12:54:58.000000
Extract from link :

... Nous continuons l'application Web de sondage et allons nous focaliser sur la création d'interfaces publiques -- les « vues »....


.[Delicious] RĂ©daction de votre premiĂšre appli Django, partie 3 : CrĂ©ation des vues de l'interface publique " Django, Traduction, Web Frameworks " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution.RĂ©daction de votre premiĂšre appli Django, partie 3 : CrĂ©ation des vues de l'interface publique " Django, Traduction, Web Frameworks " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution. †n ‚EAAƒƒmƒUhttp://www.biologeek.com/django,traduction,web-frameworks/redaction-de-votre-premiere-appli-django-partie-2-exploration-de-l-interface-d-admin-auto-generee/2008-08-31 17:40:54.4811372008-08-08 12:54:54.000000
Extract from link :

... Nous continuons l'application de sondage Web et allons nous focaliser sur le site d'administration généré automatiquement par Django....


.[Delicious] Rédaction de votre premiÚre appli Django, partie 2 : Exploration de l'interface d'admin auto-générée " Django, Traduction, Web Frameworks " Journal " Biologeek, l'avis d'un freelance passionné par le web et son évolution.Rédaction de votre premiÚre appli Django, partie 2 : Exploration de l'interface d'admin auto-générée " Django, Traduction, Web Frameworks " Journal " Biologeek, l'avis d'un freelance passionné par le web et son évolution.div>Extract from link :

... Cela consistera en deux parties: Un site public qui permet aux internautes de voir les sondages et de voter. Un site d'administration qui vous permet d'ajouter, modifier et supprimer un sondage. Nous considÚrerons que vous avez déjà Django d'installé . Vous pouvez tester si Django est installé en lançant l'interpréteur interactif Python et en tapant import django. Si cette commande s'exécute sans erreur, c'est que Django est bien installé....


.[Delicious] RĂ©daction de votre premiĂšre appli Django, partie 1 : Initialisation, crĂ©ation des modĂšles et API de la base de donnĂ©es " Django, Traduction, Web Frameworks " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution.RĂ©daction de votre premiĂšre appli Django, partie 1 : Initialisation, crĂ©ation des modĂšles et API de la base de donnĂ©es " Django, Traduction, Web Frameworks " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution. ? ?…H eAAˆYQ9http://www.haypocalc.com/wiki/Python_ou_rien2008-08-31 17:40:55.9287322008-08-07 08:11:17.000000
Extract from link :

...Python ou rien Un article de Haypo. Aller Ă  : Navigation , Rechercher Retour aux langages de programmation Ce document se veut ĂȘtre un document concis expliquant pourquoi Python est un langage surpuissant :-) (rien que ça !) Sommaire 1 Structures de donnĂ©es 2 GĂ©nĂ©rateur et boucle « pour chaque » 3 Langage dynamique 3.1 Introspection 3.2 Typage dynamique 4 Surchage d'opĂ©rateur 5 Comparatif avec d'autres langages 5.1 Comparatif avec le C++ 5.2 Com...


.[Delicious] Python ou rien - HaypoPython ou rien - Haypo‰k ‚gAAˆ„ƒyhttp://www.biologeek.com/django,traduction,web-frameworks/redaction-de-votre-premiere-appli-django-partie-1-initialisation-creation-des-modeles-et-api-de-la-base-de-donnees/2008-08-31 17:40:55.7214452008-08-08 12:54:50.000000< ¶ŰŽú[¶"‚Ehttp://www.biologeek.com/django,traduction,web-frameworks/redaction-de-votre-premiere-appli-django-partie-2-exploration-de-l-interface-d-admin-auto-generee/‚9http://www.biologeek.com/django,traduction,web-frameworks/redaction-de-votre-premiere-appli-django-partie-3-creation-des-vues-de-l-interface-publique/ ‚Ahttp://www.biologeek.com/django,traduction,web-frameworks/redaction-de-votre-premiere-appli-django-partie-4-conception-d-un-formulaire-et-vues-generiques/|yhttp://www.biologeek.com/django,traduction,web-frameworks/le-langage-de-template-django-pour-les-auteurs-de-templates/qchttp://kdl.nobugware.com/post/2007/12/04/La-liste-des-applications/lib-utiles-pour-un-nouveau-projet-DjangoHhttp://video.google.com/videoplay?docid=-2884501541077753488&hl=fr&Ohttp://djangobook.zindep.com/1.0/ !JŻEȚjÖąX!5mhttp://www.afpy.org/Members/gawel/news/rmll_2008Hhttp://www.afpy.org/Members/pilotsystems/manuel-utilisateur-plone32ghttp://www.afpy.org/Members/sdouche/rm-200808D http://www.biologeek.com/python/pourquoi-programmer-en-python/Lhttp://www.biologeek.com/bonnes-pratiques,python/python-et-underscore/r ehttp://www.biologeek.com/bonnes-pratiques,python/optimisation-des-chaines-de-caracteres-en-python-le-retour/ e Khttp://www.biologeek.com/bonnes-pratiques,python/formatage-des-chaines-de-caracteres-en-python/ h Qhttp://www.biologeek.com/bonnes-pratiques,python/optimisation-des-chaines-de-caracteres-en-python/ f Mhttp://www.biologeek.com/bonnes-pratiques,python/bonnes-pratiques-de-la-programmation-en-python/ 1 ehttp://www.haypocalc.com/wiki/Python_ou_rien 3‚ghttp://www.biologeek.com/django,traduction,web-frameworks/redaction-de-votre-premiere-appli-django-partie-1-initialisation-creation-des-modeles-et-api-de-la-base-de-donnees/ šš†c MAA…m‚k‚Shttp://www.biologeek.com/bonnes-pratiques,python/bonnes-pratiques-de-la-programmation-en-python/2008-08-31 17:40:56.0874382008-08-06 23:35:16.000000
Extract from link :

... bref je viens de tomber sur deux billets qui m'ont motivé, apparemment je suis pas le seul à vouloir apprendre/faire partager sur Python. Coïncidence pas si pure que ça, la sortie du livre Programmation Python que j'attends depuis quelques semaines et que je compte acheter à Solutions Linux ou gagner :)...


.[Delicious] ★ Bonnes pratiques de la programmation en Python " Bonnes Pratiques, Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution.★ Bonnes pratiques de la programmation en Python " Bonnes Pratiques, Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution. FF…7 QAAƒ‚k‚Shttp://www.biologeek.com/bonnes-pratiques,python/optimisation-des-chaines-de-caracteres-en-python/2008-08-31 17:40:56.3955112008-08-06 23:35:09.000000
Extract from link :

...des listes ? Et les list-comprehension dans tout ça ? Réponses en tests, c'est plein de strings mais ne vous inquiétez pas, rien de sexuel ;)...


.[Delicious] Optimisation des chaĂźnes de caractĂšres en Python " Bonnes Pratiques, Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution.Optimisation des chaĂźnes de caractĂšres en Python " Bonnes Pratiques, Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution. „p KAA‚‚e‚Mhttp://www.biologeek.com/bonnes-pratiques,python/formatage-des-chaines-de-caracteres-en-python/2008-08-31 17:40:56.6654612008-08-06 23:35:02.000000
Extract from link :

...Python ? Privillégier la lisibilité ou l'optimisation ? Les deux mon capitaine !...


.[Delicious] Formatage des chaĂźnes de caractĂšres en Python " Bonnes Pratiques, Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution.Formatage des chaĂźnes de caractĂšres en Python " Bonnes Pratiques, Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution. ,,…Q eAA‚yƒ‚ohttp://www.biologeek.com/bonnes-pratiques,python/optimisation-des-chaines-de-caracteres-en-python-le-retour/2008-08-31 17:40:56.8673032008-08-06 23:34:56.000000
Extract from link :

... Depuis je cogite car il est indiqué un peu partout qu'il faut privillégier les listes. Et j'ai fini par trouver une réponse :-)....


.[Delicious] Optimisation des chaĂźnes de caractĂšres en Python : le retour ! " Bonnes Pratiques, Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution.Optimisation des chaĂźnes de caractĂšres en Python : le retour ! " Bonnes Pratiques, Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution. „m AA‚q‚M‚5http://www.biologeek.com/bonnes-pratiques,python/python-et-underscore/2008-08-31 17:40:57.5465942008-08-06 23:34:28.000000
Extract from link :

... Mais la simplification peut mener à un manque de lisibilité dans certains cas. Un cas intéressant est celui de l'underscore....


.[Delicious] Python : lisibilitĂ© vs simplicitĂ© " Bonnes Pratiques, Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution.Python : lisibilitĂ© vs simplicitĂ© " Bonnes Pratiques, Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution. HH‡5  AAˆY‚)‚http://www.biologeek.com/python/pourquoi-programmer-en-python/2008-08-31 17:41:00.2563532008-08-06 23:29:06.000000
Extract from link :

...Python souffre un peu du manque de promotion. La nouvelle version du site est un premier pas, de « nouvelles » initiatives voient le jour (Ă  quand une telle ressource en français ?!) mais peut-ĂȘtre que les blogs sont un des meilleurs moyen de promotion d'un produit actuellement. Voila donc ma participation, ce ne sont pas forcĂ©ment les arguments que vous pourrez lire ailleurs, nous n'aimons pas forcĂ©ment tous les mĂȘmes choses pour les mĂȘmes raisons mais ce sont ceux qui me font apprĂ©...


.[Delicious] ★ Pourquoi programmer en Python ? " Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution.★ Pourquoi programmer en Python ? " Python " Journal " Biologeek, l'avis d'un freelance passionnĂ© par le web et son Ă©volution. ûÍûƒO AAqqihttp://www.afpy.org/Members/pilotsystems/manuel-utilisateur-plone32008-08-31 17:41:00.2941412008-08-12 03:02:18.000000Plone 3 est disponible depuis 1 an. Aujourd'hui, c'est son manuel utilisateur qui est disponible... en français !Plone 3 est disponible depuis 1 an. Aujourd'hui, c'est son manuel utilisateur qui est disponible... en français ![Afpy News] Le manuel d'utilisation Plone 3 en français !Le manuel d'utilisation Plone 3 en français !‚0 gAA}}oWhttp://www.afpy.org/Members/sdouche/rm-2008082008-08-31 17:41:00.2765942008-08-17 05:21:18.000000Comme chaque mois, la rĂ©union mensuelle AFPy sur Paris.Comme chaque mois, la rĂ©union mensuelle AFPy sur Paris.[Afpy News] RĂ©union mensuelle Paris 30 aout 2008RĂ©union mensuelle Paris 30 aout 2008 »€»_ AA qYhttp://www.afpy.org/Members/Nightlybuild/Compte-renduAFPyroBreizhvolume012008-08-31 17:41:00.3527602008-06-27 07:35:54.000000[Afpy News] Compte-rendu AFPyro Breizh - Volume 01Compte-rendu AFPyro Breizh - Volume 01‚ AAQQYAhttp://www.afpy.org/Members/lunatik/afpynews.2008-07-09.29346351602008-08-31 17:41:00.3331752008-07-09 02:39:38.000000Ceci n'est pas un poisson d'avril.Ceci n'est pas un poisson d'avril.[Afpy News] Sun se rapproche de PythonSun se rapproche de Python‚Y mAA55[Chttp://www.afpy.org/Members/gawel/news/rmll_20082008-08-31 17:41:00.3136562008-07-13 09:32:57.000000L'AFPy Ă©tait prĂ©sent aux Rencontres Mondiales du Logiciel Libre Ă  Mont-de-Marsan.L'AFPy Ă©tait prĂ©sent aux Rencontres Mondiales du Logiciel Libre Ă  Mont-de-Marsan.[Afpy News] RMLL 2008 - On y Ă©tait !!!RMLL 2008 - On y Ă©tait !!! J¶e.üż€GŚ V̌J@!http://www.afpy.org/Members/gawel/news/afpyro-janvier-2008!> http://www.afpy.org/Members/olarcheveque/barcamp-montreal @http://www.afpy.org/Members/gawel/news/afpyro_fevrier_2008F http://www.afpy.org/Members/ccomb/afpynews.2008-03-24.8361167660Hhttp://www.afpy.org/Members/lunatik/guido-part-travailler-chez-sun5mhttp://www.afpy.org/Members/tarek/sprint-plone-3=}http://www.afpy.org/Members/gawel/news/afpyro_avril_2008/ahttp://www.afpy.org/Members/tarek/pycon-fr7qhttp://www.afpy.org/Members/Nightlybuild/rm-200806=}http://www.afpy.org/Members/ccomb/questionnaire-pycon-08;yhttp://www.afpy.org/Members/Nightlybuild/afpyro-rennes0chttp://www.afpy.org/Members/ogrisel/bpython5mhttp://www.afpy.org/Members/gawel/news/juin_2008Ohttp://www.afpy.org/Members/Nightlybuild/Compte-renduAFPyroBreizhvolume01Hhttp://www.afpy.org/Members/lunatik/afpynews.2008-07-09.2934635160 8_] yAA==S;http://www.afpy.org/Members/Nightlybuild/afpyro-rennes2008-08-31 17:41:00.4095462008-06-02 07:10:26.000000AFPyro Breizh flavoured.AFPyro Breizh flavoured.[Afpy News] AFPyro de juin - RennesAFPyro de juin - RennesƒV cAA‚+‚+gOhttp://www.afpy.org/Members/ogrisel/bpython2008-08-31 17:41:00.3925732008-06-16 16:25:26.000000bpython est un interprĂ©teur python interactif avec complĂ©tion automatique, suggestion d'arguments et coloration syntaxique le tout en curses.bpython est un interprĂ©teur python interactif avec complĂ©tion automatique, suggestion d'arguments et coloration syntaxique le tout en curses.[Afpy News] bpython - ton nouvel ami le shellbpython - ton nouvel ami le shellE mAA==A)http://www.afpy.org/Members/gawel/news/juin_20082008-08-31 17:41:00.3734852008-06-24 06:13:35.000000Oh chĂ©ri(e) chĂ©ri(e) !Oh chĂ©ri(e) chĂ©ri(e) ![Afpy News] AFPyro de JuinAFPyro de Juin ÿÿƒ~ }AA‚'‚'mhttp://www.afpy.org/Members/ccomb/questionnaire-pycon-082008-08-31 17:41:00.4273082008-06-01 20:34:47.000000N'hĂ©sitez pas Ă  rĂ©pondre Ă  notre questionnaire pour nous aider Ă  amĂ©liorer l'Ă©dition 2009 de PyCon FR, et Ă  revoir les confĂ©rences !N'hĂ©sitez pas Ă  rĂ©pondre Ă  notre questionnaire pour nous aider Ă  amĂ©liorer l'Ă©dition 2009 de PyCon FR, et Ă  revoir les confĂ©rences ![Afpy News] Questionnaire, Slides et Video sur PyCon FR 2008Questionnaire, Slides et Video sur PyCon FR 2008 …{ qAA„S„S]Ehttp://www.afpy.org/Members/Nightlybuild/rm-2008062008-08-31 17:41:00.4463792008-06-15 05:35:16.000000Nous relançons les rencontres mensuelles pour permettre aux membres de l'AFPy de se voir (non pas autour d'une biĂšre comme Ă  l'afpyro mais) devant des ordinateurs. Le but Ă©tant de coder, de prĂ©senter des technos et plus gĂ©nĂ©ralement d'Ă©changer techniquement autour du langage Python.Nous relançons les rencontres mensuelles pour permettre aux membres de l'AFPy de se voir (non pas autour d'une biĂšre comme Ă  l'afpyro mais) devant des ordinateurs. Le but Ă©tant de coder, de prĂ©senter des technos et plus gĂ©nĂ©ralement d'Ă©changer techniquement autour du langage Python.[Afpy News] RĂ©union mensuelle juin 2008RĂ©union mensuelle juin 2008 z`˜z‚ mAAssaIhttp://www.afpy.org/Members/tarek/sprint-plone-32008-08-31 17:41:00.5039662008-04-14 02:42:13.000000Sprint Plone 3 les 25, 26 et 27 avril 2008 Ă  ParisSprint Plone 3 les 25, 26 et 27 avril 2008 Ă  Paris[Afpy News] Sprint Plone 3, 25/26/27 avrilSprint Plone 3, 25/26/27 avrilE }AA55A)http://www.afpy.org/Members/gawel/news/afpyro_avril_20082008-08-31 17:41:00.4840532008-04-21 01:29:55.000000Encore un AFPyro !!!Encore un AFPyro !!![Afpy News] AFPyro d'AvrilAFPyro d'Avrilƒ aAA}}]Ehttp://www.afpy.org/Members/tarek/pycon-fr2008-08-31 17:41:00.4641252008-05-07 10:00:19.000000La deuxiĂšme Ă©dition des journĂ©es Python aura lieu les 17 et 18 mai prochains Ă  la CitĂ© des Sciences de la Villette.La deuxiĂšme Ă©dition des journĂ©es Python aura lieu les 17 et 18 mai prochains Ă  la CitĂ© des Sciences de la Villette.[Afpy News] PyCon FR - 17-18 mai - ParisPyCon FR - 17-18 mai - Paris ȘƒȘƒV  AA‚‚u]http://www.afpy.org/Members/ccomb/afpynews.2008-03-24.83611676602008-08-31 17:41:00.5453562008-03-24 11:42:36.000000Si vous souhaitez faire une prĂ©sentation lors des JournĂ©es Python en mai, il est encore temps de dĂ©poser vos propositions.Si vous souhaitez faire une prĂ©sentation lors des JournĂ©es Python en mai, il est encore temps de dĂ©poser vos propositions.[Afpy News] JournĂ©es Python - Appel Ă  propositionsJournĂ©es Python - Appel Ă  propositions‚z AA##{chttp://www.afpy.org/Members/lunatik/guido-part-travailler-chez-sun2008-08-31 17:41:00.5251712008-04-03 06:17:02.000000Guido Van Rossum, le crĂ©ateur du language Python part travailler chez Sun.Guido Van Rossum, le crĂ©ateur du language Python part travailler chez Sun.[Afpy News] Sun Microsystems dĂ©bauche Guido Van RossumSun Microsystems dĂ©bauche Guido Van Rossum Ó»ĐӁz! AAaaG/http://www.afpy.org/Members/gawel/news/afpyro-janvier-20082008-08-31 17:41:00.6052852008-01-12 02:32:18.000000Il est de nouveau temps de se retrouver !!Il est de nouveau temps de se retrouver !![Afpy News] AFPyro de janvierAFPyro de janvierh AAQQG/http://www.afpy.org/Members/olarcheveque/barcamp-montreal2008-08-31 17:41:00.5858022008-02-05 07:33:16.000000Meeeting Python le 7 fĂ©vrier 2008Meeeting Python le 7 fĂ©vrier 2008[Afpy News] BarCamp MontrĂ©alBarCamp MontrĂ©al‚B AA  cKhttp://www.afpy.org/Members/gawel/news/afpyro_fevrier_20082008-08-31 17:41:00.5655682008-02-25 15:52:54.000000Quand il fait pas beau, on a qu'une envie, c'est d'un AFPyro !!Quand il fait pas beau, on a qu'une envie, c'est d'un AFPyro !![Afpy News] AFPyro - Jeudi 28 FĂ©vrier 2008AFPyro - Jeudi 28 FĂ©vrier 2008 üDü‚E# AA++E-http://www.afpy.org/Members/gawel/news/afpyro-decembre-20072008-08-31 17:41:00.6479262007-12-11 06:46:24.000000Il n'Ă©tait pas pensable de ne pas se retrouver pour fĂȘter la fin de l'annĂ©e.Il n'Ă©tait pas pensable de ne pas se retrouver pour fĂȘter la fin de l'annĂ©e.[Afpy News] AFPyro dĂ©cembreAFPyro dĂ©cembreƒ9" 5AA;;whttp://www.afpy.org/Members/pilotsystems/solutions-linux-2008-presence-de-zope-plone2008-08-31 17:41:00.6243612008-01-08 10:23:19.000000Zope et Plone seront prĂ©sents au salon Solutions Linux 2008, du 29 au 31 janvier 2008.Zope et Plone seront prĂ©sents au salon Solutions Linux 2008, du 29 au 31 janvier 2008.[Afpy News] Zope et Plone prĂ©sents au salon Solutions Linux 2008Zope et Plone prĂ©sents au salon Solutions Linux 2008 Y€aӏEÉ•` ƉY./_http://www.afpy.org/Members/jpcw2002/gcal/;.yhttp://www.afpy.org/Members/ogrisel/slides-fosdem-2007.X-1http://www.afpy.org/Members/pilotsystems/solutions-linux-2007-support-presentation->,http://www.afpy.org/Members/odeckmyn/plone-fr-mailinglist,3+ihttp://www.afpy.org/Members/jpcw2002/video_rms+2*ghttp://www.afpy.org/Members/EuGeNe/ann-pylule*<){http://www.afpy.org/Members/gawel/news/afpyro-juin-2007)<({http://www.afpy.org/Members/gawel/news/afpyro-aout-2007(H'http://www.afpy.org/Members/ogrisel/afpynews.2007-09-13.1829091519'B&http://www.afpy.org/Members/gawel/news/afpyro-septembre-2007&D% http://www.afpy.org/Members/amine/python_contre_les_pedophiles%F$ http://www.afpy.org/Members/ccomb/afpynews.2007-10-02.5367488405$A#http://www.afpy.org/Members/gawel/news/afpyro-decembre-2007#Z"5http://www.afpy.org/Members/pilotsystems/solutions-linux-2008-presence-de-zope-plone" ))…T$  AA„„iQhttp://www.afpy.org/Members/ccomb/afpynews.2007-10-02.53674884052008-08-31 17:41:00.6697052007-10-15 02:17:19.000000L'Afpy Computer Camp Ă©tait l'Ă©vĂ©nement mĂ©morable du week-end dernier (29-30 sept 2007), organisĂ© Ă  Dijon dans la maison de Tarek. Il s'agissait initialement de tenir l'AG de l'association, et d'en profiter pour faire quelques activitĂ©s sympathiques...L'Afpy Computer Camp Ă©tait l'Ă©vĂ©nement mĂ©morable du week-end dernier (29-30 sept 2007), organisĂ© Ă  Dijon dans la maison de Tarek. Il s'agissait initialement de tenir l'AG de l'association, et d'en profiter pour faire quelques activitĂ©s sympathiques...[Afpy News] Afpy Computer Camp - on y Ă©tait !Afpy Computer Camp - on y Ă©tait ! RËR‚v& AAUUK3http://www.afpy.org/Members/gawel/news/afpyro-septembre-20072008-08-31 17:41:00.7273442007-09-17 14:05:31.000000Il fait toujours aussi moche Ă  Paris, c'est donc l'occasion de retrouver un peu de baume au coeur !Il fait toujours aussi moche Ă  Paris, c'est donc l'occasion de retrouver un peu de baume au coeur ![Afpy News] AFPyro de SeptembreAFPyro de Septembre‚2%  AA{{aIhttp://www.afpy.org/Members/amine/python_contre_les_pedophiles2008-08-31 17:41:00.6895362007-10-14 00:45:11.000000310 pĂ©dophiles prĂ©sumĂ©s confondus grĂące Ă  Python!!310 pĂ©dophiles prĂ©sumĂ©s confondus grĂące Ă  Python!![Afpy News] Python contre les pĂ©dophiles!Python contre les pĂ©dophiles!   x( {AAiiA)http://www.afpy.org/Members/gawel/news/afpyro-aout-20072008-08-31 17:41:00.7671272007-08-27 00:08:32.000000Ce mois ci, l'AFPyro sera ROCK'N'ROLLLLLLLLL !Ce mois ci, l'AFPyro sera ROCK'N'ROLLLLLLLLL ![Afpy News] AFPyro d'AoĂ»tAFPyro d'AoĂ»tƒx' AA‚#‚#yahttp://www.afpy.org/Members/ogrisel/afpynews.2007-09-13.18290915192008-08-31 17:41:00.7485952007-09-13 08:17:16.000000Voici un petit utilitaire trĂšs pratique quand vous utilisez un shell interactif python : plus besoin de faire import os, sys et compagnie.Voici un petit utilitaire trĂšs pratique quand vous utilisez un shell interactif python : plus besoin de faire import os, sys et compagnie.[Afpy News] Autoimp - importeur de modules automatiqueAutoimp - importeur de modules automatique ™ƒ* gAAkkaIhttp://www.afpy.org/Members/EuGeNe/ann-pylule2008-08-31 17:41:00.8124092007-06-14 09:02:31.000000Annonce de la crĂ©ation d'un rendez-vous rĂ©gulier pour les utilisateurs de Python sur Lille et ses "environs".Annonce de la crĂ©ation d'un rendez-vous rĂ©gulier pour les utilisateurs de Python sur Lille et ses "environs".[Afpy News] DĂ©jeuner Pythonesque Ă  LilleDĂ©jeuner Pythonesque Ă  Lille‚d) {AASSA)http://www.afpy.org/Members/gawel/news/afpyro-juin-20072008-08-31 17:41:00.7890262007-06-28 02:23:48.000000AprĂšs un splendide Ă©pisode hors sĂ©rie pour les JPF, l'AFPyro reprends sont rythme de croisiĂšre.AprĂšs un splendide Ă©pisode hors sĂ©rie pour les JPF, l'AFPyro reprends sont rythme de croisiĂšre.[Afpy News] AFPyro de JuinAFPyro de Juin $QéĐŻm6ÿÈ‘{U/ ăœŸrcTE6' úëÜÍ·œ~o`Q $A la une) #A la une( "A la une& !A la une$ A la une#5Solutions Linux 2007"+Solutions Linux" A la une" A la une A la une A la une A la une A la une A la une A la une A la une A la une A la une A la une A la une A la une;python programmation fr$Kpython programmation fr advices$ Kpython programmation advices fr $ Kpython programmation advices fr $ Kpython programmation advices fr $ Kpython programmation advices fr  +python haypo fr 5mdjango python web web-frameworks didacticiels fr5mdjango python web web-frameworks didacticiels fr5mdjango python web web-frameworks didacticiels fr5mdjango python web web-frameworks didacticiels fr@django python web web-frameworks didacticiels fr templatesAapps django fr libs python1learning python fr-django python fr :…ńâÓö„–‡xiZK<& üíȚÎż°Ą’ƒteVG8) ûëÚÊșȘšŠzl^RD3' ęïáĐÂŽŠ˜…^#conferences ]humour \Python [Python ZPythonYPolitique Xprojet WPython VPython UPython TPython SGeekRPolitique QPython PGeek OVidĂ©o NPythonMA la une LA la uneKA la uneJA la uneIA la uneHA la uneùGAFPY NewsśFA la une”EA la une DA la uneb CA la unea BA la uneH AA la uneG @A la uneF ?A la uneE >A la uneD =A la uneC <A la uneA ;A la une@ :A la une? 9A la une> 8A la une=7AFPY News< 6A la une< 5A la une9 4A la une835Solutions Linux 200772+Solutions Linux7 1A la une6 0A la une5 /A la une4 .A la une2 -A la une1 ,A la une0 +A la une/*!FOSDEM2007. )fosdem.(AFPY News. 'A la une. &A la une- %A la une* ŁÎŁ‚(, AA}}[Chttp://www.afpy.org/Members/odeckmyn/plone-fr-mailinglist2008-08-31 17:41:00.8556472007-04-24 00:52:11.000000Plone.org a mis Ă  disposition une mailing list plone-frPlone.org a mis Ă  disposition une mailing list plone-fr[Afpy News] Nouvelle Mailing-List PloneNouvelle Mailing-List Plone„/+ iAA‚q‚qw_http://www.afpy.org/Members/jpcw2002/video_rms2008-08-31 17:41:00.8336842007-04-27 07:39:35.000000Le 04 avril 2007 R.M.S himself est venu faire une confĂ©rence sur les logiciels libres Ă  Pau. Vous n'avez pu venir, ou vous voulez revoir la conf ! Voici le lien vers la vidĂ©o.Le 04 avril 2007 R.M.S himself est venu faire une confĂ©rence sur les logiciels libres Ă  Pau. Vous n'avez pu venir, ou vous voulez revoir la conf ! Voici le lien vers la vidĂ©o.[Afpy News] VidĂ©o de Richard Stallman en français !VidĂ©o de Richard Stallman en français ! WW…&-1AAƒƒ7http://www.afpy.org/Members/pilotsystems/solutions-linux-2007-support-presentation2008-08-31 17:41:00.8745192007-04-05 05:32:30.000000Zope et Plone Ă©taient prĂ©sents au salon Solutions Linux 2007, du 30 janvier au 1er fĂ©vrier 2007. Retrouvez ici les supports utilisĂ©s pour les prĂ©sentations de la session Zope/Plone.Zope et Plone Ă©taient prĂ©sents au salon Solutions Linux 2007, du 30 janvier au 1er fĂ©vrier 2007. Retrouvez ici les supports utilisĂ©s pour les prĂ©sentations de la session Zope/Plone.[Afpy News] Support de prĂ©sentation de la session Zope/Plone Ă  Solutions Linux 2007Support de prĂ©sentation de la session Zope/Plone Ă  Solutions Linux 2007 &&‡W. yAA†?†?I1http://www.afpy.org/Members/ogrisel/slides-fosdem-20072008-08-31 17:41:00.8968302007-03-27 15:06:23.000000Voici enfin mes slides pour les prĂ©sentations que j'ai eu le plaisir de donner dans la devroom python de l'Ă©dition 2007 du FOSDEM Ă  Bruxelles en fĂ©vrier dernier. Les sujets prĂ©sentĂ©s Ă©taient les suivants: dĂ©veloppement dirigĂ© par les tests et la documentation, packaging avec les eggs (distutils et setuptools), les interfaces et les composants Zope3 et le traitement XML avec lxml et (c)ElementTree.Voici enfin mes slides pour les prĂ©sentations que j'ai eu le plaisir de donner dans la devroom python de l'Ă©dition 2007 du FOSDEM Ă  Bruxelles en fĂ©vrier dernier. Les sujets prĂ©sentĂ©s Ă©taient les suivants: dĂ©veloppement dirigĂ© par les tests et la documentation, packaging avec les eggs (distutils et setuptools), les interfaces et les composants Zope3 et le traitement XML avec lxml et (c)ElementTree.[Afpy News] Slides FOSDEM 2007Slides FOSDEM 2007 ìŻì@0 {AA11A)http://www.afpy.org/Members/gawel/news/afpyro-mars-20072008-08-31 17:41:00.9435682007-03-22 05:29:52.000000C'est encore lui !C'est encore lui ![Afpy News] AFPyro de marsAFPyro de mars„N/ _AAƒ9ƒ9S;http://www.afpy.org/Members/jpcw2002/gcal2008-08-31 17:41:00.9226482007-03-22 06:07:12.000000Nouveau ! Consultez et abonnez-vous au calendrier public de l'AFPY. Vous serez ainsi automatiquement informĂ©s des prochains AFPYRO ou encore des confĂ©rences des JournĂ©es Francophones Python du 26 et 27 mai 2007.Nouveau ! Consultez et abonnez-vous au calendrier public de l'AFPY. Vous serez ainsi automatiquement informĂ©s des prochains AFPYRO ou encore des confĂ©rences des JournĂ©es Francophones Python du 26 et 27 mai 2007.[Afpy News] Le calendrier de l'AFPYLe calendrier de l'AFPY f‚M”[„H”f,<[http://www.afpy.org/Members/Gwen/afpyro1http://www.afpy.org/Members/sdouche/photos-evenement-afpy1<0{http://www.afpy.org/Members/gawel/news/afpyro-mars-20070 77ƒF1 AA‚‚]Ehttp://www.afpy.org/Members/sdouche/photos-evenement-afpy2008-08-31 17:41:00.9658242007-02-28 09:00:45.000000Je viens de publier les photos de ces Ă©vĂ©nements sur mon site photo. D'autres sont Ă  venir (notamment la derniĂšre rĂ©union Afpy).Je viens de publier les photos de ces Ă©vĂ©nements sur mon site photo. D'autres sont Ă  venir (notamment la derniĂšre rĂ©union Afpy).[Afpy News] Photos SL 2007 & Fosdem 2007Photos SL 2007 & Fosdem 2007 žž„E2 iAAƒ/ƒ/O7http://www.afpy.org/Members/ogrisel/fosdem20072008-08-31 17:41:00.9867632007-02-11 13:44:28.000000L'AFPy sera prĂ©sente lors du Free and Open Source Developers European Meeting (FOSDEM) le weekend du 24/25 fĂ©vrier 2007 Ă  Bruxelles. Nous y animons cette annĂ©e et pour la premiĂšre fois une devroom Python.L'AFPy sera prĂ©sente lors du Free and Open Source Developers European Meeting (FOSDEM) le weekend du 24/25 fĂ©vrier 2007 Ă  Bruxelles. Nous y animons cette annĂ©e et pour la premiĂšre fois une devroom Python.[Afpy News] L'AFPy au FOSDEM 2007L'AFPy au FOSDEM 2007 ƒl3 sAA‚K‚KU=http://www.afpy.org/Members/odeckmyn/plone3-preview2008-08-31 17:41:01.0112482007-02-02 05:31:01.000000A l'occasion du salon Solutions Linux 2007, qui s'est tenu au CNIT Ă  Paris, un coin du voile a Ă©tĂ© levĂ© sur le futur de Plone, avec une preview de Plone 3.A l'occasion du salon Solutions Linux 2007, qui s'est tenu au CNIT Ă  Paris, un coin du voile a Ă©tĂ© levĂ© sur le futur de Plone, avec une preview de Plone 3.[Afpy News] Plone au futur proche...Plone au futur proche... Óӄ*49AA}};#http://www.afpy.org/Members/pilotsystems/ouverture-d-une-instance-plone25-sur-objectis2008-08-31 17:41:01.0318552006-11-30 00:27:18.000000Pilot Systems ouvre une instance Plone 2.5 sur Objectis, son service d'hĂ©bergement gratuit et offre Ă  l'AFPY 30 sites.Pilot Systems ouvre une instance Plone 2.5 sur Objectis, son service d'hĂ©bergement gratuit et offre Ă  l'AFPY 30 sites.[Afpy News] Ouverture d'une instance Plone 2.5 chez l'hĂ©bergeur Zope gratuit ObjectisOuverture d'une instance Plone 2.5 chez l'hĂ©bergeur Zope gratuit Objectis V„V‚+6 yAAI1http://www.afpy.org/Members/gawel/news/afpyro_novembre2008-08-31 17:41:01.0745842006-11-13 12:11:06.000000Ca y est, il est arrivĂ© ! C'est lui, le troisiĂšme jeudi du mois !Ca y est, il est arrivĂ© ! C'est lui, le troisiĂšme jeudi du mois ![Afpy News] AFPyro de NovembreAFPyro de Novembre„y5 1AA‚u‚uhttp://www.afpy.org/Members/christopher/reunion_afpy_belgique_charleroi_9_dec_20062008-08-31 17:41:01.0530782006-11-24 05:54:26.000000La rĂ©union de l'AFPy (Association Francophone de Python) se tiendra le samedi 9 dĂ©cembre 2006 Ă  Charleroi. Nous invitons tous nos amis Belges francophones Ă  nous y rejoindre !La rĂ©union de l'AFPy (Association Francophone de Python) se tiendra le samedi 9 dĂ©cembre 2006 Ă  Charleroi. Nous invitons tous nos amis Belges francophones Ă  nous y rejoindre ![Afpy News] RĂ©union de l'AFPy le samedi 9 dĂ©cembre Ă  Charleroi, BERĂ©union de l'AFPy le samedi 9 dĂ©cembre Ă  Charleroi, BE 00ƒM7 5AAOOwhttp://www.afpy.org/Members/pilotsystems/solutions-linux-2007-presence-de-zope-plone2008-08-31 17:41:01.0976982006-11-04 07:24:47.000000Zope et Plone seront prĂ©sents au salon Solutions Linux 2007, du 30 janvier au 1er fĂ©vrier 2007.Zope et Plone seront prĂ©sents au salon Solutions Linux 2007, du 30 janvier au 1er fĂ©vrier 2007.[Afpy News] Zope et Plone prĂ©sents au salon Solutions Linux 2007Zope et Plone prĂ©sents au salon Solutions Linux 2007 //…N8 {AAƒƒghttp://www.afpy.org/Members/JP/conf_calcul_scientifique2008-08-31 17:41:01.1219612006-11-02 13:25:27.000000ConfĂ©rence sur le thĂšme du calcul scientifique avec Python sur Paris le Jeudi 14 dĂ©cembre 2006 On devrait y aborder l'interfaçage avec le FORTRAN, le C/C++ ainsi que la bibliothĂšque Python NumĂ©rique (numpy ?) et les bibliothĂšques graphiques.ConfĂ©rence sur le thĂšme du calcul scientifique avec Python sur Paris le Jeudi 14 dĂ©cembre 2006 On devrait y aborder l'interfaçage avec le FORTRAN, le C/C++ ainsi que la bibliothĂšque Python NumĂ©rique (numpy ?) et les bibliothĂšques graphiques.[Afpy News] Python et calcul scientifique le 14 dĂ©cembrePython et calcul scientifique le 14 dĂ©cembre *=*‚:  AAYY_Ghttp://www.afpy.org/Members/tarek/afpynews.2006-10-04.86413297752008-08-31 17:41:01.1696422006-10-03 15:04:10.000000Un rĂ©sumĂ© exhaustif sur pycheesecakeUn rĂ©sumĂ© exhaustif sur pycheesecake[Afpy News] Les outils de tests en PythonLes outils de tests en Pythonƒ@9 wAA‚-‚-E-http://www.afpy.org/Members/gawel/news/afpyro_octobre2008-08-31 17:41:01.1476172006-10-16 12:53:20.000000Le 3Ăšme jeudi du mois approche. Il est temps pour nous de vous annoncer l'Ă©vĂ©nement qui, sans nul doute, marquera les esprits pour longtemps.Le 3Ăšme jeudi du mois approche. Il est temps pour nous de vous annoncer l'Ă©vĂ©nement qui, sans nul doute, marquera les esprits pour longtemps.[Afpy News] AFPyro d'OctobreAFPyro d'Octobre ÇDŽ6;UAAqqE-http://www.afpy.org/Members/pilotsystems/annonces-pilotsystems/pilot-systems-support-formation-plone2008-08-31 17:41:01.1938972006-10-02 12:53:49.000000Pilot Systems publie un suppport de formation Plone sous licence Creative Commons, Ă  tĂ©lĂ©charger gratuitement !Pilot Systems publie un suppport de formation Plone sous licence Creative Commons, Ă  tĂ©lĂ©charger gratuitement ![Afpy News] Pilot Systems publie un support de formation Plone sous licence Creative CommonsPilot Systems publie un support de formation Plone sous licence Creative Commons ځR=  AA]Ehttp://www.afpy.org/Members/tarek/afpynews.2006-07-06.99450476672008-08-31 17:41:01.2371072006-09-24 06:43:18.000000le feu !le feu ![Afpy News] Session Python RMLL Ă  NancySession Python RMLL Ă  Nancy„&< [AAƒ!ƒ!E-http://www.afpy.org/Members/Gwen/afpyro2008-08-31 17:41:01.2138582006-08-14 11:58:39.000000AFPyROÂź est un apĂ©ro qui permet aux membres de se rencontrer. Le but de l'AFPyROÂź est de consolider les relations entre membre de l'AFPY et d'apporter des solutions pour faire Ă©voluer l'association.AFPyROÂź est un apĂ©ro qui permet aux membres de se rencontrer. Le but de l'AFPyROÂź est de consolider les relations entre membre de l'AFPY et d'apporter des solutions pour faire Ă©voluer l'association.[Afpy News] AFPyRO sur ParisAFPyRO sur Paris JžpB ÄŽFś°fڒJFJ http://www.afpy.org/Members/tarek/afpynews.2006-01-09.2799716765JFI http://www.afpy.org/Members/tarek/afpynews.2006-01-20.0363351618I=H}http://www.afpy.org/Members/maikroeder/reunion_mars_2006HKGhttp://www.afpy.org/Members/maikroeder/afpynews.2006-03-11.7356760527GHFhttp://www.afpy.org/Members/ogrisel/afpynews.2006-03-16.2652246222FEE http://www.afpy.org/Members/Gwen/afpynews.2006-03-20.4863586905EMDhttp://www.afpy.org/Members/ogrisel/afpynews.lxml.2006-03-21.4441473844DFC http://www.afpy.org/Members/tarek/afpynews.2006-03-28.1323348854C4Bkhttp://www.afpy.org/Members/salvatore/karriblogBFA http://www.afpy.org/Members/tarek/afpynews.2006-05-18.7307192188A4@khttp://www.afpy.org/Members/gawel/news/aidez-le@,?[http://www.afpy.org/Members/Gwen/zenoss?F> http://www.afpy.org/Members/tarek/afpynews.2006-07-04.5091654834>F= http://www.afpy.org/Members/tarek/afpynews.2006-07-06.9945047667= lÙl‚j? [AA# http://www.afpy.org/Members/Gwen/zenoss2008-08-31 17:41:01.3003422006-06-07 11:33:09.000000Zenoss, sous licence GPL, est construit avec Zope et Python.Zenoss, sous licence GPL, est construit avec Zope et Python.[Afpy News] Zenoss, plate-forme d'administration et de supervision rĂ©seau.Zenoss, plate-forme d'administration et de supervision rĂ©seau.‚$>  AA{{Q9http://www.afpy.org/Members/tarek/afpynews.2006-07-04.50916548342008-08-31 17:41:01.2785732006-07-04 03:23:39.000000Slides Europython - (zope-cookbook.org, CPSBayes, Ajax)Slides Europython - (zope-cookbook.org, CPSBayes, Ajax)[Afpy News] Slides Europython 2006Slides Europython 2006 mpPB kAASS7http://www.afpy.org/Members/salvatore/karriblog2008-08-31 17:41:01.3730422006-04-19 00:37:07.000000CrĂ©ation d'un blog avec Karrigell.CrĂ©ation d'un blog avec Karrigell.[Afpy News] KarriBlogKarriBlogzA  AAKKW?http://www.afpy.org/Members/tarek/afpynews.2006-05-18.73071921882008-08-31 17:41:01.3464392006-05-18 04:48:03.000000Les rĂ©servations sont ouvertesLes rĂ©servations sont ouvertes[Afpy News] Europython: c'est parti !Europython: c'est parti !ƒ@ kAA}}K3http://www.afpy.org/Members/gawel/news/aidez-le2008-08-31 17:41:01.3219882006-05-25 07:32:07.000000Nous en appelons Ă  votre gĂ©nĂ©rositĂ© pour que notre membre et ami David Convent puisse s'acheter un nouveau portable.Nous en appelons Ă  votre gĂ©nĂ©rositĂ© pour que notre membre et ami David Convent puisse s'acheter un nouveau portable.[Afpy News] A votre bon coeur !A votre bon coeur ! żż‚>C  AA  [Chttp://www.afpy.org/Members/tarek/afpynews.2006-03-28.13233488542008-08-31 17:41:01.3942622006-03-27 18:03:15.000000OyĂ© OyĂ©, la rĂ©union d'Avril aura finalement lieu le.. 6 maiOyĂ© OyĂ©, la rĂ©union d'Avril aura finalement lieu le.. 6 mai[Afpy News] RĂ©union de l'AFPY le 6 MaiRĂ©union de l'AFPY le 6 Mai Öֆ'D AA„Q„Qu]http://www.afpy.org/Members/ogrisel/afpynews.lxml.2006-03-21.44414738442008-08-31 17:41:01.4177532006-03-21 08:07:10.000000lxml est une implĂ©mentation alternative de l'API d'ElementTree basĂ©e sur les excellentes bibliothĂšques C libxml2/libxslt. lxml apporte donc des fonctions supplĂ©mentaires par rapport Ă  (c)ElementTree comme la gestion des standards XPATH, XSLT et la validation par XMLSchemas et RelaxNG.lxml est une implĂ©mentation alternative de l'API d'ElementTree basĂ©e sur les excellentes bibliothĂšques C libxml2/libxslt. lxml apporte donc des fonctions supplĂ©mentaires par rapport Ă  (c)ElementTree comme la gestion des standards XPATH, XSLT et la validation par XMLSchemas et RelaxNG.[Afpy News] lxml 0.9 est chez le marchand de fromagelxml 0.9 est chez le marchand de fromage .B.„F AA‚/‚/mhttp://www.afpy.org/Members/ogrisel/afpynews.2006-03-16.26522462222008-08-31 17:41:01.4643112006-03-15 18:05:59.000000Voici une nouvelle version plus conviviale Ă  utiliser de l'utilitaire de couverture de tests prĂ©sentĂ© lors de la derniĂšre rĂ©union de l'AFPy.Voici une nouvelle version plus conviviale Ă  utiliser de l'utilitaire de couverture de tests prĂ©sentĂ© lors de la derniĂšre rĂ©union de l'AFPy.[Afpy News] trace2html 0.2.0 est chez le marchand de fromagetrace2html 0.2.0 est chez le marchand de fromageƒ;E  AAwwkShttp://www.afpy.org/Members/Gwen/afpynews.2006-03-20.48635869052008-08-31 17:41:01.4410372006-03-20 02:46:25.000000Ce Lundi 20 Mars est la journĂ©e de la Francophonie, en tant qu'association Francophone nous tenions Ă  le signaler !Ce Lundi 20 Mars est la journĂ©e de la Francophonie, en tant qu'association Francophone nous tenions Ă  le signaler ![Afpy News] 20 Mars JournĂ©e de la Francophonie20 Mars JournĂ©e de la Francophonie SĄS‚KH }AA_Ghttp://www.afpy.org/Members/maikroeder/reunion_mars_20062008-08-31 17:41:01.5163852006-03-11 08:02:48.000000Vous ĂȘtes invitĂ©s Ă  la prochaine rĂ©union de l'AFPY le 11 mars 2006.Vous ĂȘtes invitĂ©s Ă  la prochaine rĂ©union de l'AFPY le 11 mars 2006.[Afpy News] RĂ©union de l'AFPY le 11 marsRĂ©union de l'AFPY le 11 mars‚\G AAyymhttp://www.afpy.org/Members/maikroeder/afpynews.2006-03-11.73567605272008-08-31 17:41:01.4862142006-03-18 01:07:37.000000Votez pour la date de la prochaine rĂ©union de l'AFPY.Votez pour la date de la prochaine rĂ©union de l'AFPY.[Afpy News] Planification de la prochaine rĂ©union de l'AFPYPlanification de la prochaine rĂ©union de l'AFPY e‚PJ  AA--I1http://www.afpy.org/Members/tarek/afpynews.2006-01-09.27997167652008-08-31 17:41:01.5629762006-01-26 02:38:32.000000Ă  Paris, les 23 & 24 mars 2006, la confĂ©rence agile sur les mĂ©thodes agiles !Ă  Paris, les 23 & 24 mars 2006, la confĂ©rence agile sur les mĂ©thodes agiles ![Afpy News] XP Day France 2006XP Day France 2006ƒI  AAMMqYhttp://www.afpy.org/Members/tarek/afpynews.2006-01-20.03633516182008-08-31 17:41:01.5378712006-01-26 02:38:09.000000"Programmation Python", nouveau livre sur Python par Tarek ZiadĂ©, sortie aux Ă©ditions Eyrolles"Programmation Python", nouveau livre sur Python par Tarek ZiadĂ©, sortie aux Ă©ditions Eyrolles[Afpy News] Sortie du livre "Programmation Python"Sortie du livre "Programmation Python" è{èƒL AA]]W?http://www.afpy.org/Members/lunatik/afpynews.2006-02-03.29246876162008-08-31 17:41:01.6209042006-02-05 03:05:28.000000Un petit sondage dont le rĂ©sultat servira Ă  offrir d'autres espaces que Zope sur le portail de l'AFPy.Un petit sondage dont le rĂ©sultat servira Ă  offrir d'autres espaces que Zope sur le portail de l'AFPy.[Afpy News] Quel Python pour le web ?Quel Python pour le web ?ƒK AAqq5http://www.afpy.org/Members/ldarnis/afpynews.2006-02-09.39998747982008-08-31 17:41:01.6014822006-02-09 13:33:01.000000SednaBAO est un outil entiĂšrement dĂ©veloppĂ© en Python et OpenSource, c'est dans les grandes lignes un mini-ETL.SednaBAO est un outil entiĂšrement dĂ©veloppĂ© en Python et OpenSource, c'est dans les grandes lignes un mini-ETL.[Afpy News] SednaBAOSednaBAO H¶lÊ{*Ùˆ9ê™HOVhttp://www.afpy.org/news/Python/2005/11/13/afpynews.2005-11-13.5702501252VOUhttp://www.afpy.org/news/Python/2005/11/13/afpynews.2005-11-13.5727835071UMThttp://www.afpy.org/news/Zope/2005/11/13/afpynews.2005-11-13.5741429411TMShttp://www.afpy.org/news/Zope/2005/11/13/afpynews.2005-11-13.5755398470SORhttp://www.afpy.org/news/Python/2005/11/21/afpynews.2005-11-21.5120187147ROQhttp://www.afpy.org/news/Python/2005/11/23/afpynews.2005-11-23.6460336121QOPhttp://www.afpy.org/news/Python/2006/01/04/afpynews.2006-01-04.3077751921PMOhttp://www.afpy.org/news/Zope/2006/01/04/afpynews.2006-01-04.3083028280OONhttp://www.afpy.org/news/Python/2006/01/04/afpynews.2006-01-04.3085145761NOMhttp://www.afpy.org/news/Python/2006/01/04/afpynews.2006-01-04.3086966740MHLhttp://www.afpy.org/Members/lunatik/afpynews.2006-02-03.2924687616LHKhttp://www.afpy.org/Members/ldarnis/afpynews.2006-02-09.3999874798K ˆű¶ˆ‚+O AAqq[Chttp://www.afpy.org/news/Zope/2006/01/04/afpynews.2006-01-04.30830282802008-08-31 17:41:01.6791772006-01-04 14:05:08.000000Chris McDonough lance meld3, une variation de l'ouChris McDonough lance meld3, une variation de l'ou[Afpy News] meld3, remplaçant de ZPT ?meld3, remplaçant de ZPT ?‚?N AAqqmUhttp://www.afpy.org/news/Python/2006/01/04/afpynews.2006-01-04.30851457612008-08-31 17:41:01.6597022006-01-04 14:05:08.000000l'implementation .NET de Python Jim Hugunin, arrivl'implementation .NET de Python Jim Hugunin, arriv[Afpy News] Sortie de la beta 1 d'IronPython 1.0Sortie de la beta 1 d'IronPython 1.0‚M AAqq3http://www.afpy.org/news/Python/2006/01/04/afpynews.2006-01-04.30869667402008-08-31 17:41:01.6402722006-01-04 14:05:08.000000Petit module pour monter et dĂ©monter des systĂšmePetit module pour monter et dĂ©monter des systĂšme[Afpy News] mountpymountpy 0 r0‚?R AAoooWhttp://www.afpy.org/news/Python/2005/11/21/afpynews.2005-11-21.51201871472008-08-31 17:41:01.7471412005-11-21 12:38:31.000000Voici le dernier rĂ©sumĂ© des activitĂ©s des coreVoici le dernier rĂ©sumĂ© des activitĂ©s des core[Afpy News] RĂ©sumĂ© des activitĂ©s de python-devRĂ©sumĂ© des activitĂ©s de python-dev‚+Q AAoo[Chttp://www.afpy.org/news/Python/2005/11/23/afpynews.2005-11-23.64603361212008-08-31 17:41:01.7251562005-11-23 03:34:06.000000Voici la liste des talks de Pycon 2006. ProgrammeVoici la liste des talks de Pycon 2006. Programme[Afpy News] Programme Python Pycon 2006Programme Python Pycon 2006‚]P AAeMhttp://www.afpy.org/news/Python/2006/01/04/afpynews.2006-01-04.30777519212008-08-31 17:41:01.7054132006-01-26 02:38:59.000000Voici le programme final pour PyCon 2006. Relativement allĂ©chant...Voici le programme final pour PyCon 2006. Relativement allĂ©chant...[Afpy News] Le programme final de Pycon 2006Le programme final de Pycon 2006 šâŒš‚U AAqqM5http://www.afpy.org/news/Python/2005/11/13/afpynews.2005-11-13.57278350712008-08-31 17:41:01.8063252005-11-13 03:49:32.000000Django propose un nouveau framework pour la lecturDjango propose un nouveau framework pour la lectur[Afpy News] RSS/Atom dans DjangoRSS/Atom dans Django‚#T AAooU=http://www.afpy.org/news/Zope/2005/11/13/afpynews.2005-11-13.57414294112008-08-31 17:41:01.7865992005-11-13 03:49:34.000000evan publie une recette pour proposer un systĂšmeevan publie une recette pour proposer un systĂšme[Afpy News] Templating OOO dans ZopeTemplating OOO dans Zope‚S AAqqK3http://www.afpy.org/news/Zope/2005/11/13/afpynews.2005-11-13.57553984702008-08-31 17:41:01.7668942005-11-13 03:49:35.000000Sortie de la version 3.3.8, derniĂšre version de dSortie de la version 3.3.8, derniĂšre version de d[Afpy News] Sortie de CPS 3.3.8Sortie de CPS 3.3.8 ŽæšŽ‚X AAmmK3http://www.afpy.org/news/Zope/2005/11/03/afpynews.2005-11-03.63918942262008-08-31 17:41:01.8770092005-11-03 14:57:19.000000Sortie de Zope 2.8.4. Plus d'infos ici: http://Sortie de Zope 2.8.4. Plus d'infos ici: http://[Afpy News] Zope 2.8.4 releasedZope 2.8.4 released‚;W /AAqqaIhttp://www.afpy.org/news/PythonDailyUrl/2005/11/03/afpynews.2005-11-03.64003586812008-08-31 17:41:01.8459782005-11-03 14:57:20.000000On connaissait la colorisation de code Python en hOn connaissait la colorisation de code Python en h[Afpy News] Colorisation de code, en XHTMLColorisation de code, en XHTML‚V AAqqE-http://www.afpy.org/news/Python/2005/11/13/afpynews.2005-11-13.57025012522008-08-31 17:41:01.8262082005-11-13 03:49:31.000000Voidspace nous offre une petite introduction Ă  laVoidspace nous offre une petite introduction Ă  la[Afpy News] Introduction OOPIntroduction OOP B§X žgœdĉBEb http://www.afpy.org/Members/Gwen/afpynews.2005-10-06.7453169728b9auhttp://www.afpy.org/Members/lunatik/news_section_jobaO`http://www.afpy.org/news/Python/2005/11/01/afpynews.2005-11-01.8205421555`M_http://www.afpy.org/news/Zope/2005/11/01/afpynews.2005-11-01.8213649566_W^/http://www.afpy.org/news/PythonDailyUrl/2005/11/01/afpynews.2005-11-01.8220441722^W]/http://www.afpy.org/news/PythonDailyUrl/2005/11/01/afpynews.2005-11-01.8224176250]O\http://www.afpy.org/news/Python/2005/11/01/afpynews.2005-11-01.8229290185\O[http://www.afpy.org/news/Python/2005/11/03/afpynews.2005-11-03.6351889722[OZhttp://www.afpy.org/news/Python/2005/11/03/afpynews.2005-11-03.6365552106ZMYhttp://www.afpy.org/news/Zope/2005/11/03/afpynews.2005-11-03.6384026847YMXhttp://www.afpy.org/news/Zope/2005/11/03/afpynews.2005-11-03.6391894226XWW/http://www.afpy.org/news/PythonDailyUrl/2005/11/03/afpynews.2005-11-03.6400358681W kđÒk‚d[ AAoo{http://www.afpy.org/news/Python/2005/11/03/afpynews.2005-11-03.63518897222008-08-31 17:41:01.9428812005-11-03 14:57:15.000000Jonathan Kolyer implĂ©mente un client/serveur bitJonathan Kolyer implĂ©mente un client/serveur bit[Afpy News] Exemple de code: client-serveur bittorrent avec TwistedExemple de code: client-serveur bittorrent avec Twisted‚Z AAqqI1http://www.afpy.org/news/Python/2005/11/03/afpynews.2005-11-03.63655521062008-08-31 17:41:01.9228482005-11-03 14:57:16.000000PyPy est l'extraordinaire rĂ©implĂ©mentation de PyPyPy est l'extraordinaire rĂ©implĂ©mentation de Py[Afpy News] Sortie de PyPy 0.8Sortie de PyPy 0.8‚ Y AAoo?'http://www.afpy.org/news/Zope/2005/11/03/afpynews.2005-11-03.63840268472008-08-31 17:41:01.8970232005-11-12 02:44:12.000000zrails a comme objectif de faciliter la crĂ©ationzrails a comme objectif de faciliter la crĂ©ation[Afpy News] zope on railszope on rails >ș>‚y] /AAqqhttp://www.afpy.org/news/PythonDailyUrl/2005/11/01/afpynews.2005-11-01.82241762502008-08-31 17:41:01.9832252005-10-31 15:37:02.000000Shane Hathaway explique les diffĂ©rentes approchesShane Hathaway explique les diffĂ©rentes approches[Afpy News] Shane Hathaway analyse les frameworks web Python disponiblesShane Hathaway analyse les frameworks web Python disponibles‚C\ AAqqqYhttp://www.afpy.org/news/Python/2005/11/01/afpynews.2005-11-01.82292901852008-08-31 17:41:01.9630672005-10-31 15:37:03.000000Bouquin sur Twisted trĂšs prochainement disponibleBouquin sur Twisted trĂšs prochainement disponible[Afpy News] Twisted Network Programming EssentialsTwisted Network Programming Essentials |Ž€|‚` AA]]C+http://www.afpy.org/news/Python/2005/11/01/afpynews.2005-11-01.82054215552008-08-31 17:41:02.0582762005-10-31 15:37:00.000000dnspython est un toolkit DNS pour Pythondnspython est un toolkit DNS pour Python[Afpy News] dnspython 1.3.5dnspython 1.3.5‚1_ AAqqaIhttp://www.afpy.org/news/Zope/2005/11/01/afpynews.2005-11-01.82136495662008-08-31 17:41:02.0353072005-10-31 15:37:01.000000Chris McDonough dĂ©brief sur le sprint qui a eu liChris McDonough dĂ©brief sur le sprint qui a eu li[Afpy News] Sprint 'GoldgEgg' Ă  Zope CorpSprint 'GoldgEgg' Ă  Zope Corp‚I^ /AAqqoWhttp://www.afpy.org/news/PythonDailyUrl/2005/11/01/afpynews.2005-11-01.82204417222008-08-31 17:41:02.0034262005-10-31 15:37:02.000000Ned Batchelder prĂ©sente des alternatives pour lesNed Batchelder prĂ©sente des alternatives pour les[Afpy News] Alternatives pour les tests unitairesAlternatives pour les tests unitaires /R*/xc AA[[C+http://www.afpy.org/Members/ogrisel/afpynews.2005-09-17.93610381322008-08-31 17:41:02.1449862005-09-18 02:42:49.000000Annonce de la sortie de oodoctest 0.1.0Annonce de la sortie de oodoctest 0.1.0[Afpy News] oodoctest 0.1.0oodoctest 0.1.0‚%b  AAoo_Ghttp://www.afpy.org/Members/Gwen/afpynews.2005-10-06.74531697282008-08-31 17:41:02.1204612005-10-06 05:54:31.000000Veuillez nous excuser pour la gĂȘne occasionnĂ©e.Veuillez nous excuser pour la gĂȘne occasionnĂ©e.[Afpy News] afpy.org de nouveau en ligne.afpy.org de nouveau en ligne.ƒ+a uAAuuiQhttp://www.afpy.org/Members/lunatik/news_section_job2008-08-31 17:41:02.0836742005-10-19 10:42:46.000000Le portail possĂšde Ă  prĂ©sent une nouvelle section toute prĂȘte pour diffuser des offres d'emploi du monde Python.Le portail possĂšde Ă  prĂ©sent une nouvelle section toute prĂȘte pour diffuser des offres d'emploi du monde Python.[Afpy News] Nouvelle section : Offres d'emploiNouvelle section : Offres d'emploi X¶]łZ Čc ±XWm/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2489075785mWl/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2495791195lWk/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.3135040785kMjhttp://www.afpy.org/news/Zope/2005/07/20/afpynews.2005-07-20.4462780597jWi/http://www.afpy.org/news/PythonDailyUrl/2005/07/20/afpynews.2005-07-20.4522556308iMhhttp://www.afpy.org/news/Zope/2005/07/20/afpynews.2005-07-20.4547599945hWg/http://www.afpy.org/news/PythonDailyUrl/2005/07/20/afpynews.2005-07-20.4569960892gOfhttp://www.afpy.org/news/Python/2005/07/20/afpynews.2005-07-20.4599038494fWe/http://www.afpy.org/news/PythonDailyUrl/2005/07/20/afpynews.2005-07-20.4619221027eWd/http://www.afpy.org/news/PythonDailyUrl/2005/07/20/afpynews.2005-07-20.4641712047dHchttp://www.afpy.org/Members/ogrisel/afpynews.2005-09-17.9361038132c :Æ|:‚?f AAoooWhttp://www.afpy.org/news/Python/2005/07/20/afpynews.2005-07-20.45990384942008-08-31 17:41:02.2064042005-07-19 16:25:07.000000Naissance de Ido, le 30 juin, arborant fiĂšrementNaissance de Ido, le 30 juin, arborant fiĂšrement[Afpy News] Twisted.Child #1: Bravo Ă  Luc et NoaTwisted.Child #1: Bravo Ă  Luc et Noa‚Ge /AAqqmUhttp://www.afpy.org/news/PythonDailyUrl/2005/07/20/afpynews.2005-07-20.46192210272008-08-31 17:41:02.1859582005-07-19 15:34:22.000000Cette recette explique comment rendre homogĂšne leCette recette explique comment rendre homogĂšne le[Afpy News] Normalisation du retour Ă  la ligne.Normalisation du retour Ă  la ligne.‚7d /AAwwW?http://www.afpy.org/news/PythonDailyUrl/2005/07/20/afpynews.2005-07-20.46417120472008-08-31 17:41:02.1654802005-07-19 15:34:24.000000Dmitry Dvoinikov présente une recette pour contrÃDmitry Dvoinikov présente une recette pour contrÃ[Afpy News] Decorators pour mĂ©thodesDecorators pour mĂ©thodes -Êž-‚ni /AAqq{http://www.afpy.org/news/PythonDailyUrl/2005/07/20/afpynews.2005-07-20.45225563082008-08-31 17:41:02.2696902005-07-19 15:34:12.000000Ce petit script permet de scanner un rĂ©pertoire eCe petit script permet de scanner un rĂ©pertoire e[Afpy News] Script pour scanner les modules Python d'un rĂ©pertoireScript pour scanner les modules Python d'un rĂ©pertoire‚)h AAqqYAhttp://www.afpy.org/news/Zope/2005/07/20/afpynews.2005-07-20.45475999452008-08-31 17:41:02.2474252005-07-19 15:34:14.000000PluggableAuthService est un outil extrĂȘment souplPluggableAuthService est un outil extrĂȘment soupl[Afpy News] PluggableAuthService 1.1b2PluggableAuthService 1.1b2‚3g /AAqqYAhttp://www.afpy.org/news/PythonDailyUrl/2005/07/20/afpynews.2005-07-20.45699608922008-08-31 17:41:02.2269082005-07-19 15:34:17.000000Tres Seaver converti CMF pour le baser sur des intTres Seaver converti CMF pour le baser sur des int[Afpy News] Interfaces Zope 3 pour CMFInterfaces Zope 3 pour CMF FŽF‚Ek /AAoomUhttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.31350407852008-08-31 17:41:02.3336562005-06-14 15:48:33.000000Nuxeo a publié la version beta 2 de son coNuxeo a publié la version beta 2 de son co[Afpy News] CPSSharedCalendar 1.0 beta 2 publiĂ©CPSSharedCalendar 1.0 beta 2 publiĂ©‚oj AAqqhttp://www.afpy.org/news/Zope/2005/07/20/afpynews.2005-07-20.44627805972008-08-31 17:41:02.3128612005-07-19 15:34:06.000000Ce produit modifie la maniĂšre dont les tracebacksCe produit modifie la maniĂšre dont les tracebacks[Afpy News] Visual Traceback - coloration syntaxique des tracebacks ZopeVisual Traceback - coloration syntaxique des tracebacks Zope f ‚ n /AAqq3http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24827762452008-08-31 17:41:02.3958552005-06-14 15:47:28.000000Stelios Xanthakis a publié la version 0.5 dStelios Xanthakis a publié la version 0.5 d[Afpy News] pyc 0.5pyc 0.5‚Cm /AAookShttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24890757852008-08-31 17:41:02.3751142005-06-14 15:47:29.000000Webworks Sweden propose un nouveau Plone trainingWebworks Sweden propose un nouveau Plone training[Afpy News] Plone training Ă  Stansted, LondresPlone training Ă  Stansted, Londresƒl /AAkkA)http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24957911952008-08-31 17:41:02.3543672005-06-14 15:47:29.000000Anand Pillai présente une recette pour sAnand Pillai présente une recette pour s[Afpy News] Serializer/deserializer simple d'XML utilisant des dictionaires et marshallingSerializer/deserializer simple d'XML utilisant des dictionaires et marshalling -§NőœCê‘8߆-Wx/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2390508767xWw/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2395052432wWv/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2400219351vWu/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2408894392uWt/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2419811514tWs/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2429044102sWr/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2441898297rWq/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2448031682qWp/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2460014955pWo/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2475415976oWn/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2482776245n 5™q5‚9q /AAooaIhttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24480316822008-08-31 17:41:02.4601072005-06-14 15:47:25.000000Glyph Lefkowitz recherche des personnes surqualGlyph Lefkowitz recherche des personnes surqual[Afpy News] OĂč sont allĂ© tous les hobos?OĂč sont allĂ© tous les hobos?‚%p /AAooM5http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24600149552008-08-31 17:41:02.4373592005-06-14 15:47:26.000000Robert Brewer rapporte quelques contributions autRobert Brewer rapporte quelques contributions aut[Afpy News] CherryPy WSGI marcheCherryPy WSGI marche‚do /AAqq qhttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24754159762008-08-31 17:41:02.4165862005-06-14 15:47:27.000000Cette version 1.7.1 du navigateur web Epiphany pouCette version 1.7.1 du navigateur web Epiphany pou[Afpy News] Epiphany 1.7.1 ajoute des liens natifs vers PythonEpiphany 1.7.1 ajoute des liens natifs vers Python kæÀk‚Rt /AAaaohttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24198115142008-08-31 17:41:02.5237222005-06-14 15:47:22.000000Drools est un moteur de règles ReteDrools est un moteur de règles Rete[Afpy News] Drools 2.0 permet d'Ă©crire des rĂšgles en PythonDrools 2.0 permet d'Ă©crire des rĂšgles en Python‚#s /AAooK3http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24290441022008-08-31 17:41:02.5027002005-06-14 15:47:23.000000Glyph Lefkowitz ne sait plus quoi dire depuis qu'Glyph Lefkowitz ne sait plus quoi dire depuis qu'[Afpy News] Twisted Ă  l'Ă©coleTwisted Ă  l'Ă©cole‚r /AAoo?'http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24418982972008-08-31 17:41:02.4817082005-06-14 15:47:24.000000James Stone a publié la version 0.6.0 de TJames Stone a publié la version 0.6.0 de T[Afpy News] TunaPie 0.6.0TunaPie 0.6.0 J€J‚3v /AAoo[Chttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24002193512008-08-31 17:41:02.5658722005-06-14 15:47:20.000000La fondation Shuttleworth a publié la versLa fondation Shuttleworth a publié la vers[Afpy News] SchoolTool 0.10 RC1 publiĂ©SchoolTool 0.10 RC1 publiĂ©‚}u /AAkk'http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.24088943922008-08-31 17:41:02.5447922005-06-14 15:47:21.000000Simon Wittber présente une réimplSimon Wittber présente une réimpl[Afpy News] SĂ©rialisation de type Python simple plus sĂ»re, deuxiĂšme partieSĂ©rialisation de type Python simple plus sĂ»re, deuxiĂšme partie Jź˜J‚Ky /AAoos[http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.23796379812008-08-31 17:41:02.6306762005-06-14 15:47:18.000000Chui Tey écrit que la mise à jour dChui Tey écrit que la mise à jour d[Afpy News] Mise Ă  jour des Web Folders casse ZopeMise Ă  jour des Web Folders casse Zope‚x /AAoo;#http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.23905087672008-08-31 17:41:02.6079942005-06-14 15:47:19.000000Jonathan Ellis explique les changements de la verJonathan Ellis explique les changements de la ver[Afpy News] Spyce 2.0.2Spyce 2.0.2‚Ow /AAoow_http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.23950524322008-08-31 17:41:02.5868972005-06-14 15:47:19.000000Tim Morgan a publié la version 0.6.2 de ReTim Morgan a publié la version 0.6.2 de Re[Afpy News] React Application Framework 0.6.2 publiĂ©React Application Framework 0.6.2 publiĂ© %§NőœCê‘6ۀ%X/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.9018927116ƒX/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.9030035699‚X/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.9042947992X/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.9058342033€W/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.9069029856W~/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.9077967314~W}/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.9092675311}W|/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2346553697|W{/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2359147570{Wz/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2375383931zWy/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.2379637981y €âȘ€‚'| /AAooO7http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.23465536972008-08-31 17:41:02.7055032005-06-14 15:47:14.000000Will Guaraldi vient de lire l'article "FunctWill Guaraldi vient de lire l'article "Funct[Afpy News] Tester dans PyBlosxomTester dans PyBlosxom‚5{ /AAoo]Ehttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.23591475702008-08-31 17:41:02.6841802005-06-14 15:47:16.000000Hans Nowak est prêt à donner des droHans Nowak est prêt à donner des dro[Afpy News] Qui veut travailler sur Wax?Qui veut travailler sur Wax?‚z /AAooC+http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.23753839312008-08-31 17:41:02.6627792005-06-14 15:47:17.000000Will Guaraldi décrit les nouveautésWill Guaraldi décrit les nouveautés[Afpy News] PyBlosxom 1.2.1PyBlosxom 1.2.1 8¶d8‚) /AAkkU=http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.90690298562008-08-31 17:41:02.7695222005-06-14 15:25:07.000000Un article dans ZopeWiki explique les deux maniUn article dans ZopeWiki explique les deux mani[Afpy News] Connecter Zope Ă  OracleConnecter Zope Ă  Oracle‚O~ /AAggghttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.90779673142008-08-31 17:41:02.7481752005-06-14 15:25:08.000000Le programme ”été de codeLe programme ”été de code[Afpy News] La PSF participe Ă  l'Ă©tĂ© de code de GoogleLa PSF participe Ă  l'Ă©tĂ© de code de Google‚G} /AAoooWhttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.90926753112008-08-31 17:41:02.7268232005-06-14 15:25:09.000000Steven Rainwater rapport pour robots.net: "ESteven Rainwater rapport pour robots.net: "E[Afpy News] DARPA GC team GPLs drive-by-wire codeDARPA GC team GPLs drive-by-wire code 6ĂW6‚ /AAooE-http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.90300356992008-08-31 17:41:02.8359602005-06-14 15:25:03.000000Ronny De Winter a sorti la version 1.1 de QuotesVRonny De Winter a sorti la version 1.1 de QuotesV[Afpy News] QuotesViewer 1.1QuotesViewer 1.1‚h /AAoowhttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.90429479922008-08-31 17:41:02.8138742005-06-14 15:25:04.000000Dans un article pour NewsForge, Donna Snow concluDans un article pour NewsForge, Donna Snow conclu[Afpy News] Plone CMS pour les applications entreprise d'intranetPlone CMS pour les applications entreprise d'intranet‚9 /AAqq_Ghttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.90583420332008-08-31 17:41:02.7908682005-06-14 15:25:06.000000Ian Bicking explique les tests fonctionnels dans PIan Bicking explique les tests fonctionnels dans P[Afpy News] Tests fonctionnels dans PasteTests fonctionnels dans Paste Rç‡R‚1 /AAooYAhttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.89771926582008-08-31 17:41:02.9012882005-06-14 15:24:57.000000Andy McKay a testé l'installeur de Plone pAndy McKay a testé l'installeur de Plone p[Afpy News] Mac me rend confus parfoisMac me rend confus parfois‚\ /AAmmmhttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.89985620142008-08-31 17:41:02.8791582005-06-14 15:25:00.000000Richard Philip présente une recette d'uneRichard Philip présente une recette d'une[Afpy News] VĂ©rifier la validitĂ© d'un nom de fichier POSIXVĂ©rifier la validitĂ© d'un nom de fichier POSIX‚ /AAqq;#http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.90189271162008-08-31 17:41:02.8575492005-06-14 15:25:02.000000Damien Miller a sorti la version 0.8.5 de flowd, uDamien Miller a sorti la version 0.8.5 de flowd, u[Afpy News] flowd 0.8.5flowd 0.8.5 r„Jï”9Țƒ(ÍrX /http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.1795737749X /http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.1835876151ŒX /http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.1853889563‹X /http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.1872227583ŠX /http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.1883400888‰X/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.1892575036ˆX/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.1904991394‡X/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.1914916222†X/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.8977192658…X/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.8998562014„ uăÎu‚U /AAqq{chttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.18925750362008-08-31 17:41:02.9662972005-06-14 15:13:09.000000Tim Morgan a publié la version 0.6.1 du fraTim Morgan a publié la version 0.6.1 du fra[Afpy News] Sortie du React Application Framework 0.6.1Sortie du React Application Framework 0.6.1‚ /AAoo9!http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.19049913942008-08-31 17:41:02.9446022005-06-14 15:13:10.000000L'équipe de Five a publié Five 1.0.L'équipe de Five a publié Five 1.0.[Afpy News] Five 1.0.1Five 1.0.1‚ /AAooA)http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.19149162222008-08-31 17:41:02.9229142005-06-14 15:13:11.000000Andrew Sterian a publié la version 6-1.0.4Andrew Sterian a publié la version 6-1.0.4[Afpy News] Pyepix 6-1.0.4Pyepix 6-1.0.4 VëÌV‚r /AAqqhttp://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.18538895632008-08-31 17:41:03.0340192005-06-14 15:13:05.000000Jonathan Ellis teste vos connaissances de Python aJonathan Ellis teste vos connaissances de Python a[Afpy News] À quel point est-ce que vous connaissez Python? (Part 7)À quel point est-ce que vous connaissez Python? (Part 7)‚ /AAqqA)http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.18722275832008-08-31 17:41:03.0119922005-06-14 15:13:07.000000L'équipe de développement SchoolToolL'équipe de développement SchoolTool[Afpy News] schoolbell 1.1schoolbell 1.1‚ /AAqq7http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.18834008882008-08-31 17:41:02.9895842005-06-14 15:13:08.000000Le Knowledge Media Research Center a publiéLe Knowledge Media Research Center a publié[Afpy News] Bebop 0.6Bebop 0.6 ™áʙ‚- /AAqqS;http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.17527754162008-08-31 17:41:03.1003692005-06-14 15:12:55.000000Tomasz Bieruta presente une recette pour le tri deTomasz Bieruta presente une recette pour le tri de[Afpy News] Trie de grands fichiersTrie de grands fichiers‚ /AAqq9!http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.17957377492008-08-31 17:41:03.0782492005-06-14 15:12:59.000000Chris Stawarz a sorti la version 0.1.0 de i2py, prChris Stawarz a sorti la version 0.1.0 de i2py, pr[Afpy News] i2py 0.1.0i2py 0.1.0‚ /AAooC+http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.18358761512008-08-31 17:41:03.0561052005-06-14 15:13:03.000000Yann Ramin a sorti la version 1.3.0 de Cymbeline,Yann Ramin a sorti la version 1.3.0 de Cymbeline,[Afpy News] Cymbeline 1.3.0Cymbeline 1.3.0 Q„[¶[­ZÿŹQX/http://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.4111624184˜Phttp://www.afpy.org/news/Python/2005/05/31/afpynews.2005-05-31.4120417068—X/http://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.4125849014–Phttp://www.afpy.org/news/Python/2005/05/31/afpynews.2005-05-31.4132828522•X/http://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.4138602375”Phttp://www.afpy.org/news/Python/2005/05/31/afpynews.2005-05-31.4145970377“X/http://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.4151359797’X/http://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.4156818651‘G http://www.afpy.org/Members/tarek/afpynews.2005-06-04.9550486073G http://www.afpy.org/Members/tarek/afpynews.2005-06-08.8230545173X/http://www.afpy.org/news/PythonDailyUrl/2005/06/15/afpynews.2005-06-15.1752775416Ž ÎȘ‚ /AAoo?'http://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.41568186512008-08-31 17:41:03.1732142005-05-30 16:23:35.000000Twisted Matrix Laboratories sort la version 2.0.1Twisted Matrix Laboratories sort la version 2.0.1[Afpy News] Twisted 2.0.1Twisted 2.0.1‚   AAooYAhttp://www.afpy.org/Members/tarek/afpynews.2005-06-04.95504860732008-08-31 17:41:03.1473652005-06-06 23:38:59.000000CrĂ©ation de la page "BaromĂštre Sourceforge.net"CrĂ©ation de la page "BaromĂštre Sourceforge.net"[Afpy News] BaromĂštre Sourceforge.netBaromĂštre Sourceforge.net‚.  AAS;http://www.afpy.org/Members/tarek/afpynews.2005-06-08.82305451732008-08-31 17:41:03.1224922005-06-08 07:14:01.000000CPSMailAccess est un webmail open source complet pour CPS3CPSMailAccess est un webmail open source complet pour CPS3[Afpy News] CPSMailAccess 1.0 beta1CPSMailAccess 1.0 beta1 )œ)‚o AAqqhttp://www.afpy.org/news/Python/2005/05/31/afpynews.2005-05-31.41459703772008-08-31 17:41:03.2180732005-05-30 16:23:34.000000Vincenzo Ciaglia interview Guido van Rossum pour TVincenzo Ciaglia interview Guido van Rossum pour T[Afpy News] Vincenzo Ciaglia interview Guido van Rossum pour TuxJournalVincenzo Ciaglia interview Guido van Rossum pour TuxJournal‚` /AAqqmhttp://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.41513597972008-08-31 17:41:03.1956602005-05-30 16:23:35.000000Dave Beckett sort la version 1.0.1 de Redland, uneDave Beckett sort la version 1.0.1 de Redland, une[Afpy News] Redland, bibliothĂšque RDF accessible par PythonRedland, bibliothĂšque RDF accessible par Python ]ą]‚A AAqqoWhttp://www.afpy.org/news/Python/2005/05/31/afpynews.2005-05-31.41328285222008-08-31 17:41:03.2629142005-05-30 16:23:33.000000Dave Vehrs sort la version 0.5.4 de PyDSH, un enemDave Vehrs sort la version 0.5.4 de PyDSH, un enem[Afpy News] PyDSH, pour l'administration distantePyDSH, pour l'administration distante‚Z /AAooihttp://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.41386023752008-08-31 17:41:03.2404582005-05-30 16:23:34.000000dag annonce la sortie de dstat 0.6.0 of dstat, undag annonce la sortie de dstat 0.6.0 of dstat, un[Afpy News] Oubliez vmstat, iostat et ifstat. Voici dstat.Oubliez vmstat, iostat et ifstat. Voici dstat. m˜m‚' AAqqU=http://www.afpy.org/news/Python/2005/05/31/afpynews.2005-05-31.41204170682008-08-31 17:41:03.3352512005-05-30 16:23:32.000000Art Haas a sorti la version 25 de PythonCAD, un prArt Haas a sorti la version 25 de PythonCAD, un pr[Afpy News] PythonCAD, 25Ăšme du nomPythonCAD, 25Ăšme du nom‚d /AAqq qhttp://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.41258490142008-08-31 17:41:03.2853632005-05-30 16:23:32.000000Phillip Eby dĂ©crit EasyInstall, un outil en lignePhillip Eby dĂ©crit EasyInstall, un outil en ligne[Afpy News] EasyInstall, installation facile de paquets PythonEasyInstall, installation facile de paquets Python OšO‚G AAqqw_http://www.afpy.org/news/Zope/2005/05/31/afpynews.2005-05-31.40983046392008-08-31 17:41:03.3819652005-05-30 16:23:30.000000Ian Bicking a annoncĂ© la sortie de la version 0.2Ian Bicking a annoncĂ© la sortie de la version 0.2[Afpy News] Faites du Zope Page Template sous WebwareFaites du Zope Page Template sous Webware‚b /AAqqohttp://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.41116241842008-08-31 17:41:03.3578302005-05-30 16:23:31.000000Mark Williamson pense que Python est Ă  la traĂźneMark Williamson pense que Python est Ă  la traĂźne[Afpy News] Le systĂšme de documentation Python Ă  la traĂźneLe systĂšme de documentation Python Ă  la traĂźne FŻTùžCđšWüĄFX#/http://www.afpy.org/news/PythonDailyUrl/2005/05/24/afpynews.2005-05-24.6642554250ŁX"/http://www.afpy.org/news/PythonDailyUrl/2005/05/24/afpynews.2005-05-24.6662301216ąX!/http://www.afpy.org/news/PythonDailyUrl/2005/05/24/afpynews.2005-05-24.6680158369ĄN http://www.afpy.org/news/Zope/2005/05/24/afpynews.2005-05-24.6700054782 E http://www.afpy.org/Members/macadames/FCKeditor.Plone_2.0.1_fcŸPhttp://www.afpy.org/news/Python/2005/05/31/afpynews.2005-05-31.3943045256žX/http://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.4016539540X/http://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.4055688125œX/http://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.4074414767›X/http://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.4089192514šNhttp://www.afpy.org/news/Zope/2005/05/31/afpynews.2005-05-31.4098304639™ t”t‚= /AAqqcKhttp://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.40744147672008-08-31 17:41:03.4273982005-05-30 16:23:27.000000Titus Brown prĂ©sent twill 0.7, son systĂšme extenTitus Brown prĂ©sent twill 0.7, son systĂšme exten[Afpy News] Twill, concurrent de Selenium ?Twill, concurrent de Selenium ?‚G /AAqqmUhttp://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.40891925142008-08-31 17:41:03.4046862005-05-30 16:23:29.000000Jonathan Kolyer prĂ©sente une recette pour implĂ©mJonathan Kolyer prĂ©sente une recette pour implĂ©m[Afpy News] Le design pattern Observer en PythonLe design pattern Observer en Python /Š/‚W /AAqq}ehttp://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.40165395402008-08-31 17:41:03.4728042005-05-30 16:23:21.000000Miguel de Icaza et Jody Goldberg ont annoncĂ© la sMiguel de Icaza et Jody Goldberg ont annoncĂ© la s[Afpy News] Le tableur Gnumeric est extensible en PythonLe tableur Gnumeric est extensible en Python‚r /AAqqhttp://www.afpy.org/news/PythonDailyUrl/2005/05/31/afpynews.2005-05-31.40556881252008-08-31 17:41:03.4500682005-05-30 16:23:25.000000Richard Harris sort la version 0.1.2 d'OpenReleaseRichard Harris sort la version 0.1.2 d'OpenRelease[Afpy News] OpenRelease, pour releaser vos projets open source PythonOpenRelease, pour releaser vos projets open source Python ąȏ‚5 AAoogOhttp://www.afpy.org/news/Zope/2005/05/24/afpynews.2005-05-24.67000547822008-08-31 17:41:03.5411932005-05-24 09:54:30.000000Nouvelle mouture annoncĂ©e par Peter Bengtsson deNouvelle mouture annoncĂ©e par Peter Bengtsson de[Afpy News] IssueTrackerProduct version 0.6.8IssueTrackerProduct version 0.6.8‰N AA‡Y‡Yhttp://www.afpy.org/Members/macadames/FCKeditor.Plone_2.0.1_fc2008-08-31 17:41:03.5184072005-05-24 02:34:35.000000Cette nouvelle version du produit Zope est basĂ©e sur FCKeditor 2.0 FC, la derniĂšf‚Z AAqqohttp://www.afpy.org/news/Python/2005/05/31/afpynews.2005-05-31.39430452562008-08-31 17:41:03.4956382005-05-30 16:23:18.000000Roman Joost a annoncĂ© la sortie de Pywifi 0.2, biRoman Joost a annoncĂ© la sortie de Pywifi 0.2, bi[Afpy News] Pywifi, bibliothĂšque d'accĂšs aux fonctions wifiPywifi, bibliothĂšque d'accĂšs aux fonctions wifire version de l'Ă©diteur HTML FCKeditor, compatible MSIE5.5+ et Gecko (Mozilla, FireFox, Netscape ...), un des meilleurs au monde bien qu'il soit open-source (licence GPL). Cette version est trĂšs stable et peut ĂȘtre mise en production. Elle offre de nouvelles fonctionnalitĂ©s aux utilisateurs de Plone. Le produit est compatible avec n'importe quel CMS basĂ© sur Zope, moyennant quelques adaptations.Cette nouvelle version du produit Zope est basĂ©e sur FCKeditor 2.0 FC, la derniĂšre version de l'Ă©diteur HTML FCKeditor, compatible MSIE5.5+ et Gecko (Mozilla, FireFox, Netscape ...), un des meilleurs au monde bien qu'il soit open-source (licence GPL). Cette version est trĂšs stable et peut ĂȘtre mise en production. Elle offre de nouvelles fonctionnalitĂ©s aux utilisateurs de Plone. Le produit est compatible avec n'importe quel CMS basĂ© sur Zope, moyennant quelques adaptations.[Afpy News] FCKeditor 2.0.1 FC editeur HTML en ligne pour Plone et ZopeFCKeditor 2.0.1 FC editeur HTML en ligne pour Plone et Zope še‚Q# /AAooyahttp://www.afpy.org/news/PythonDailyUrl/2005/05/24/afpynews.2005-05-24.66425542502008-08-31 17:41:03.6117022005-05-24 09:54:24.000000Chris McAvoy est trĂšs impressionĂ© par "Mighty",Chris McAvoy est trĂšs impressionĂ© par "Mighty",[Afpy News] PrĂ©sentation du moteur de template MightyPrĂ©sentation du moteur de template Mighty‚1" /AAqqW?http://www.afpy.org/news/PythonDailyUrl/2005/05/24/afpynews.2005-05-24.66623012162008-08-31 17:41:03.5887102005-05-24 09:54:26.000000pyNetConv permet de faire des conversions d'une mupyNetConv permet de faire des conversions d'une mu[Afpy News] Sortie de pyNetConv 0.8.1Sortie de pyNetConv 0.8.1‚b! /AAqqohttp://www.afpy.org/news/PythonDailyUrl/2005/05/24/afpynews.2005-05-24.66801583692008-08-31 17:41:03.5656962005-05-24 09:54:28.000000Matt Goodall donne une recette de mise en place d'Matt Goodall donne une recette de mise en place d'[Afpy News] Mise en place d'une chaine differĂ©e avec TwistedMise en place d'une chaine differĂ©e avec Twisted ±M‚3& AAqqcKhttp://www.afpy.org/news/Zope/2005/05/24/afpynews.2005-05-24.65593037672008-08-31 17:41:03.6808362005-05-24 09:54:16.000000Paul Everitt, en charge du track Zope d'EuropythonPaul Everitt, en charge du track Zope d'Europython[Afpy News] Le programme Zope Ă  EuroPythonLe programme Zope Ă  EuroPython‚`% AAqq uhttp://www.afpy.org/news/Python/2005/05/24/afpynews.2005-05-24.65857850092008-08-31 17:41:03.6577882005-05-24 09:54:18.000000SurfTheWorld annonce la sortie de la version 0.5.0SurfTheWorld annonce la sortie de la version 0.5.0[Afpy News] Sortie de PyTest 0.5.0, outil de test de haut niveauSortie de PyTest 0.5.0, outil de test de haut niveau‚K$ /AAqqqYhttp://www.afpy.org/news/PythonDailyUrl/2005/05/24/afpynews.2005-05-24.66197180882008-08-31 17:41:03.6347432005-05-24 09:54:22.000000Vibha Tripathi propose un script Python qui permetVibha Tripathi propose un script Python qui permet[Afpy News] un "tail - f" multi-fichiers en Pythonun "tail - f" multi-fichiers en Python =„RŠKúŸDó˜=X./http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1236418124źX-/http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1244890125­N,http://www.afpy.org/news/Zope/2005/05/22/afpynews.2005-05-22.1255211961ŹX+/http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1261572400«X*/http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1266799228ȘN)http://www.afpy.org/news/Zope/2005/05/22/afpynews.2005-05-22.1270984069©X(/http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1276622681šX'/http://www.afpy.org/news/PythonDailyUrl/2005/05/24/afpynews.2005-05-24.6453508879§N&http://www.afpy.org/news/Zope/2005/05/24/afpynews.2005-05-24.6559303767ŠP%http://www.afpy.org/news/Python/2005/05/24/afpynews.2005-05-24.6585785009„X$/http://www.afpy.org/news/PythonDailyUrl/2005/05/24/afpynews.2005-05-24.6619718088€ ]Í–]‚5) AAqqeMhttp://www.afpy.org/news/Zope/2005/05/22/afpynews.2005-05-22.12709840692008-08-31 17:41:03.7517492005-05-21 16:12:07.000000Le projet Zope 3 ECM vient d'ĂȘtre lancĂ©, il propLe projet Zope 3 ECM vient d'ĂȘtre lancĂ©, il prop[Afpy News] Lancement du projet Zope 3 / ECMLancement du projet Zope 3 / ECM‚3( /AAuuU=http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.12766226812008-08-31 17:41:03.7269982005-05-22 01:59:32.000000Andy Todd est trop occupĂ© Ă  jouer sur Python ChallAndy Todd est trop occupĂ© Ă  jouer sur Python Chall[Afpy News] Le site Python ChallengeLe site Python Challenge‚/' /AAqqU=http://www.afpy.org/news/PythonDailyUrl/2005/05/24/afpynews.2005-05-24.64535088792008-08-31 17:41:03.7039072005-05-24 09:54:11.000000AndrĂ© Roberge nous explique le sens du signe Ă©gaAndrĂ© Roberge nous explique le sens du signe Ă©ga[Afpy News] Le sens de "=" en PythonLe sens de "=" en Python iŐ€i‚7, AAqqgOhttp://www.afpy.org/news/Zope/2005/05/22/afpynews.2005-05-22.12552119612008-08-31 17:41:03.8216282005-05-21 16:12:05.000000Tim Morgan vient d'annoncer la sortie de la versioTim Morgan vient d'annoncer la sortie de la versio[Afpy News] React Application Framework 0.5.2React Application Framework 0.5.2‚-+ /AAqqS;http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.12615724002008-08-31 17:41:03.7983422005-05-22 02:00:31.000000Oren Tirosh propose une recette puor crĂ©er des diOren Tirosh propose une recette puor crĂ©er des di[Afpy News] Dictionnaires immuablesDictionnaires immuables‚'* /AAooO7http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.12667992282008-08-31 17:41:03.7750752005-05-22 02:00:01.000000Gerhard HĂ€ring annonce la sortie de PySQLLite 2,Gerhard HĂ€ring annonce la sortie de PySQLLite 2,[Afpy News] Sortie de PySQLLite 2Sortie de PySQLLite 2 mË–m‚%/ /AAqqK3http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.12266010882008-08-31 17:41:03.8918862005-05-22 02:01:51.000000Fredrik Lundh explique que le traitement de l'imagFredrik Lundh explique que le traitement de l'imag[Afpy News] la puissance de PILla puissance de PIL‚1. /AAqqW?http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.12364181242008-08-31 17:41:03.8684972005-05-22 02:01:25.000000Marq Kole: " Python StringTemplate 2.1 est un moteMarq Kole: " Python StringTemplate 2.1 est un mote[Afpy News] Python StringTemplate 2.1Python StringTemplate 2.1‚1- /AAqqW?http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.12448901252008-08-31 17:41:03.8451252005-05-21 16:12:04.000000Ruud Erwig propose une variation de la recette d'ARuud Erwig propose une variation de la recette d'A[Afpy News] Types constants en PythonTypes constants en Python („Jï”9Ț”9Țƒ(X9/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.3812655091čX8/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.4268018235žX7/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.7583522847·X6/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.8200227122¶G5 http://www.afpy.org/Members/tarek/afpynews.2005-05-16.1768343834”X4/http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1149167724ŽX3/http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1179987369łX2/http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1193235947ČX1/http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1209740594±X0/http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1217404826°X//http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.1226601088Ż 2żž2‚h2 /AAqq uhttp://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.11932359472008-08-31 17:41:03.9639192005-05-21 16:11:59.000000Martin LaMonica explique dans son article dans CNeMartin LaMonica explique dans son article dans CNe[Afpy News] Les langages de scripts de plus en plus considĂ©rĂ©sLes langages de scripts de plus en plus considĂ©rĂ©s‚1 /AAqqC+http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.12097405942008-08-31 17:41:03.9403082005-05-21 16:12:01.000000Jean-Yves Mengan dĂ©crit Jpydbg, dans un article dJean-Yves Mengan dĂ©crit Jpydbg, dans un article d[Afpy News] Jpydbg debuggerJpydbg debugger‚=0 /AAqqcKhttp://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.12174048262008-08-31 17:41:03.9152612005-05-21 16:12:01.000000Sean McGrath montre comment utiliser DTracepour prSean McGrath montre comment utiliser DTracepour pr[Afpy News] DTrace, un profiler pour PythonDTrace, un profiler pour Python jÏŒj‚5  AAqqU=http://www.afpy.org/Members/tarek/afpynews.2005-05-16.17683438342008-08-31 17:41:04.0355802005-05-16 14:44:08.000000crĂ©ation de la section "Liens Python journaliers"crĂ©ation de la section "Liens Python journaliers"[Afpy News] Liens Python journaliersLiens Python journaliers‚?4 /AAqqeMhttp://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.11491677242008-08-31 17:41:04.0111692005-05-21 16:11:55.000000Michael Droettboom s'arrache la tĂȘte pour faire fMichael Droettboom s'arrache la tĂȘte pour faire f[Afpy News] wxPython : portabilitĂ© relativewxPython : portabilitĂ© relative‚-3 /AAqqS;http://www.afpy.org/news/PythonDailyUrl/2005/05/22/afpynews.2005-05-22.11799873692008-08-31 17:41:03.9874952005-05-21 16:11:58.000000Annonce de la premiĂšre sortie de PYANO ( Python iAnnonce de la premiĂšre sortie de PYANO ( Python i[Afpy News] PYANO, bibliothĂšque 3DPYANO, bibliothĂšque 3D Ùm‚K8 /AAqqqYhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.42680182352008-08-31 17:41:04.1086522005-05-15 12:30:27.000000Uche Ogbuji est content de voir 4Suite 1.0b1 intĂ©Uche Ogbuji est content de voir 4Suite 1.0b1 intĂ©[Afpy News] 4Suite 1.0b1 pour Fedora Core 4 Test 34Suite 1.0b1 pour Fedora Core 4 Test 3‚h7 /AAqq uhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.75835228472008-08-31 17:41:04.0849692005-05-15 12:35:58.000000NewsForge dĂ©crit la migration du site UNC HealthcNewsForge dĂ©crit la migration du site UNC Healthc[Afpy News] UNC Healthcare trouve que Plone est facile Ă  avalerUNC Healthcare trouve que Plone est facile Ă  avaler‚#6 /AAqqI1http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.82002271222008-08-31 17:41:04.0612922005-05-15 12:37:00.000000Version 2.0a1 de PyDO, une librairie de mapping obVersion 2.0a1 de PyDO, une librairie de mapping ob[Afpy News] PyDO 2.0a1 publiĂ©PyDO 2.0a1 publiĂ© [ŐŽ[‚U; /AAqq{chttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.94401441362008-08-31 17:41:04.1886072005-05-15 12:22:24.000000Michael Swanson couvre le sujet POP3 dans la premiMichael Swanson couvre le sujet POP3 dans la premi[Afpy News] Librairies e-mail de Python, partie 1: POP3Librairies e-mail de Python, partie 1: POP3‚: /AAqqC+http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.18910092982008-08-31 17:41:04.1646642005-05-15 12:26:29.000000Mike Foord a travaillĂ© sur son simple server avecMike Foord a travaillĂ© sur son simple server avec[Afpy News] Le serpent sertLe serpent sert‚'9 /AAqqM5http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.38126550912008-08-31 17:41:04.1407442005-05-15 12:29:41.000000Il semble Ă  Patrick Logan que IronPython pourraitIl semble Ă  Patrick Logan que IronPython pourrait[Afpy News] L'age des dynamiquesL'age des dynamiques r„Jï”9Țƒ(ÍrXC/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.2895863920ĂXB/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.5756006536ÂXA/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.6149806278ÁX@/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.6729801147ÀX?/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.7184272558żX>/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.8075385512ŸX=/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.8643596291œX</http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.9053369939ŒX;/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.9440144136»X:/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.1891009298ș S ÔS‚}> /AAqq! http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.80753855122008-08-31 17:41:04.2607372005-05-15 12:20:07.000000Andrew Kuchling a commencĂ© de chercher un lieu poAndrew Kuchling a commencĂ© de chercher un lieu po[Afpy News] Retour Ă  la case dĂ©part pour trouver un lieu pour PyCon 2006Retour Ă  la case dĂ©part pour trouver un lieu pour PyCon 2006‚1= /AAqqW?http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.86435962912008-08-31 17:41:04.2366412005-05-15 12:21:04.000000Glyph Lefkowitz a rĂ©alisĂ© qu'un des problĂšmes mGlyph Lefkowitz a rĂ©alisĂ© qu'un des problĂšmes m[Afpy News] Meta-roadmap pour TwistedMeta-roadmap pour Twisteds< /AASS7http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.90533699392008-08-31 17:41:04.2126272005-05-15 12:21:45.000000Titus Brown a jouĂ© avec pyparsing.Titus Brown a jouĂ© avec pyparsing.[Afpy News] pyparsingpyparsing J”sJ‚%A /AAqqK3http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.61498062782008-08-31 17:41:04.3508982005-05-15 12:16:55.000000Version 2.6.2 de PyGTK, les bindings Python pour lVersion 2.6.2 de PyGTK, les bindings Python pour l[Afpy News] PyGTK 2.6.2 publiĂ©PyGTK 2.6.2 publiĂ©‚@ /AAqqC+http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.67298011472008-08-31 17:41:04.3089102005-05-15 12:17:53.000000Zoran Isailovski presente une recette pour le pattZoran Isailovski presente une recette pour le patt[Afpy News] Memento closureMemento closure‚h? /AAqq uhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.71842725582008-08-31 17:41:04.2847932005-05-15 12:18:38.000000Robert Leftwich a annoncĂ© un premier jet de son cRobert Leftwich a annoncĂ© un premier jet de son c[Afpy News] Se lancer dans la librairie de classes OO matplotlibSe lancer dans la librairie de classes OO matplotlib B”sB‚-D /AAqqS;http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.23261915582008-08-31 17:41:04.4255542005-05-15 11:53:52.000000Karrigell 2.1.3 a Ă©tĂ© publiĂ©. C'est un frameworKarrigell 2.1.3 a Ă©tĂ© publiĂ©. C'est un framewor[Afpy News] Karrigell 2.1.3 publiĂ©Karrigell 2.1.3 publiĂ©‚C /AAooE-http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.28958639202008-08-31 17:41:04.4012642005-05-15 11:54:50.000000Mike Foord a annoncĂ© la publication de rest2web,Mike Foord a annoncĂ© la publication de rest2web,[Afpy News] rest2web publiĂ©rest2web publiĂ©‚hB /AAqq uhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.57560065362008-08-31 17:41:04.3769012005-05-15 12:16:16.000000Jerol Harrington prĂ©sente une recette simple dĂ©mJerol Harrington prĂ©sente une recette simple dĂ©m[Afpy News] Communiquation entre des processus en utilisant mmapCommuniquation entre des processus en utilisant mmap r„Jï”9Țƒ(ÍrXM/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.6118464261ÍXL/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.6670440606ÌXK/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.7810083004ËXJ/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.8423799980ÊXI/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.9717374105ÉXH/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.0334471074ÈXG/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.0842961113ÇXF/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.1448816754ÆXE/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.1888999393ĆXD/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.2326191558Ä •Ûș•‚!G /AAqqG/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.08429611132008-08-31 17:41:04.4985152005-05-15 11:51:24.000000ttb 0.9.2 a Ă©tĂ© publiĂ©. C'est un navigateur dĂ©ttb 0.9.2 a Ă©tĂ© publiĂ©. C'est un navigateur dĂ©[Afpy News] ttb 0.9.2 publiĂ©ttb 0.9.2 publiĂ©‚F /AAqqC+http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.14488167542008-08-31 17:41:04.4741952005-05-15 11:52:25.000000The Metrics 1.0 a Ă©tĂ© publiĂ©. C'est un logicielThe Metrics 1.0 a Ă©tĂ© publiĂ©. C'est un logiciel[Afpy News] The Metrics 1.0The Metrics 1.0‚!E /AAqqG/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.18889993932008-08-31 17:41:04.4498942005-05-15 11:53:09.000000PyUI2 0.1 a Ă©tĂ© publiĂ©. C'est une librairie d'iPyUI2 0.1 a Ă©tĂ© publiĂ©. C'est une librairie d'i[Afpy News] PyUI2 0.1 publiĂ©PyUI2 0.1 publiĂ© Í‚‚dJ /AAqq qhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.84237999802008-08-31 17:41:04.5716752005-05-15 11:47:22.000000Huu Nguyen prĂ©sente une extension de Pythologic dHuu Nguyen prĂ©sente une extension de Pythologic d[Afpy News] Extension de Pythologic - Syntaxe Prolog en PythonExtension de Pythologic - Syntaxe Prolog en Python‚GI /AAqqmUhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.97173741052008-08-31 17:41:04.5472542005-05-15 11:49:31.000000AndrĂ© Roberge pondĂšre la difficultĂ© de dĂ©ciderAndrĂ© Roberge pondĂšre la difficultĂ© de dĂ©cider[Afpy News] La version 1.0 de rur-ple s'approcheLa version 1.0 de rur-ple s'approche‚/H /AAG/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.03344710742008-08-31 17:41:04.5228432005-05-15 11:50:33.000000Ned Batchelder réfléchit à tous les recettes rÃNed Batchelder réfléchit à tous les recettes rÃ[Afpy News] Enums et switchesEnums et switches ŃŽ‚lM /AAqqyhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.61184642612008-08-31 17:41:04.6473802005-05-15 11:43:32.000000Diego Novella prĂ©sente une autre façon de traiteDiego Novella prĂ©sente une autre façon de traite[Afpy News] Une autre façon de traiter le sujet "automatic super"Une autre façon de traiter le sujet "automatic super"‚?L /AAqqeMhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.66704406062008-08-31 17:41:04.6226942005-05-15 11:44:27.000000SoulSeek pour Linux 1.2.7 a Ă©tĂ© publiĂ©. Il s'agSoulSeek pour Linux 1.2.7 a Ă©tĂ© publiĂ©. Il s'ag[Afpy News] SoulSeek for Linux 1.2.7 publiĂ©SoulSeek for Linux 1.2.7 publiĂ©‚+K /AAqqQ9http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.78100830042008-08-31 17:41:04.5980512005-05-15 11:46:21.000000Tea4CUPS 2.11 a Ă©tĂ© publiĂ©. En termes de fonctiTea4CUPS 2.11 a Ă©tĂ© publiĂ©. En termes de foncti[Afpy News] Tea4CUPS 2.11 releasedTea4CUPS 2.11 released CœC‚UO /AAoo}ehttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.48231740752008-08-31 17:41:04.6966432005-05-15 11:41:22.000000La version 0.8 du RUR Python Learning EnvironmentLa version 0.8 du RUR Python Learning Environment[Afpy News] RUR Python Learning Environment 0.8 releasedRUR Python Learning Environment 0.8 released‚`N /AAooohttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.54138827032008-08-31 17:41:04.6719942005-05-15 11:42:21.000000Will Guaraldi annonce la deuxiĂšme publication deWill Guaraldi annonce la deuxiĂšme publication de[Afpy News] Contributed plugins pack 1.2.1 pour PyBlosxom 1.2Contributed plugins pack 1.2.1 pour PyBlosxom 1.2 r„Jï”9Țƒ(ÍrXW/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.1758404463ŚXV/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.2277132738ÖXU/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.6261286928ŐXT/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.7949663669ÔXS/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.8677561658ÓXR/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.9349777542ÒXQ/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.1378482193ŃXP/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.4122888231ĐXO/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.4823174075ÏXN/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.5413882703Î úKú‚MQ /AAqqs[http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.13784821932008-08-31 17:41:04.7460922005-05-15 11:35:38.000000Version 0.5 du React Application Framework d'appliVersion 0.5 du React Application Framework d'appli[Afpy News] React Application Framework 0.5 publiĂ©React Application Framework 0.5 publiĂ©ƒ1P /AAqqU=http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.41228882312008-08-31 17:41:04.7213202005-05-15 11:40:12.000000Bill Bumgarner a Ă©crit un screen saver inscrit Ă Bill Bumgarner a Ă©crit un screen saver inscrit Ă [Afpy News] Screen saver fondĂ© sur Quartz-Composer pour afficher des flux photo provenant de FlickrScreen saver fondĂ© sur Quartz-Composer pour afficher des flux photo provenant de Flickr [Í[‚nS /AAqq{http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.86775616582008-08-31 17:41:04.7976302005-05-15 11:31:08.000000Le 'Plone Symposium' aura lieu Ă  New Orleans du 2Le 'Plone Symposium' aura lieu Ă  New Orleans du 2[Afpy News] Plone Symposium, New Orleans, 2005: Inscription ouvertePlone Symposium, New Orleans, 2005: Inscription ouverte‚/R /AAqqU=http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.93497775422008-08-31 17:41:04.7726052005-05-15 11:32:15.000000Codeville 0.1.11 a Ă©tĂ© publiĂ©. Codeville est unCodeville 0.1.11 a Ă©tĂ© publiĂ©. Codeville est un[Afpy News] Codeville 0.1.11 publiĂ©Codeville 0.1.11 publiĂ© 2Œi2‚3V /AAwwS;http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.22771327382008-08-31 17:41:04.8725422005-05-15 12:43:48.000000La version 2.1.4 du framework web Karrigell a étÃLa version 2.1.4 du framework web Karrigell a étÃ[Afpy News] Karrigell 2.1.4 publiĂ©Karrigell 2.1.4 publiĂ©‚U /AAqqE-http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.62612869282008-08-31 17:41:04.8475582005-05-15 13:07:06.000000Mike Foord a créé des projets Sourceforge pour rMike Foord a créé des projets Sourceforge pour r[Afpy News] Mike Foord forgeMike Foord forge‚pT /AAqq}http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.79496636692008-08-31 17:41:04.8225702005-05-15 11:29:55.000000Parfois vous avez besoin de chaĂźnes Ă©tant des vrParfois vous avez besoin de chaĂźnes Ă©tant des vr[Afpy News] Rapidement vĂ©rifier si des chaĂźnes sont un identifiantRapidement vĂ©rifier si des chaĂźnes sont un identifiant ƒÓЃ‚Y /AAqqE-http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.01970324522008-08-31 17:41:04.9490482005-05-15 12:40:20.000000Zettai.net s'est associĂ© avec The Ungerleider GroZettai.net s'est associĂ© avec The Ungerleider Gro[Afpy News] Learn@Zettai.netLearn@Zettai.net‚)X /AAqqO7http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.09703972582008-08-31 17:41:04.9225022005-05-15 12:41:37.000000Version 0.6 de Zelenium, un produit Zope 2 pour crVersion 0.6 de Zelenium, un produit Zope 2 pour cr[Afpy News] Zelenium 0.6 releasedZelenium 0.6 released‚)W /AAqqO7http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.17584044632008-08-31 17:41:04.8975332005-05-15 12:42:56.000000Version 0.96 de Marauroa a Ă©tĂ© publiĂ©. Il s'agiVersion 0.96 de Marauroa a Ă©tĂ© publiĂ©. Il s'agi[Afpy News] Marauroa 0.96 publiĂ©Marauroa 0.96 publiĂ© r„Jï”9Țƒ(ÍrXa/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.2809177007áX`/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.3348992141àX_/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.3727239056ßX^/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.4094739638ȚX]/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.4695489968ĘX\/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.5364128792ÜX[/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.2306078814ÛXZ/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.3222571956ÚXY/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.0197032452ÙXX/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.0970397258Ű EčE‚p[ /AAqq}http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.23060788142008-08-31 17:41:05.0012952005-05-15 12:27:11.000000Tarek ZiadĂ© fait un rĂ©sumĂ© de son utilisation dTarek ZiadĂ© fait un rĂ©sumĂ© de son utilisation d[Afpy News] ZAsync pour les actions asynchrones dans Zope, partie #2ZAsync pour les actions asynchrones dans Zope, partie #2‚CZ /AAqqiQhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.32225719562008-08-31 17:41:04.9758892005-05-15 12:28:42.000000Andy McKay pense que l'application Ajax d'Ian BickAndy McKay pense que l'application Ajax d'Ian Bick[Afpy News] ZEO prompt via le web , quelqu'un?ZEO prompt via le web , quelqu'un? 9Ąv9‚9^ /AAqq_Ghttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.40947396382008-08-31 17:41:05.0771042005-05-18 02:32:35.000000Ian Bicking a experimentĂ© avec Ajax (Javascript aIan Bicking a experimentĂ© avec Ajax (Javascript a[Afpy News] Ma premiĂšre application AjaxMa premiĂšre application Ajax‚'] /AAqqM5http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.46954899682008-08-31 17:41:05.0517992005-05-18 02:31:39.000000Ian Bicking tente sa chance d'expliquer Python PasIan Bicking tente sa chance d'expliquer Python Pas[Afpy News] Qu'est-ce que Paste?Qu'est-ce que Paste?‚[\ /AAyyyahttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.53641287922008-08-31 17:41:05.0265262005-05-18 02:39:12.000000Une des idĂ©es que Ian Bicking veut emprunter Ă  RailsUne des idĂ©es que Ian Bicking veut emprunter Ă  Rails[Afpy News] Building testability into web applicationsBuilding testability into web applications Oł‚O‚/a /AAqqU=http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.28091770072008-08-31 17:41:05.1552792005-05-18 02:34:51.000000Michele Simionato presente une recette pour mĂ©morMichele Simionato presente une recette pour mĂ©mor[Afpy News] CrĂ©ation d'objet cachĂ©CrĂ©ation d'objet cachĂ©‚-` /AAqqS;http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.33489921412008-08-31 17:41:05.1293442005-05-15 12:12:15.000000Version 0.11 de Quod Libet, une application pour gVersion 0.11 de Quod Libet, une application pour g[Afpy News] Quod Libet 0.11 publiĂ©Quod Libet 0.11 publiĂ©‚I_ /AAqqoWhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.37272390562008-08-31 17:41:05.1038732005-05-18 02:33:32.000000Grig Gheorghiu a mis Ă  jour la liste d'articles eGrig Gheorghiu a mis Ă  jour la liste d'articles e[Afpy News] Articles et courses sur Agile TestingArticles et courses sur Agile Testing ;á;‚Qd /AAqqw_http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.13822739882008-08-31 17:41:05.2338062005-05-15 12:08:58.000000Uche Ogbuji essaie encore une fois de produire uneUche Ogbuji essaie encore une fois de produire une[Afpy News] Directory listing XML recursive, partie 2Directory listing XML recursive, partie 2‚Mc /AAoou]http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.18202261812008-08-31 17:41:05.2081202005-05-18 02:37:37.000000Ian Bicking a créé un blog pour les actualitĂ©sIan Bicking a créé un blog pour les actualitĂ©s[Afpy News] Blog sur les actualitĂ©s de Python PasteBlog sur les actualitĂ©s de Python Paste‚b /AAqqA)http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.24165573132008-08-31 17:41:05.1824722005-05-18 02:36:45.000000Ian Bicking a assistĂ© Ă  une rencontre de Ruby MeIan Bicking a assistĂ© Ă  une rencontre de Ruby Me[Afpy News] Rencontre RubyRencontre Ruby r„Jï”9Țƒ(ÍrXk/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.7490563055ëXj/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.7791086907êXi/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.8185987276éXh/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.8568060560èXg/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.9075109796çXf/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.9439334803æXe/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.9834779491ćXd/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.1382273988äXc/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.1820226181ăXb/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.2416557313â _”z_‚g /AAoo?'http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.90751097962008-08-31 17:41:05.3299812005-05-15 12:05:07.000000Ori Peleg prĂ©sente une recette pour un proxy quiOri Peleg prĂ©sente une recette pour un proxy qui[Afpy News] ObserverProxyObserverProxy‚7f /AAoo_Ghttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.94393348032008-08-31 17:41:05.3043582005-05-15 12:05:44.000000AndrĂ© Roberge a annoncĂ© la sortie de la versionAndrĂ© Roberge a annoncĂ© la sortie de la version[Afpy News] rur-ple version 0.8.5 publiĂ©rur-ple version 0.8.5 publiĂ©‚Ge /AAqqmUhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.98347794912008-08-31 17:41:05.2594162005-05-15 12:06:23.000000Bill Mill trouve que les "link of the moment" peuvBill Mill trouve que les "link of the moment" peuv[Afpy News] Trouver les posts del.icio.us uniqueTrouver les posts del.icio.us unique ‰ÓŒ‰‚/j /AAqqU=http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.77910869072008-08-31 17:41:05.4264062005-05-15 12:02:59.000000Jonathan Ellis a Ă©crit spyce.el, fournissant un sJonathan Ellis a Ă©crit spyce.el, fournissant un s[Afpy News] Support Emacs pour SpyceSupport Emacs pour Spyce‚i /AAqq9!http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.81859872762008-08-31 17:41:05.3989402005-05-15 12:03:38.000000Max Khesin a jouĂ© avec la librarie de plotting maMax Khesin a jouĂ© avec la librarie de plotting ma[Afpy News] matplotlibmatplotlib‚)h /AAqqO7http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.85680605602008-08-31 17:41:05.3732722005-05-15 12:04:17.000000Uche Ogbuji raconte les problĂšmes que lui et DaveUche Ogbuji raconte les problĂšmes que lui et Dave[Afpy News] 4Suite 1.0b1 via yum?4Suite 1.0b1 via yum? ;Ù~;‚?m /AAqqeMhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.63931246802008-08-31 17:41:05.5066352005-05-15 12:00:39.000000Uche Ogbuji a jouĂ© avec Amara/4Suite et CherryPy,Uche Ogbuji a jouĂ© avec Amara/4Suite et CherryPy,[Afpy News] Quelques dĂ©mos d'Amara/CherryPyQuelques dĂ©mos d'Amara/CherryPy‚Wl /AAqq}ehttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.68579903852008-08-31 17:41:05.4807122005-05-15 12:01:26.000000Uche Ogbuji montre comment utiliser os.walk pour pUche Ogbuji montre comment utiliser os.walk pour p[Afpy News] Directory listing recursive en XML, partie 1Directory listing recursive en XML, partie 1‚#k /AAqqI1http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.74905630552008-08-31 17:41:05.4546812005-05-15 12:02:29.000000Uche Ogbuji discute Xmldiff, un utilitaire pour exUche Ogbuji discute Xmldiff, un utilitaire pour ex[Afpy News] Xmldiff and PicketXmldiff and Picket @„Jï”9Ț’D Ăy@6wmhttp://www.afpy.org/Members/tarek/cps_3.3.3_totośGv http://www.afpy.org/Members/tarek/afpynews.2005-04-16.6206289540öFu http://www.afpy.org/Members/Gwen/afpynews.2005-04-26.4241827735ő5tkhttp://www.afpy.org/Members/jackadam/vitefait32ôKshttp://www.afpy.org/Members/fermigier/afpynews.2005-05-11.8849712385óIrhttp://www.afpy.org/Members/lunatik/afpynews.2005-05-12.2058053038òXq/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.4037245767ńXp/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.4603340206đXo/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.5491563044ïXn/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.5953066992îXm/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.6393124680íXl/http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.6857990385ì 3”v3‚?p /AAqqeMhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.46033402062008-08-31 17:41:05.5843582005-05-15 11:57:40.000000Siegmund FĂŒhringer montre un serveur web sur TwisSiegmund FĂŒhringer montre un serveur web sur Twis[Afpy News] Serveur Twisted reStructuredTextServeur Twisted reStructuredText‚;o /AAqqaIhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.54915630442008-08-31 17:41:05.5584432005-05-15 11:59:09.000000Il est commun de tester si une liste est vide et dIl est commun de tester si une liste est vide et d[Afpy News] Tester si un iterator est videTester si un iterator est vide‚Gn /AAoooWhttp://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.59530669922008-08-31 17:41:05.5325432005-05-15 11:59:55.000000Guyon Moree n'Ă©tait pas dirĂšctement intĂ©ressĂ©Guyon Moree n'Ă©tait pas dirĂšctement intĂ©ressĂ©[Afpy News] Python Challenge solutions - partie 1Python Challenge solutions - partie 1 ŽÙŽ‚Gr AA__ uhttp://www.afpy.org/Members/lunatik/afpynews.2005-05-12.20580530382008-08-31 17:41:05.6405432005-05-12 07:28:31.000000Rencontre XUL / Python autour d'un verre.Rencontre XUL / Python autour d'un verre.[Afpy News] Rencontre XULfr et afpy le jeudi 19 Ă  partir de 19hRencontre XULfr et afpy le jeudi 19 Ă  partir de 19h‚#q /AAooK3http://www.afpy.org/news/PythonDailyUrl/2005/05/15/afpynews.2005-05-15.40372457672008-08-31 17:41:05.6128432005-05-15 11:56:44.000000PyKota 1.22 a Ă©tĂ© publiĂ©. C'est un systĂšme dePyKota 1.22 a Ă©tĂ© publiĂ©. C'est un systĂšme de[Afpy News] PyKota 1.22 publiĂ©PyKota 1.22 publiĂ© ::…Bs AAƒwƒwmUhttp://www.afpy.org/Members/fermigier/afpynews.2005-05-11.88497123852008-08-31 17:41:05.6699862005-05-11 01:58:08.000000Nuxeo est heureux d'annoncer CPSSharedCalendar 1.0beta, un composant de gestion de calendriers avancĂ© et flexible pour Zope, CPS, et, aprĂšs un petit peu de travail d'adaptation, pour les autres CMS bĂątis sur Zope comme le CMF, Plone ou Silva.Nuxeo est heureux d'annoncer CPSSharedCalendar 1.0beta, un composant de gestion de calendriers avancĂ© et flexible pour Zope, CPS, et, aprĂšs un petit peu de travail d'adaptation, pour les autres CMS bĂątis sur Zope comme le CMF, Plone ou Silva.[Afpy News] CPSSharedCalendar 1.0beta disponibleCPSSharedCalendar 1.0beta disponible UŠcU‚ v  AAQQaIhttp://www.afpy.org/Members/tarek/afpynews.2005-04-16.62062895402008-08-31 17:41:05.7483532005-04-16 01:15:37.000000RĂ©sultats des votes des visiteursRĂ©sultats des votes des visiteurs[Afpy News] PyCon : feedback des visiteursPyCon : feedback des visiteurs‚?u  AA++;#http://www.afpy.org/Members/Gwen/afpynews.2005-04-26.42418277352008-08-31 17:41:05.7222722005-04-26 05:34:04.000000Concours professionnel de programmation avec une Ă©preuve d'intĂ©gration Zope !Concours professionnel de programmation avec une Ă©preuve d'intĂ©gration Zope ![Afpy News] TopDev 2005TopDev 2005‚Vt kAAghttp://www.afpy.org/Members/jackadam/vitefait322008-08-31 17:41:05.6961562005-11-14 12:13:12.000000La version 3.2 est utilisable en mode natif ou avec CPS ou Plone.La version 3.2 est utilisable en mode natif ou avec CPS ou Plone.[Afpy News] La version 3.2 de Vitefait est sortie ce jourLa version 3.2 de Vitefait est sortie ce jour K‚0x sAAsss[http://www.afpy.org/Members/jackadam/vitefaitcps31a2008-08-31 17:41:05.8140092005-04-13 06:55:58.000000VitefaitCPS3.1a et Vitefait3.1a sont sortis ce jourVitefaitCPS3.1a et Vitefait3.1a sont sortis ce jour[Afpy News] premiĂšre version stable de VitefaitCPSpremiĂšre version stable de VitefaitCPS1w mAA337http://www.afpy.org/Members/tarek/cps_3.3.3_toto2008-08-31 17:41:05.7751942005-04-25 11:52:01.000000Sortie de CPS 3.3.3Sortie de CPS 3.3.3[Afpy News] CPS 3.3.3CPS 3.3.3 +ÄzFüÄŒB Âx<òČe+7‚ohttp://www.afpy.org/Members/fermigier/livecd-erp5J‚http://www.afpy.org/Members/zyon/concours_programmation_python_2005=‚{http://www.afpy.org/Members/davconvent/interview-pvw-frG‚ http://www.afpy.org/Members/tarek/afpynews.2005-03-22.72546155189‚shttp://www.afpy.org/Members/jackadam/vitefait3.1rc1G‚ http://www.afpy.org/Members/tarek/afpynews.2005-03-22.0820893874G‚ http://www.afpy.org/Members/tarek/afpynews.2005-03-22.32832988313ghttp://www.afpy.org/Members/lunatik/pythonjdnÿG~ http://www.afpy.org/Members/tarek/afpynews.2005-03-31.6687165117ț5}khttp://www.afpy.org/Members/Lawouach/ironpythonę5|khttp://www.afpy.org/Members/jackadam/vitefait31üG{ http://www.afpy.org/Members/tarek/afpynews.2005-04-04.5949027636û1zchttp://www.afpy.org/Members/Gwen/NotesGroupúGy http://www.afpy.org/Members/tarek/afpynews.2005-04-10.2791031007ù9xshttp://www.afpy.org/Members/jackadam/vitefaitcps31aű dd…y  AAƒ_ƒ__Ghttp://www.afpy.org/Members/tarek/afpynews.2005-04-10.27910310072008-08-31 17:41:05.8411032005-04-12 02:28:54.000000Guido van Rossum revient tout juste de PyCon 2005. C'Ă©tait l'occasion pour nous de lui poser quelques questions sur Python... Un grand merci aux membres qui ont proposĂ© des questions [Jiba, Bader, HervĂ©, etc..] - par Tarek ZiadĂ©Guido van Rossum revient tout juste de PyCon 2005. C'Ă©tait l'occasion pour nous de lui poser quelques questions sur Python... Un grand merci aux membres qui ont proposĂ© des questions [Jiba, Bader, HervĂ©, etc..] - par Tarek ZiadĂ©[Afpy News] interview de Guido van Rossuminterview de Guido van Rossum ‰㉂V{  AAcKhttp://www.afpy.org/Members/tarek/afpynews.2005-04-04.59490276362008-08-31 17:41:05.8993782005-04-04 02:58:52.000000Appel Ă  contribution pour les rencontres mondiales du logiciel libre.Appel Ă  contribution pour les rencontres mondiales du logiciel libre.[Afpy News] Appel Ă  contribution RMLL 2005Appel Ă  contribution RMLL 2005„z cAA‚S‚Sihttp://www.afpy.org/Members/Gwen/NotesGroup2008-08-31 17:41:05.8712792005-04-06 07:48:54.000000NotesGroup est une solution Web flexible permettant de crĂ©er rapidement et simplement des espaces de travail collaboratif entre vos collaborateurs et partenaires.NotesGroup est une solution Web flexible permettant de crĂ©er rapidement et simplement des espaces de travail collaboratif entre vos collaborateurs et partenaires.[Afpy News] NotesGroup, ConcentrĂ© de Travail CollaboratifNotesGroup, ConcentrĂ© de Travail Collaboratif š–šj~  AAAAQ9http://www.afpy.org/Members/tarek/afpynews.2005-03-31.66871651172008-08-31 17:41:05.9787412005-03-31 04:19:11.000000Sortie de la version 2.4.1Sortie de la version 2.4.1[Afpy News] Sortie de Python 2.4.1Sortie de Python 2.4.1v} kAAooA)http://www.afpy.org/Members/Lawouach/ironpython2008-08-31 17:41:05.9523452005-03-31 06:16:24.000000Nouvelle version d'IronPython. Du Python sur .NETNouvelle version d'IronPython. Du Python sur .NET[Afpy News] IronPython 0.7IronPython 0.7‚l| kAAEE_Ghttp://www.afpy.org/Members/jackadam/vitefait312008-08-31 17:41:05.9257712005-04-01 13:43:44.000000Des nouvelles fonctionnalitĂ©s concernant la sĂ©curitĂ© et le support des diffĂ©rentes basesDes nouvelles fonctionnalitĂ©s concernant la sĂ©curitĂ© et le support des diffĂ©rentes bases[Afpy News] Vitefait3.1 stable est sortieVitefait3.1 stable est sortie fˆf‚‚  AAssS;http://www.afpy.org/Members/tarek/afpynews.2005-03-22.32832988312008-08-31 17:41:06.0318152005-03-22 05:08:17.000000SchoolBell est un serveur de calendrier sous Zope 3SchoolBell est un serveur de calendrier sous Zope 3[Afpy News] SchoolBell 1.0 annoncĂ©SchoolBell 1.0 annoncĂ©‚t gAAQQ]Ehttp://www.afpy.org/Members/lunatik/pythonjdn2008-08-31 17:41:06.0053252005-03-23 01:19:34.000000Le journal du net section dĂ©veloppeurs fait une prĂ©sentation de Python. Auteur: Xavier Borderie.Le journal du net section dĂ©veloppeurs fait une prĂ©sentation de Python. Auteur: Xavier Borderie.[Afpy News] Python sur JDN DĂ©veloppeursPython sur JDN DĂ©veloppeurs  ’ ƒ‚ sAA[[[Chttp://www.afpy.org/Members/jackadam/vitefait3.1rc12008-08-31 17:41:06.0871322005-03-22 01:51:35.000000Quelques semaines aprĂšs la sortie de Vitefait 3.0, Vitefait 3.1 apporte de nouvelles fonctionnalitĂ©s.Quelques semaines aprĂšs la sortie de Vitefait 3.0, Vitefait 3.1 apporte de nouvelles fonctionnalitĂ©s.[Afpy News] PremiĂšre RC de Vitefait3.1PremiĂšre RC de Vitefait3.1‚j‚  AA==S;http://www.afpy.org/Members/tarek/afpynews.2005-03-22.08208938742008-08-31 17:41:06.0584992005-03-22 02:05:44.000000Google ouvre une section dĂ©diĂ©e aux logiciels open source et met Ă  l'honneur PyGoogleGoogle ouvre une section dĂ©diĂ©e aux logiciels open source et met Ă  l'honneur PyGoogle[Afpy News] PyGoogle et Google CodePyGoogle et Google Code ìƒT‚ {AA‚‚qYhttp://www.afpy.org/Members/davconvent/interview-pvw-fr2008-08-31 17:41:06.1469252005-03-11 05:20:37.000000Interview par Tarek Ziade de Philipp von Weitershausen Ă  propos de son livre sur Zope 3 (Traduction française par David Convent).Interview par Tarek Ziade de Philipp von Weitershausen Ă  propos de son livre sur Zope 3 (Traduction française par David Convent).[Afpy News] Interview de Philipp von WeitershausenInterview de Philipp von Weitershausen‚‚  AA9!http://www.afpy.org/Members/tarek/afpynews.2005-03-22.72546155182008-08-31 17:41:06.1166412005-03-23 10:33:46.000000La confĂ©rence annuelle Python a lieu actuellement Ă  DC.La confĂ©rence annuelle Python a lieu actuellement Ă  DC.[Afpy News] PyCon 2005PyCon 2005 AcA‚‚ oAAmmiQhttp://www.afpy.org/Members/fermigier/livecd-erp52008-08-31 17:41:06.2057352005-02-23 11:18:53.000000La version 1.0rc2 du livceCD ERP est disponible.La version 1.0rc2 du livceCD ERP est disponible.[Afpy News] LiveCD ERP5 disponible en FTP/HTTPLiveCD ERP5 disponible en FTP/HTTP…‚ AAƒWƒWeMhttp://www.afpy.org/Members/zyon/concours_programmation_python_20052008-08-31 17:41:06.1764912005-02-28 09:22:49.000000L'Afpy organise un concours de programmation Python. Le concours consiste Ă  concevoir un programme Python (un 'bot') qui puisse tenir une conversation avec l'utilisateur, dans le mĂȘme esprit qu'Eliza ou que le concours Turing.L'Afpy organise un concours de programmation Python. Le concours consiste Ă  concevoir un programme Python (un 'bot') qui puisse tenir une conversation avec l'utilisateur, dans le mĂȘme esprit qu'Eliza ou que le concours Turing.[Afpy News] Concours de programmation PythonConcours de programmation Python c§„c‚>‚ kAAs[http://www.afpy.org/Members/amine/python_nokia22008-08-31 17:41:06.2889382005-02-21 02:52:40.000000Developper en Python pour les GSM Nokia est enfin possible.Developper en Python pour les GSM Nokia est enfin possible.[Afpy News] Python entre dans la telephonie mobile!Python entre dans la telephonie mobile!~‚ oAAggO7http://www.afpy.org/Members/tarek/afpy_rmlls_20052008-08-31 17:41:06.2600712005-02-23 02:29:22.000000l'afpy organise le track Python des RMLL 2005l'afpy organise le track Python des RMLL 2005[Afpy News] L'AFPY aux RMLLS 2005L'AFPY aux RMLLS 2005‚U‚ AAyahttp://www.afpy.org/Members/zyon/ouverture_tutoriels_python2008-08-31 17:41:06.2325582005-02-23 01:37:58.000000Comme promis la section "Tutoriels Python" est disponible ...Comme promis la section "Tutoriels Python" est disponible ...[Afpy News] Ouverture de la section "Tutoriels python"Ouverture de la section "Tutoriels python" ?»IÎsœbЇ?E‚ http://feeds.feedburner.com/~r/Baderlog/python/~3/322281799/74F‚ http://feeds.feedburner.com/~r/Baderlog/python/~3/322281798/118F‚ http://feeds.feedburner.com/~r/Baderlog/python/~3/322281797/136F‚ http://feeds.feedburner.com/~r/Baderlog/python/~3/322281796/137X‚/http://www.afpy.org/news/PythonDailyUrl/2005/05/09/afpynews.2005-05-11.6733155824X‚/http://www.afpy.org/news/PythonDailyUrl/2005/05/09/afpynews.2005-05-11.7593598020X‚ /http://www.afpy.org/news/PythonDailyUrl/2005/05/09/afpynews.2005-05-11.8528143380 X‚ /http://www.afpy.org/news/PythonDailyUrl/2005/05/09/afpynews.2005-05-11.9388452264 6‚ mhttp://www.afpy.org/Members/zyon/creation_assoce ?‚ http://www.afpy.org/Members/zyon/version_stable_vitefait3 5‚ khttp://www.afpy.org/Members/amine/python_nokia2 7‚ohttp://www.afpy.org/Members/tarek/afpy_rmlls_2005B‚http://www.afpy.org/Members/zyon/ouverture_tutoriels_python ·R·ƒ‚ mAAOOghttp://www.afpy.org/Members/zyon/creation_assoce2008-08-31 17:41:06.3455812005-02-18 16:25:45.000000Nous sommes heureux de vous faire part de la naissance de l'Afpy, Association francophone Python.Nous sommes heureux de vous faire part de la naissance de l'Afpy, Association francophone Python.[Afpy News] CrĂ©ation de l'Association Francophone PythonCrĂ©ation de l'Association Francophone Pythonƒ*‚ AAiioWhttp://www.afpy.org/Members/zyon/version_stable_vitefait32008-08-31 17:41:06.3176762005-02-18 16:26:03.000000AprĂšs prĂšs d'un an de modifications et de tests, 3 versions Beta et 3 RC, Vitefait 3 sort en version stable.AprĂšs prĂšs d'un an de modifications et de tests, 3 versions Beta et 3 RC, Vitefait 3 sort en version stable.[Afpy News] PremiĂšre version stable de Vitefait3PremiĂšre version stable de Vitefait3 .1.‚ /AAGGO7http://www.afpy.org/news/PythonDailyUrl/2005/05/09/afpynews.2005-05-11.85281433802008-08-31 17:41:06.4292342005-05-13 04:17:36.000000CMFBoard 2.2 a Ă©tĂ© publiĂ©.CMFBoard 2.2 a Ă©tĂ© publiĂ©.[Afpy News] CMFBoard 2.2 releasedCMFBoard 2.2 releasedƒK‚ /AA‚‚[Chttp://www.afpy.org/news/PythonDailyUrl/2005/05/09/afpynews.2005-05-11.93884522642008-08-31 17:41:06.4020822005-05-13 04:17:36.000000Zoran Isailovski prĂ©sente une recette dĂ©montrant une vraie Ă©numĂ©ration symbolique avec un accĂšs qualifiĂ© aux valueurs.Zoran Isailovski prĂ©sente une recette dĂ©montrant une vraie Ă©numĂ©ration symbolique avec un accĂšs qualifiĂ© aux valueurs.[Afpy News] First-class enums en PythonFirst-class enums en Python llƒ‚ /AAGGeMhttp://www.afpy.org/news/PythonDailyUrl/2005/05/09/afpynews.2005-05-11.67331558242008-08-31 17:41:07.0597312005-05-13 14:44:39.000000Cedric Otaku n'aime pas la syntaxe des "generator expressions" et d'autres aspects de Python.Cedric Otaku n'aime pas la syntaxe des "generator expressions" et d'autres aspects de Python.[Afpy News] Python continue de me chiffonnerPython continue de me chiffonnerƒu‚ /AA‚A‚AI1http://www.afpy.org/news/PythonDailyUrl/2005/05/09/afpynews.2005-05-11.75935980202008-08-31 17:41:06.4563882005-05-13 13:14:52.000000FlĂĄvio Codeço Coelho prĂ©sente une recette utilisant VPython pour dessiner des "stripcharts" pour un certain nombre de canaux dĂ©fini par l'utilisateur.FlĂĄvio Codeço Coelho prĂ©sente une recette utilisant VPython pour dessiner des "stripcharts" pour un certain nombre de canaux dĂ©fini par l'utilisateur.[Afpy News] Stripchart plotterStripchart plotter łł†I‚  AA…/…/=-http://feeds.feedburner.com/~r/Baderlog/python/~3/322281796/1372008-08-31 17:41:07.0910812007-06-12 16:54:49.000000Dailymotion blogged video REST avec Python VidĂ©o envoyĂ©e par badroucha PrĂ©sentation rapide sur l’architecture Web REST avec le langage de programmation libre Python. Articles similaires ThĂšme Python aux RMLL 2006 (0) PythonSpotting :ĂŸ (0) PrĂ©sentation «QualitĂ© en Python» (0) Pizza au Thon (0) PHP vs Python (0)Dailymotion blogged video REST avec Python VidĂ©o envoyĂ©e par badroucha PrĂ©sentation rapide sur l’architecture Web REST avec le langage de programmation libre Python. Articles similaires ThĂšme Python aux RMLL 2006 (0) PythonSpotting :ĂŸ (0) PrĂ©sentation «QualitĂ© en Python» (0) Pizza au Thon (0) PHP vs Python (0)[Bader] REST avec PythonREST avec Python GG‡5‚  AA…[…[}mhttp://feeds.feedburner.com/~r/Baderlog/python/~3/322281797/1362008-08-31 17:41:07.1236392007-06-09 15:12:40.000000Les JPF 2007 sont un trĂšs bon cru. J’ai pu y croiser pas mal de monde que je voyais qu’online sur l’IRC (#afpy et #python-fr sur irc.freenode.net). Je pense que ça a rĂ©unit pas mal de monde, venant d’univers trĂšs diffĂ©rents: des scientifiques de formation, des zopeurs, des webbistes ou des DLFPien. Cet Ă©vĂšnement a permis [...]Les JPF 2007 sont un trĂšs bon cru. J’ai pu y croiser pas mal de monde que je voyais qu’online sur l’IRC (#afpy et #python-fr sur irc.freenode.net). Je pense que ça a rĂ©unit pas mal de monde, venant d’univers trĂšs diffĂ©rents: des scientifiques de formation, des zopeurs, des webbistes ou des DLFPien. Cet Ă©vĂšnement a permis [...][Bader] Mon bilan des JournĂ©es Francophones Python 2007Mon bilan des JournĂ©es Francophones Python 2007 ]]‡‚  AA…s…sO?http://feeds.feedburner.com/~r/Baderlog/python/~3/322281798/1182008-08-31 17:41:07.1580742007-01-10 11:27:22.000000L’Association Francophone Python (AFPy) a la chance d’avoir une dev room dĂ©diĂ©e Ă  Python au FOSDEM les 25, 26 et 27 fĂ©vrier prochain. Une dev room est une salle, en parrallĂšle des confĂ©rences, dĂ©diĂ©e Ă  un sujet technique et gĂ©rĂ©e par un groupe de personnes qui organisent des rencontres, prĂ©sentations, ou tout autre forme d’évĂšnement. FOSDEM Le [...]L’Association Francophone Python (AFPy) a la chance d’avoir une dev room dĂ©diĂ©e Ă  Python au FOSDEM les 25, 26 et 27 fĂ©vrier prochain. Une dev room est une salle, en parrallĂšle des confĂ©rences, dĂ©diĂ©e Ă  un sujet technique et gĂ©rĂ©e par un groupe de personnes qui organisent des rencontres, prĂ©sentations, ou tout autre forme d’évĂšnement. FOSDEM Le [...][Bader] Dev Room Python au FOSDEMDev Room Python au FOSDEM $$‡X‚  AA††eUhttp://feeds.feedburner.com/~r/Baderlog/python/~3/322281799/742008-08-31 17:41:07.1931352006-09-01 20:00:00.000000Encore une confĂ©rence prĂ©sentĂ©e aux RMLL, celle-ci sur comment Ă©tendre python avec ctypes et pyrex. Elle est en anglais, mais ça reste assez comprĂ©hensible. Presentation about how-to extend Python with ctypes and pyrex. Articles similaires ThĂšme Python aux RMLL 2006 (0) REST avec Python (0) PythonSpotting :ĂŸ (0) PrĂ©sentation «QualitĂ© en Python» (0) Pizza au Thon (0)Encore une confĂ©rence prĂ©sentĂ©e aux RMLL, celle-ci sur comment Ă©tendre python avec ctypes et pyrex. Elle est en anglais, mais ça reste assez comprĂ©hensible. Presentation about how-to extend Python with ctypes and pyrex. Articles similaires ThĂšme Python aux RMLL 2006 (0) REST avec Python (0) PythonSpotting :ĂŸ (0) PrĂ©sentation «QualitĂ© en Python» (0) Pizza au Thon (0)[Bader] Étendre Python avec ctypes et PyrexÉtendre Python avec ctypes et Pyrex6-09-01 20:00:00.000000VoilĂ , j’ai prĂ©sentĂ© ma conf sur la qualitĂ© en Python. L’accueil Ă©tait pas franchement enthousiaste mais il y avait beaucoup de dĂ©butants dans la salle, ceci expliquant peut-ĂȘtre cela. En tout cas je l’ai mis en ligne, on me l’avait demandĂ©, c’est chose faite ! Quality in Python (PDF) Quality in Python (ODP) Articles similaires ThĂšme Python aux RMLL [...]VoilĂ , j’ai prĂ©sentĂ© ma conf sur la qualitĂ© en Python. L’accueil Ă©tait pas franchement enthousiaste mais il y avait beaucoup de dĂ©butants dans la salle, ceci expliquant peut-ĂȘtre cela. En tout cas je l’ai mis en ligne, on me l’avait demandĂ©, c’est chose faite ! Quality in Python (PDF) Quality in Python (ODP) Articles similaires ThĂšme Python aux RMLL [...][Bader] PrĂ©sentation «QualitĂ© en Python»PrĂ©sentation «QualitĂ© en Python» ‘‘‡r‚  AA†1†1eUhttp://feeds.feedburner.com/~r/Baderlog/python/~3/322281800/752008-08-31 17:41:07.223464200  @žp(à˜:ŸHŚ@‚‚%http://www.biologeek.com/django,python,rest,web-frameworks/une-solution-pour-faciliter-la-conception-d-applications-web-restful-avec-django/n‚[http://www.biologeek.com/critique,livre,python/envie-de-developper-agilement-en-python-suivez-le-guide/s‚ehttp://www.biologeek.com/django,informatique,python,web-frameworks,web-semantique/des-vacances-et-des-liens/y‚qhttp://www.biologeek.com/bonnes-pratiques,conferences,django,python,traduction/bonnes-pratiques-et-astuces-python/[‚5http://www.biologeek.com/conferences,django,python/conferences-django-pour-pycon-fr/E‚ http://feeds.feedburner.com/~r/Baderlog/python/~3/322281804/98E‚ http://feeds.feedburner.com/~r/Baderlog/python/~3/322281803/93E‚ http://feeds.feedburner.com/~r/Baderlog/python/~3/322281802/78E‚ http://feeds.feedburner.com/~r/Baderlog/python/~3/322281801/76E‚ http://feeds.feedburner.com/~r/Baderlog/python/~3/322281800/75 nn‡‚  AA…w…w;+http://feeds.feedburner.com/~r/Baderlog/python/~3/322281801/762008-08-31 17:41:07.2547472006-09-01 20:00:00.000000Je suis aux RMLL oĂč je vais prĂ©senter 3 confĂ©rences sur Python. PremiĂšres impressions: mĂȘme si l’Ă©vĂšnement reste assez majoritairement français, bien plus que dans mes souvenirs; les locaux (politiques, mĂ©dias) s’intĂ©ressent Ă  cet Ă©vĂšnement. Il y a pas Ă©normĂ©ment de monde cette annĂ©e pour la premiĂšre journĂ©e mais je pense que au fur et [...]Je suis aux RMLL oĂč je vais prĂ©senter 3 confĂ©rences sur Python. PremiĂšres impressions: mĂȘme si l’Ă©vĂšnement reste assez majoritairement français, bien plus que dans mes souvenirs; les locaux (politiques, mĂ©dias) s’intĂ©ressent Ă  cet Ă©vĂšnement. Il y a pas Ă©normĂ©ment de monde cette annĂ©e pour la premiĂšre journĂ©e mais je pense que au fur et [...][Bader] Coucou des RMLLCoucou des RMLL **‡R‚  AA†#†#SChttp://feeds.feedburner.com/~r/Baderlog/python/~3/322281802/782008-08-31 17:41:07.2884432006-09-01 20:00:00.000000comme certains d’entre vous le savent dĂ©jĂ , la grande messe estivale du logiciel libre, les 7Ăšmes Rencontres Mondiales du Logiciel Libres (RMLL) se tiendront du 4 au 8 juillet 2006 Ă  Vandoeuvre-les-Nancy, dans le bĂątiment 1er cycle de la FacultĂ© des Sciences du campus de l’UniversitĂ© Henri PoincarĂ© – Nancy 1. Allons droit Ă  l’essentiel, un thĂšme Python s’y dĂ©roulera [...]comme certains d’entre vous le savent dĂ©jĂ , la grande messe estivale du logiciel libre, les 7Ăšmes Rencontres Mondiales du Logiciel Libres (RMLL) se tiendront du 4 au 8 juillet 2006 Ă  Vandoeuvre-les-Nancy, dans le bĂątiment 1er cycle de la FacultĂ© des Sciences du campus de l’UniversitĂ© Henri PoincarĂ© – Nancy 1. Allons droit Ă  l’essentiel, un thĂšme Python s’y dĂ©roulera [...][Bader] ThĂšme Python aux RMLL 2006ThĂšme Python aux RMLL 2006 ąˆ|‚  AA‡_‡_A1http://feeds.feedburner.com/~r/Baderlog/python/~3/322281804/982008-08-31 17:41:09.3025632006-09-01 20:00:00.000000J⩆Z‚  AA…G…G7'http://feeds.feedburner.com/~r/Baderlog/python/~3/322281803/932008-08-31 17:41:07.3188242006-09-01 20:00:00.000000PHP et Python sont deux langages de programmation dynamiques qui sont trĂšs utilisĂ©s pour des applications Web. Le premier l’a largement emportĂ© sur le second en terme de part de marchĂ© ! En effet quel hĂ©bergeur grand public ne supporte pas mod_php et plus gĂ©nĂ©ralement l’architecture LAMP ? PHP a tellement envahi le web qu’il est [...]PHP et Python sont deux langages de programmation dynamiques qui sont trĂšs utilisĂ©s pour des applications Web. Le premier l’a largement emportĂ© sur le second en terme de part de marchĂ© ! En effet quel hĂ©bergeur grand public ne supporte pas mod_php et plus gĂ©nĂ©ralement l’architecture LAMP ? PHP a tellement envahi le web qu’il est [...][Bader] PHP vs PythonPHP vs Python€™ai rĂ©alisĂ© une petite affiche en français, format A3 quand mĂȘme, pour promouvoir Python. Cette affiche inspirĂ© de http://apipes.blogspot.com/2005/01/choose-python.html lui-mĂȘme originaire de http://www.adminspotting.org/ inspirĂ© du poster associĂ© au film d’antologie TrainSpotting. J’espĂšre que vous apprĂ©cierez. Articles similaires ThĂšme Python aux RMLL 2006 (0) REST avec Python (0) PrĂ©sentation «QualitĂ© en Python» (0) Pizza au Thon (0) PHP vs Python (0)J’ai rĂ©alisĂ© une petite affiche en français, format A3 quand mĂȘme, pour promouvoir Python. Cette affiche inspirĂ© de http://apipes.blogspot.com/2005/01/choose-python.html lui-mĂȘme originaire de http://www.adminspotting.org/ inspirĂ© du poster associĂ© au film d’antologie TrainSpotting. J’espĂšre que vous apprĂ©cierez. Articles similaires ThĂšme Python aux RMLL 2006 (0) REST avec Python (0) PrĂ©sentation «QualitĂ© en Python» (0) Pizza au Thon (0) PHP vs Python (0)[Bader] PythonSpotting :ĂŸPythonSpotting :ĂŸšon exemplaire, des confĂ©rences de qualitĂ©, des discussions de geek, que du bon. Je me suis enfin dĂ©cidĂ© Ă  mettre les slides en ligne, en attendant les vidĂ©os.

Historique

J'avais déjà présenté Django l'année derniÚre et j'avais vraiment eu l'impression de passer à cÎté de ma conf. Outre le fait que j'étais bien crevé d'avoir mis en ligne django-fr, j'ai relevé 3 gros défauts :

Partant de ce constat, j'ai essayé cette année de :

Alors pari rĂ©ussi ? Mon retour personnel aprĂšs chaque confĂ©rence ci-dessous. J'essaye de retrouver ce que j'ai dit de tĂȘte, ça sera forcĂ©menȘt diffĂ©rent des vidĂ©os qui devraient arriver plus tard : moins de stress, davantage de temps pour Ă©toffer et des liens en bonus.

Pourquoi Django ?

Je n'ai jamais eu de cours de marketing et je hais les commerciaux donc c'est vraiment une épreuve pour moi de « vendre mon produit ». J'ai surtout voulu aller à l'essentiel pour pouvoir ensuite en débattre pendant les questions/réponses.

Pourquoi Django

Avant de parler de Django, il est bon de rappeler les intĂ©rĂȘts d'un framework web face Ă  l'approche plus traditionnelle par applications fonctionnelles toutes prĂȘtes. Qu'est-ce qui a pu suscitĂ© un tel engouement ?

Pourquoi Django

On connaĂźt tous des p«rojets qui commencent avec un projet tout simple (je prends souvent l'exemple du blog car il est assez parlant). Il existe des trillions de moteurs de blog et il est donc aisĂ© d'en prendre un tout fait :

Pourquoi Django

Mais bien (trop) souvent, un projet évolue en cours de route et l'ajout de fonctionnalités (galerie de photos, paiement en ligne, inclusion de vidéos) aboutit finalement à un cahier des charges ressemblant plutÎt à :

Pourquoi Django

Si vous ĂȘtes parti d'un simple moteur de blog rafistolĂ©, il est trĂšs probable que vous arriviez Ă  un rĂ©sultat de piĂštre qualitĂ© :

Pourquoi Django

La solution est de partir d'une approche plus bas nivŹeau : la caisse Ă  outil qui va vous permettre de construire vos propres briques fonctionnelles et de rĂ©aliser un projet de maniĂšre cohĂ©rente et Ă©volutive.

Pourquoi Django

De cette façon, vous allez énormément gagner en agilité, la clé de voûte de la qualité (du projet), de la sérénité (du développeur) et de la satisfaction (du client).

Pourquoi Django

Maintenant que vous ĂȘtes convaincu du bien fondĂ© des frameworks web, il est temps de passer au plat de rĂ©sistance : pourquoi Django ?

Pourquoi Django

Django est Ă©crit en Python et vous permet d'Ă©crire du Python, il n'y a pas de fichiers de configuration en xml (ai-je besoin de rappeler que ­ce format est fait pour les machines ?).

Pourquoi Django

Django est trĂšs facile Ă  prendre en main, il suffit de quelques heures (mĂȘme sans connaĂźtre initialement Python) pour avoir une premiĂšre application qui tourne et en comprendre les principaux concepts.

Pourquoi Django

Face aux deux approches : framework glue vs. réinvention de la roue, Django a choisi la seconde ce qui apporte une cohérence à tous les niveaux (documentation, code, aide, etc) au détriment de sa modularité intrinsÚque.

Pourquoi Django

La documentation est un rĂ©el atout, surtout lorsqu'on dĂ©bute. C'est l'une des meilleures documentation technique que je connaisse et elle est źen train d'ĂȘtre encore amĂ©liorĂ©e !

Pourquoi Django

Je suis assez mal placé pour parler de rapidité de développement avec la refonte de ce blog qui a pris... du temps. Néanmoins, pour l'utiliser quotidiennement, je peux affirmer que le développement avec ce framework permet de concrétiser plus rapidement des projets. L'un des atouts est par exemple de prototyper des applications en des temps records, aprÚs bien sûr les détails prennent plus de temps, comme partout.

Pourquoi Django

L'interface d'administration auto-générée est vraiment utile et participe à l'« effet Wow !© » initial. Difficile de s'en priver ensuite.

Pourquoi Django

L'Ă©chapŻpement des caractĂšres html par dĂ©faut peut ĂȘtre un Ă©lĂ©ment important pour une personne dĂ©butant en dĂ©veloppement web. Ce choix est une rĂ©elle sĂ©curitĂ© si vous ne maĂźtrisez pas vraiment toutes les failles possibles d'un code (mĂȘme s'il serait bon de vous renseigner Ă  ce sujet si c'est le cas !).

Pourquoi Django

Django est simple, autant dans ses concepts que dans leurs mises en application, si vous connaissez Python, vous pouvez mĂȘme sans peine plonger dans le code de Django et dĂ©couvrir quelques pĂ©pites.

Pourquoi Django

La maturitĂ© est souvent un facteur dĂ©cisif d'un point de vue professionnel, aprĂšs 5 ans de dĂ©veloppement, le framework est devenu stable et Ă  Ă©normĂ©ment gagnĂ© de son ouverture °en Open-Source (pour ceux qui se demandent ce qu'une litiĂšre pour chat vient faire ici, c'est un jardin zen, j'ai pas trouvĂ© mieux).

Pourquoi Django

Quelques chiffres issus de la présentation de l'année précédente, on voit bien la progression en terme d'utilisateurs et donc de contributeurs potentiels.

Pourquoi Django

Enfin, l'avantage d'avoir des outils Ă  sa disposition est de pouvoir laisser s'exprimer sa crĂ©ativitĂ©, le plus important est ce que l'on fait avec ses outils. Vous pouvez prendre le meilleur des frameworks, ça ne vous assurera pas une application Ă  succĂšs. Ça serait bien trop facile sinon ;-).

Pourquoi Django

AprĂšs avoir vantĂ© au±tant de qualitĂ©s, voyons pour quels projets cette caisse Ă  outils s'applique.

Pourquoi Django

Il n'y a pas d'outil miracle, notre mĂ©tier est un Ă©ternel compromis et il faut savoir faire avec. L'avantage de Django est qu'il permet de couvrir un trĂšs large pĂ©rimĂštre d'applications mais si vous voulez construire un gratte-ciel il va peut-ĂȘtre falloir penser Ă  autre chose.

Pourquoi Django

Cela dit, il y a un trÚs faible pourcentage de projets web qui doivent en arriver là et il sera toujours temps de changer certaines parties ou d'améliorer les performances le moment venu.

Pourq���Čuoi Django

On termine avec un peu de teasing...

Pourquoi Django

On ne l'attend plus mais Django 1.0 arrive ! (si si, je vous assure) La premiÚre branche importante (queryset-refactor) a été mergée au trunk.

Pourquoi Django

Et la suivante (newforms-admin) est en cours de finitions actives. Ce n'est plus qu'une question de ... (mettez ce qui vous semble le plus crédible et votez sur whendjangowillreleaseonepointzero.com).

Pourquoi Django

Des fois que le message n'ait pas Ă©tĂ© assez clair (j'adore les photos de gens qui sautent dans les prĂ©sentations, je trouve łĂ§a kitsch au possible ;-)).

Pourquoi Django

Bilan personnel

Difficile d'enchaßner une nuit trop alcoolisée courte (il faut croire que c'est une malédiction) et d'insuffler suffisamment de vitalité. Je suis néanmoins assez satisfait car je pense avoir bien fait passer le message qui était tout simple : essayez Django !

L'exemple initial Ă©tait assez fort pour capter directement l'attention, la liste des avantages Ă©tait assez claire. Bon par contre je suis conscient qu'il y a du progrĂšs Ă  faire au niveau de la conclusion car je n'ai pas assez insistĂ© Ă  l'oral sur l'intĂ©rĂȘt d'avoir une simple caisse Ă  outils pour laisser s'exprimer sa crĂ©ativitĂ© et je voulais insister lĂ -dessus.

Je me suis permis quelques trolls un peu douteux sur Zope 3 (un peu la chance d'avoir assistĂ© Ă  la conf dessus la veille, un peu car on en a parlĂ© une boŽnne partie de la nuit), je suis pas vraiment sĂ»r que ça avait sa place. Quoi qu'il en soit, les Ă©lĂ©ments de comparaison citĂ©s dans la discussion qui a suivie Ă©taient intĂ©ressants.

Django : performances et qualité

J'ai eu beaucoup plus de mal à préparer cette présentation car elle était trÚs dépendante du public. Je voulais éviter de ne m'adresser qu'à une poignée de personnes et j'ai donc choisi au final une approche plus généraliste sur les bonnes pratiques web, appliquées à Django.

Un rapide sondage m'a montré que ce choix était pertinent et que me craintes étaient fondées. Moins d'un quart de la salle avait déjà essayé Django, et une poignée sur de gros projets. Adaptation à chaud : il valait mieux passer du temps sur les aspects pas trop pointus... quitte à décevoir ceux qui étaient venus pour l'intitulé de la conf !

Django : q���”ualitĂ© et performances

Un rappel prĂ©alable sur le coĂ»t de la qualitĂ© et des performances s'impose. C'est un investissement dans une logique qui s'inscrit dans la durĂ©e, ce n'est pas forcĂ©ment adaptĂ© Ă  tous les projets et ça doit ĂȘtre mis en place d'un commun accord entre les acteurs du projet (les tests sont trĂšs difficiles Ă  facturer).

Django : qualité et performances

Un titre qui claque, je suis sûr qu'en anglais ça rend encore mieux.

Django : qualité et performances

Il existe de nombreux outils de détection, du simple module logging à ceux permettant de stresser votre application et votre architecture.

���¶"Django

Avant d'optimiser, il faut bien évaluer la situation, il ne sert à rien d'optimiser un site qui ne rencontre pas de problÚmes de performances, privilégiez plutÎt l'expérience utilisateur (ergonomie, etc). Si vous n'avez pas le temps d'optimiser, vous pouvez toujours avoir une expansion horizontale dans un premier temps (plus de serveurs) si vous disposez des fonds nécessaires. J'ai oublié de parler de l'évolution vers les clouds pour gérer ce type de problématiques.

Django : qualité et performances

On entre dans le vif du sujet.

Django : qualité et performances

Le cache est l'Ă©lĂ©ment le plus simple Ă  mettre en Ɠuvre et il existe diffĂ©rents niveaux avec Django (page, fragment, vue, quer·yset, etc) qui permettent d'avoir la modularitĂ© nĂ©cessaire. Attention, il ne faut pas oublier d'avoir des mĂ©canismes d'invalidation du cache ! (pas comme sur ce blog par exemple...)

Django : qualité et performances

Le cache est bien pratique mais insuffisant parfois. Lorsqu'on arrive sur des gros projets, il est quasi illusoire de vouloir s'en tenir à des données normalisées. Ne serait-ce que pour le nombre d'items, il faut avoir recours à des champs dénormalisés. Django dispose de signals pour gérer ça de façon automatisée.

Django : qualité et performances

De nombreuses choses peuvent ĂȘtre faites en asynchrone (envoi de mail, prĂ©chargements de widget coĂ»teux, etc), AJAX peut žici prendre tout son sens.

Django : qualité et performances

Il faut bien faire la différence entre ce qui est imputable à Django et ce qui concerne l'architecture de votre projet, un bon admin sys et/ou DBA peut faire des miracles. Il ne faut pas oublier non plus que les performances css/js jouent un rÎle important à ce niveau...

Django : qualité et performances

Une petite astuce propre à Django, l'utilisation du tag {% with %} pour créer des alias dans les templates lorsqu'une méthode coûteuse est évaluée dans une boucle par exemple.

Django : qualitĂ© et performa���čnces

Le traitement des performances se fait de maniÚre itérative, essayez de toujours identifier le facteur limitant de la réactivité de votre application.

Django : qualité et performances

Un résultat est important, que ce soit un échec ou pas (le scientifique reprend le dessus), pensez à documenter vos essais, que ce soit pour votre équipe ou de maniÚre publique (blog, djangosnippets, etc).

Django : qualité et performances

Un autre titre jemelapĂštegrave.

Django : qualité et performances

La pĂ©rennitĂ© d'une application web est toute relative, l'Ă©volutșion technologique est telle qu'il est difficile d'ĂȘtre pertinent Ă  plus de 3 ans. Ça veut dire qu'il faut quand mĂȘme rester Ă©volutif jusque lĂ  !

Django : qualité et performances

Les rĂšgles qui s'appliquent ici sont les mĂȘmes que pour un projet Python, il est impĂ©ratif de tester les diffĂ©rentes fonctionnalitĂ©s grĂące aux unittests et doctests. Django dispose d'un module entier consacrĂ© Ă  ça, il est temps de s'en servir. Un client spĂ©cifique aux tests permet mĂȘme de tester les diffĂ©rentes vues et le rĂ©sultats des appels (GET, POST, etc).

Django : qualité et performances

En découplant les différentes applications de votre projet (lire à ce sujet l'excellent post de James Bennett), vous allez pouvoir vous constituer (ou récupérer) un bibliothÚque d'applications web réutilisables dans plusieurs de vos projets.

Django : qualité et performances

On ne mentionnera jamais assez à quel point la documentation d'un projet est importante. Normalement les doctests doivent permettre de « raconter une histoire », développez vos talents d'écrivain !

Django : qualité et performances

Cerise sur le gĂąteau, Django vous permet de gĂ©nĂ©rer automatiquement la documentation Ă  partir du code dans l'interface d'administration, ce qui s'avĂšre trĂšs pratique si vous travaillez avec une Ă©quipeŒ de plusieurs personnes dont certaines s'occupent exclusivement du html/css/js.

Django : qualité et performances

Exemple d'itération sur l'implémentation des URL.

Django : qualité et performances

Utilisation assez naïve avec la construction d'URL à la main, c'est une mauvaise pratique car vous devez modifier les URL à de nombreux endroits si vous décidez de changer votre schéma.

Django : qualité et performances

La seconde mĂ©thode s'appuie sur une mĂ©thode du modĂšle (diffĂ©rente ici du bien connu get_absolute_url car on veut accĂ©der au profil et non Ă  l'utilisateur), c'est dĂ©jĂ  mieux mais ilœ faut encore modifier l'URL Ă  deux endroits en cas de modification.

Django : qualité et performances

Enfin la bonne méthode est d'utiliser les URL nommées, qui permettent de ne dupliquer la création des URL à aucun endroit, si vous modifiez celle dans urls.py ça va impacter sur l'ensemble des URL de votre site. Cela est permis grùce au décorateur permalink.

Django : qualité et performances

Ces différentes pratiques vous permettent d'opérer des refactoring important de code tout en étant serein et de vous concentrer sur d'autres fonctionnalités.

Django : qualité et performances

Je voulais terminer sur un point qui me semble capital pour améliorer la qualité d'une application (pas forcément Django).

Django : qualité et performances

L'idée m'est venue en consultant la présentation de Cameron Moll et plus spécifiquement le slide comparant le bon designer au super designer.

Django : qualité et performances

J'en suis arrivé à la conclusion qu'un bon développeur est consciencieux, il connaßt ses outils et sait parfaitement obtenir un résultat satisfaisant avec. Qu'est-ce qu'il lui manque alors ?

Django : qualité et performances

Bien souvent la curiosité, celle de fureter pour finalement trouver une solution plus adaptée ou un module qui fait déjà ce qu'il a mis une semaine à coder, celle d'aller à des conférences, de lire des livres, d'essayer de comprendre pourquoi certaines choses ont été faites ainsi. Cette qualité vous permet de vous épanouir quotidiennement dans votre travail.

Django : qualité et performances

Bon avec tous ces conseils, vous allez forcément faire une appli qui va conquérir le monde, faire chuter l'action Google et sauver la planÚte.

Django : qualité et performances

Les crĂ©dits, mercÀi ! (complĂštement illisibles, il faut que je trouve un moyen simple de formater ça)

Django : qualité et performances

Bilan personnel

Je suis beaucoup moins satisfait de ma seconde prestation, j'ai remis en question chaque concept prĂ©sentĂ© au fur et Ă  mesure, doutant de l'intĂ©rĂȘt pour quelqu'un s'intĂ©ressant peu Ă  Django. Du coup j'Ă©tais un peu hĂ©sitant et je pense que ça s'est ressenti.

Au final, j'ai un peu le sentiment que ceux qui connaissaient pas trop ces problématiques se sont ennuyés et ceux qui y étaient confrontés aussi car je ne suis pas allé assez loin...

Concernant Keynote (ça vaut pour les deux confs) : aucun problÚme au niveau des images, par contre je n'ai pas pris le temps de configurer l'écran pour voir le slide suivant + le temps sur l'écran et c'était un tort car ça aide beaucoup.

Conclusion

ÁIl y a probablement des formats plus appropriĂ©s pour aborder les problĂ©matiques de performances/qualitĂ©s comme des tables rondes ou des sĂ©ances de questions/rĂ©ponses comme me le suggĂ©rait Fabien par mail. Pour montrer la rapiditĂ© de dĂ©veloppement de Django et donner envie d'essayer, rien ne vaut un atelier avec un petit projet de mise en bouche. Autant de pistes qu'il faudra explorer lors des journĂ©es 2009 !

Vous y étiez ?

Votre avis m'intĂ©resse Ă©normĂ©ment. J'aimerais vraiment pouvoir progresser Ă  ce niveau et vous ĂȘtes le mieux placĂ© pour m'aider. J'ai dĂ©jĂ  eu des retours par blog (merci Sunny), par email et sur irc mais si vous avez un peu de temps, n'hĂ©sitez pas, je prends le bon mais aussi et surtout le mauvais. N'ayez pas peur d'y aller trop fort, j'encaisse derriĂšre :-).

[Edit] : Âles vidĂ©os sont en ligne ! Merci l'AFPy.

Logo biologeek ConfĂ©rences Django pour PyCon fr a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 21 Mai 2008. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

J'ai eu le privilĂšge de prĂ©senter Django lors des journĂ©es organisĂ©es par l'afpĂy. C'Ă©tait vraiment un weekend exceptionnel, une organisation exemplaire, des confĂ©rences de qualitĂ©, des discussions de geek, que du bon. Je me suis enfin dĂ©cidĂ© Ă  mettre les slides en ligne, en attendant les vidĂ©os.

Historique

J'avais déjà présenté Django l'année derniÚre et j'avais vraiment eu l'impression de passer à cÎté de ma conf. Outre le fait que j'étais bien crevé d'avoir mis en ligne django-fr, j'ai relevé 3 gros défauts :

Partant de ce constat, j'ai essayé cette année de :

Alors pari rĂ©ussi ? Mon retour personnel aprĂšs chaque confĂ©rence ci-dessous. J'Ćessaye de retrouver ce que j'ai dit de tĂȘte, ça sera forcĂ©ment diffĂ©rent des vidĂ©os qui devraient arriver plus tard : moins de stress, davantage de temps pour Ă©toffer et des liens en bonus.

Pourquoi Django ?

Je n'ai jamais eu de cours de marketing et je hais les commerciaux donc c'est vraiment une épreuve pour moi de « vendre mon produit ». J'ai surtout voulu aller à l'essentiel pour pouvoir ensuite en débattre pendant les questions/réponses.

Pourquoi Django

Avant de parler de Django, il est bon de rappeler les intĂ©rĂȘts d'un framework web face Ă  l'approche plus traditionnelle par applications fonctionnelles toutes prĂȘtes. Qu'est-ce qui a pu suscitĂ© un tel engouement ?

Pourquoi Django

On connaßt tous des projets qui commencent avec un projet tout simple (je prends souvent l'exemple du blog car il est assez parlant). Il existe des trillions de moteurs de blog et il est donc aisé d'en prendre un tout fait :

Pourquoi Django

Mais bien (trop) souvent, un projet évolue en cours de route et l'ajout de fonctionnalités (galerie de photos, paiement en ligne, inclusion de vidéos) aboutit finalement à un cahier des charges ressemblant plutÎt à :

Pourquoi Django

Si vous ĂȘtes parti d'un simple moteur de blog rafistolĂ©, il est trĂšs probable que vous arriviez Ă  un rĂ©sultat de piĂštre qualitĂ© :

Pourquoi Django

La solution est de partir d'une approche plus bas niveau : la caisse à outil qui va vous permettre de construire vos propres briques fonctionnelles et de réaliser un projet de maniÚre cohérente et évolutive.

Pourquoi Django

De cette façon, vous allez énormément gagner en agilité, la clé de voûte de la qualité (du projet), de la sérénité (du développeur) et de la satisfaction (du client).

Pourquoi Django

Maintenant que vous ĂȘtes convaincu du bien fondĂ© des frameworks web, il est temps de passer au plat de rĂ©sistance : pourquoi Django ?

Pourquoi Django

Django est Ă©crit en Python et vous permet d'Ă©crire du Python, il n'y a pas deÈ fichiers de configuration en xml (ai-je besoin de rappeler que ce format est fait pour les machines ?).

Pourquoi Django

Django est trĂšs facile Ă  prendre en main, il suffit de quelques heures (mĂȘme sans connaĂźtre initialement Python) pour avoir une premiĂšre application qui tourne et en comprendre les principaux concepts.

Pourquoi Django

Face aux deux approches : framework glue vs. réinvention de la roue, Django a choisi la seconde ce qui apporte une cohérence à tous les niveaux (documentation, code, aide, etc) au détriment de sa modularité intrinsÚque.

Pourquoi Django

La documentation est un rĂ©el atout, surtout lorsqu'on dĂ©bute. C'est l'une des Émeilleures documentation technique que je connaisse et elle est en train d'ĂȘtre encore amĂ©liorĂ©e !

Pourquoi Django

Je suis assez mal placé pour parler de rapidité de développement avec la refonte de ce blog qui a pris... du temps. Néanmoins, pour l'utiliser quotidiennement, je peux affirmer que le développement avec ce framework permet de concrétiser plus rapidement des projets. L'un des atouts est par exemple de prototyper des applications en des temps records, aprÚs bien sûr les détails prennent plus de temps, comme partout.

Pourquoi Django

L'interface d'administration auto-générée est vraiment utile et participe à l'« effet Wow !© » initial. Difficile de s'en priver ensuite.

Pourquoi Django

L'Ă©chappement des caractĂšres html par dĂ©faut peut ĂȘtre un Ă©lĂ©ment important pour une personne dĂ©butant en dĂ©veloppement web. Ce choix est une rĂ©elle sĂ©curitĂ© si vous ne maĂźtrisez pas vraiment toutes les failles possibles d'un code (mĂȘme s'il serait bon de vous renseigner Ă  ce sujet si c'est le cas !).

Pourquoi Django

Django est simple, autant dans ses concepts que dans leurs mises en application, si vous connaissez Python, vous pouvez mĂȘme sans peine plonger dans le code de Django et dĂ©couvrir quelques pĂ©pites.

Pourquoi Django

La maturitĂ© est souvent un facteur dĂ©cisif d'un point de vue professionnel, aprĂšs 5 ans de dĂ©veloppement, le framewoËrk est devenu stable et Ă  Ă©normĂ©ment gagnĂ© de son ouverture en Open-Source (pour ceux qui se demandent ce qu'une litiĂšre pour chat vient faire ici, c'est un jardin zen, j'ai pas trouvĂ© mieux).

Pourquoi Django

Quelques chiffres issus de la présentation de l'année précédente, on voit bien la progression en terme d'utilisateurs et donc de contributeurs potentiels.

Pourquoi Django

Enfin, l'avantage d'avoir des outils Ă  sa disposition est de pouvoir laisser s'exprimer sa crĂ©ativitĂ©, le plus important est ce que l'on fait avec ses outils. Vous pouvez prendre le meilleur des frameworks, ça ne vous assurera pas une application Ă  succĂšs. Ça serait bien trop facile sinon ;-).

Pourquoi Django

AprÚs avoir vanté autant de qualités, voyons pour quels projets cette caisse à outils s'applique.

Pourquoi Django

Il n'y a pas d'outil miracle, notre mĂ©tier est un Ă©ternel compromis et il faut savoir faire avec. L'avantage de Django est qu'il permet de couvrir un trĂšs large pĂ©rimĂštre d'applications mais si vous voulez construire un gratte-ciel il va peut-ĂȘtre falloir penser Ă  autre chose.

Pourquoi Django

Cela dit, il y a un trÚs faible pourcentage de projets web qui doivent en arriver là et il sera toujours temps de changer certaines parties ou d'améliorer les performances le moment venu.

Pourquoi Django

On termine avec un peu de teasing...

Pourquoi Django

On ne l'attend plus mais Django 1.0 arrive ! (si si, je vous assure) La premiÚre branche importante (queryset-refactor) a été mergée au trunk.

Pourquoi Django

Et la suivante (newforms-admin) est en cours de finitions actives. Ce n'est plus qu'une question de ... (mettez ce qui vous semble le plus crédible et votez sur whendjangowillreleaseonepointzero.com).

Pourquoi Django

Des fois que le message n'ait pas Ă©tĂ© assez clair (j'adore leÎs photos de gens qui sautent dans les prĂ©sentations, je trouve ça kitsch au possible ;-)).

Pourquoi Django

Bilan personnel

Difficile d'enchaßner une nuit trop alcoolisée courte (il faut croire que c'est une malédiction) et d'insuffler suffisamment de vitalité. Je suis néanmoins assez satisfait car je pense avoir bien fait passer le message qui était tout simple : essayez Django !

L'exemple initial Ă©tait assez fort pour capter directement l'attention, la liste des avantages Ă©tait assez claire. Bon par contre je suis conscient qu'il y a du progrĂšs Ă  faire au niveau de la conclusion car je n'ai pas assez insistĂ© Ă  l'oral sur l'intĂ©rĂȘt d'avoir une simple caisse Ă  outils pour laisser s'exprimer sa crĂ©ativitĂ© et je voulais insister lĂ -dessus.

Je me suis permis quelques trolls un peu douteux sur Zope 3 (un peu la chance d'avoir assistÏĂ© Ă  la conf dessus la veille, un peu car on en a parlĂ© une bonne partie de la nuit), je suis pas vraiment sĂ»r que ça avait sa place. Quoi qu'il en soit, les Ă©lĂ©ments de comparaison citĂ©s dans la discussion qui a suivie Ă©taient intĂ©ressants.

Django : performances et qualité

J'ai eu beaucoup plus de mal à préparer cette présentation car elle était trÚs dépendante du public. Je voulais éviter de ne m'adresser qu'à une poignée de personnes et j'ai donc choisi au final une approche plus généraliste sur les bonnes pratiques web, appliquées à Django.

Un rapide sondage m'a montré que ce choix était pertinent et que me craintes étaient fondées. Moins d'un quart de la salle avait déjà essayé Django, et une poignée sur de gros projets. Adaptation à chaud : il valait mieux passer du temps sur les aspects pas trop pointus... quitte à décevoir ceux qui étaient venus pour l'intitulé de la conf !

Django : qualité et performances

Un rappel prĂ©alable sur le coĂ»t de la qualitĂ© et des performances s'impose. C'est un investissement dans une logique qui s'inscrit dans la durĂ©e, ce n'est pas forcĂ©ment adaptĂ© Ă  tous les projets et ça doit ĂȘtre mis en place d'un commun accord entre les acteurs du projet (les tests sont trĂšs difficiles Ă  facturer).

Django : qualité et performances

Un titre qui claque, je suis sûr qu'en anglais ça rend encore mieux.

Django : qualité et performances

Il existe de nombreux outils de détection, du simple module logging à ceux permettant de stresser votre application et votre architecture.

Django : qualité et performances

Avant d'optimiser, il faut bien évaluer la situation, il ne sert à rien d'optimiser un site qui ne rencontre pas de problÚmes de performances, privilégiez plutÎt l'expérience utilisateur (ergonomie, etc). Si vous n'avez pas le temps d'optimiser, vous pouvez toujours avoir une expansion horizontale dans un premier temps (plus de serveurs) si vous disposez des fonds nécessaires. J'ai oublié de parler de l'évolution vers les clouds pour gérer ce type de problématiques.

Django : qualité et performances

On entre dans le vif du sujet.

Django : qualité et performances

Le cache est l'Ă©lĂ©ment le plus simple Ă  mettre en Ɠuvre et il eÒxiste diffĂ©rents niveaux avec Django (page, fragment, vue, queryset, etc) qui permettent d'avoir la modularitĂ© nĂ©cessaire. Attention, il ne faut pas oublier d'avoir des mĂ©canismes d'invalidation du cache ! (pas comme sur ce blog par exemple...)

Django : qualité et performances

Le cache est bien pratique mais insuffisant parfois. Lorsqu'on arrive sur des gros projets, il est quasi illusoire de vouloir s'en tenir à des données normalisées. Ne serait-ce que pour le nombre d'items, il faut avoir recours à des champs dénormalisés. Django dispose de signals pour gérer ça de façon automatisée.

Django : qualité et performances

De nombreuses choses peuvent ĂȘtre faites en asynchrone (envÓoi de mail, prĂ©chargements de widget coĂ»teux, etc), AJAX peut ici prendre tout son sens.

Django : qualité et performances

Il faut bien faire la différence entre ce qui est imputable à Django et ce qui concerne l'architecture de votre projet, un bon admin sys et/ou DBA peut faire des miracles. Il ne faut pas oublier non plus que les performances css/js jouent un rÎle important à ce niveau...

Django : qualité et performances

Une petite astuce propre à Django, l'utilisation du tag {% with %} pour créer des alias dans les templates lorsqu'une méthode coûteuse est évaluée dans une boucle par exemple.

Django : qualité et performances

Le traitement des performances se fait de maniÚre itérative, essayez de toujours identifier le facteur limitant de la réactivité de votre application.

Django : qualité et performances

Un résultat est important, que ce soit un échec ou pas (le scientifique reprend le dessus), pensez à documenter vos essais, que ce soit pour votre équipe ou de maniÚre publique (blog, djangosnippets, etc).

Django : qualité et performances

Un autre titre jemelapĂštegrave.

Django : qualité et performances

LaŐ pĂ©rennitĂ© d'une application web est toute relative, l'Ă©volution technologique est telle qu'il est difficile d'ĂȘtre pertinent Ă  plus de 3 ans. Ça veut dire qu'il faut quand mĂȘme rester Ă©volutif jusque lĂ  !

Django : qualité et performances

Les rĂšgles qui s'appliquent ici sont les mĂȘmes que pour un projet Python, il est impĂ©ratif de tester les diffĂ©rentes fonctionnalitĂ©s grĂące aux unittests et doctests. Django dispose d'un module entier consacrĂ© Ă  ça, il est temps de s'en servir. Un client spĂ©cifique aux tests permet mĂȘme de tester les diffĂ©rentes vues et le rĂ©sultats des appels (GET, POST, etc).

Django : qualité et performances

En dĂ©couplant les diffĂ©rentes appÖlications de votre projet (lire Ă  ce sujet l'excellent post de James Bennett), vous allez pouvoir vous constituer (ou rĂ©cupĂ©rer) un bibliothĂšque d'applications web rĂ©utilisables dans plusieurs de vos projets.

Django : qualité et performances

On ne mentionnera jamais assez à quel point la documentation d'un projet est importante. Normalement les doctests doivent permettre de « raconter une histoire », développez vos talents d'écrivain !

Django : qualité et performances

Cerise sur le gĂąteau, Django vous permet de gĂ©nĂ©rer automatiquement la documentation Ă  partir du code dans l'interface d'administration, ceŚ qui s'avĂšre trĂšs pratique si vous travaillez avec une Ă©quipe de plusieurs personnes dont certaines s'occupent exclusivement du html/css/js.

Django : qualité et performances

Exemple d'itération sur l'implémentation des URL.

Django : qualité et performances

Utilisation assez naïve avec la construction d'URL à la main, c'est une mauvaise pratique car vous devez modifier les URL à de nombreux endroits si vous décidez de changer votre schéma.

Django : qualité et performances

La seconde mĂ©thode s'appuie sur une mĂ©thode du modĂšle (diffĂ©rente ici du bien connu get_absolute_url car on veut accĂ©deŰr au profil et non Ă  l'utilisateur), c'est dĂ©jĂ  mieux mais il faut encore modifier l'URL Ă  deux endroits en cas de modification.

Django : qualité et performances

Enfin la bonne méthode est d'utiliser les URL nommées, qui permettent de ne dupliquer la création des URL à aucun endroit, si vous modifiez celle dans urls.py ça va impacter sur l'ensemble des URL de votre site. Cela est permis grùce au décorateur permalink.

Django : qualité et performances

Ces différentes pratiques vous permettent d'opérer des refactoring important de code tout en étant serein et de vous concentrer sur d'autres fonctionnalités.

<Ùp> Django : qualitĂ© et performances

Je voulais terminer sur un point qui me semble capital pour améliorer la qualité d'une application (pas forcément Django).

Django : qualité et performances

L'idée m'est venue en consultant la présentation de Cameron Moll et plus spécifiquement le slide comparant le bon designer au super designer.

Django : qualité et performances

J'en suis arrivĂ© Ă  la conclusion qu'un bon dĂ©veloppeur est consciencieux, il connaĂźt ses outils et sait parfaitement obtenir un rĂ©sultat satisfaisant avÚec. Qu'est-ce qu'il lui manque alors ?

Django : qualité et performances

Bien souvent la curiosité, celle de fureter pour finalement trouver une solution plus adaptée ou un module qui fait déjà ce qu'il a mis une semaine à coder, celle d'aller à des conférences, de lire des livres, d'essayer de comprendre pourquoi certaines choses ont été faites ainsi. Cette qualité vous permet de vous épanouir quotidiennement dans votre travail.

Django : qualité et performances

Bon avec tous ces conseils, vous allez forcément faire une appli qui va conquérir le monde, faire chuter l'action Google et sauver la planÚte.

D���Ûjango : qualitĂ© et performances

Les crédits, merci ! (complÚtement illisibles, il faut que je trouve un moyen simple de formater ça)

Django : qualité et performances

Bilan personnel

Je suis beaucoup moins satisfait de ma seconde prestation, j'ai remis en question chaque concept prĂ©sentĂ© au fur et Ă  mesure, doutant de l'intĂ©rĂȘt pour quelqu'un s'intĂ©ressant peu Ă  Django. Du coup j'Ă©tais un peu hĂ©sitant et je pense que ça s'est ressenti.

Au final, j'ai un peu le sentiment que ceux qui connaissaient pas trop ces problématiques se sont ennuyés et ceux qui y étaient confrontés aussi car je ne suis pas allé assez loin...

Concernant Keynote (ça vaut pour les deux confs) : aucun problĂšme au niveau des images, par contre je n'ai pas pris le temps de configurer l'Ă©cran pour voir le slide suivant + le temps sur l'Ă©cran et c'Ă©tÜait un tort car ça aide beaucoup.

Conclusion

Il y a probablement des formats plus appropriés pour aborder les problématiques de performances/qualités comme des tables rondes ou des séances de questions/réponses comme me le suggérait Fabien par mail. Pour montrer la rapidité de développement de Django et donner envie d'essayer, rien ne vaut un atelier avec un petit projet de mise en bouche. Autant de pistes qu'il faudra explorer lors des journées 2009 !

Vous y étiez ?

Votre avis m'intĂ©resse Ă©normĂ©ment. J'aimerais vraiment pouvoir progresser Ă  ce niveau et vous ĂȘtes le mieux placĂ© pour m'aider. J'ai dĂ©jĂ  eu des retours par blog (merci Sunny), par email et sur irc mais si vous avez un peu de temps, n'hĂ©sitez pas, je prends le bon mais aussi et surtout le mauvais. N'ayez pas peur d'y aller trop fort, j'encaisse derriĂšre :-).

[Edit] : les vidéos sont en ligne ! Merci l'AFPy.

Logo biologeek ConfĂ©rences Django pour PyCon fr a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 21 Mai 2008. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

[Biologeek] ★ ConfĂ©rences Django pour PyCon fr★ ConfĂ©rences Django pour PyCon fr "‹"†ù$‚qAA†ś-†ś-iQhttp://www.biologeek.com/bonnes-pratiques,conferences,django,python,traduction/bonnes-pratiques-et-astuces-python/2008-08-31 17:41:09.3941332008-05-11 18:50:44.000000

Ça faisait un moment que je n'avais pas parlĂ© des bonnes pratiques Python mais l'approche de Pycon fr (oĂč je prĂ©senterai Django : le pourquoi et le comment le 18 mai),߃±‚5AAƒŻ5ƒŻ5oWhttp://www.biologeek.com/conferences,django,python/conferences-django-pour-pycon-fr/2008-08-31 17:41:09.3462412008-05-21 00:57:53.000000

J'ai eu le privilĂšge de prĂ©senter Django lors des journĂ©es organisĂ©es par l'afpy. C'Ă©tait vraiment un weekend exceptionnel, une organisati§ 8~òäÌŸ«‹waSE/!îàÒÆžȘ—s]OA3 ôéÚɻʓ„k\PA( țńâÔÇž©š~ django/ unix. python. pylons- python- wsgi, zope3, python+ wsgi+  python*  web)  python) -bio-informatique(  python( web' python'-bonnes-pratiques& python&-bonnes-pratiques% python% livre$critique$ python$ web# ~python# }web" |python"{-bonnes-pratiques! zpython! ypython xdjango w)web-frameworks vpythonu)web-frameworkst#conferences sdjango rpython qrest ppython odjangon)web-frameworks mlivrelcritique kpythonj)web-frameworks idjango hpythong)web-semantiquef%informatiquee!traduction ddjangoc#conferences bpythona-bonnes-pratiques `python _djangoà l'Ă©vĂ©nement Python incontournable avec un programme des plus allĂ©chants, m'a bien motivĂ© pour effectuer la traduction de l'une des meilleures prĂ©sentation par David Goodger que je connaisse qui remet les bonnes pratiques Python Ă  plat, ce qui est toujours bon avant d'aller plus loin.

La lisibilité est importante

Les programmes doivent ĂȘtre Ă©crits pour ĂȘtre lus par des gens et accidentellement exĂ©cutĂ©s par les machines.

-- Abelson & Sussman, Structure and Interpretation of Computer Programs

Essayez de rendre vos programmes faciles à lire et évidents.

PEP 8 : Style Guide pour le code Python

Une lecture immanquable : http://www.python.org/dev/peps/pep-0008/ (PEP = Python Enhanácement Proposal)

Un PEP est une document procurant des informations à la communauté Python, ou décrivant une nouvelle fonctionnalité de Python et ses processus ou de son environnement.

La communauté Python a ses propres standards sur ce à quoi doit ressembler le code, codifiés dans le PEP8. Ces standards sont différents de ceux des autres communautés, comme C, Java, etc.

L'indentation et les espaces étant si importants en Python, ce Style Guide est une standard. Il est important que vous adhériez au guide ! La plupart des projets suivent ces conventions.

Whitespace 1

Whitespace 2

Nommage

Mais essayez d'Ă©viter la forme __privĂ©e. Je ne l'utilise jamais. Faăites moi confiance. Si vous l'utilisez, vous le regretterez plus tard.

Longues lignes et continuité

Garder une taille de ligne inférieure à 80 caractÚres.

Utilisez la continuité implicite des lignes au sein des parenthÚses/crochets/accolades :

def __init__(self, first, second, third,
             fourth, fifth, sixth):
    output = (first + second + third
              + fourth + fifth + sixth)

Utilisez les backslashs en dernier recours :

VeryLong.left_hand_side \
    = even_longer.right_hand_side()

Les backslashs sont locaux, ils doivent terminer la ligne sur laquelle ils sont. Si vous ajoutez un espace aprÚs le backslash, ça ne sert à rien. Ah aussi, c'est laid.

Longues chaĂźnes de caractĂšres

Les chaßnes de caractÚres adjacentes sont concaténées par le parser:

>>> print 'o' 'n' "e"
one

Les espaces entre les chaĂźnes ne sont pas requis, ämais aident Ă  la lisibilitĂ©. Tous les types de quotes sont utilisable :

>>> print 't' r'\/\/' """o"""
t\/\/o

La chaßne précédée par "r" est une chaßne de type "raw". Les backslashs ne sont pas évalués comme étant des caractÚres d'échappement dans les chaßnes de type raw. Elles sont utiles pour les expressions réguliÚres et les chemins de fichiers Windows.

Notez que les chaßnes de caractÚres nommées ne sont pas concaténées :

>>> a = 'three'
>>> b = 'four'
>>> a b
  File "<stdin>", line 1
    a b
      ^
SyntaxError: invalid syntax

Cela vient du fait que la concaténation automatique est une fonctionnalité du parser/compiler Python, pas de l'interpréteur. Vous devez utiliser le signe "+" pour concaténer des chaßnes de caractÚres à l'éxecution.

text = ('Long strings can be made up '
        'of several shorter strings.')


Les parenthÚses autorisent la continuité implicite des lignes. Les chaßnes de caractÚres sur plusieurs lignes utilisent les triple quotes :

"""Triple
double
quotes"""

'''\
Triple
single
quotes\
'''

Dans le dernier exemple ci-dessus (simple triple quotes), notez l'utilisation du backslash pour Ă©chapper les nouvelles lignes. Cela Ă©limine les nouvelles lignes en conservant les quotes joliment alignĂ©es Ă  gauche. Les backslashs doivent ĂȘtre Ă  la fin de leurs lignes.

Déclarations

Bon :

if foo == 'blah':
    do_something()
do_one()
do_two()
do_three()

Mauvais :

if foo == 'blah': do_something()
do_one(); do_two(); do_three()

Les espaces et l'indentation sont de bons indicateurs visuels du flot du programme. L'indentation de la seconde ligne du "Bon" ci-dessus montre au lecteur que quelque chose va se produire, alors que le manque d'indentation dans le "Mauvais" exemple cachæe le "if".

Les dĂ©clarations multiples sur une mĂȘme ligne sont une torture. En Python, la lisibilitĂ© compte.

Docstrings et Commentaires

Docstrings = Comment utiliser le code

Commentaires = Pourquoi (rationnel) et comment le code fonctionne

Les docstrings expliquent comment utiliser le code et sont lĂ  pour les utilisateurs de votre code. Quelques usages :

Les commentaires expliquent pourquoi et sont pour les mainteneurs de votre code. Examples incluçant des notes pour vous-mĂȘme, comme :

# !!! BUG: ...

# !!! FIX: This is a hack

# ??? Why is this here?

Les deux types sont de votre ressort donc écrivez de bonnes docstrings et de bons commentaires !

Les docstrings sont utiles pour un usage interactif (help()) et pour les systĂšmes d'auto-documentation.

Les commentaires et docstrings faux sont pire que tout. Donc conservez les à jour ! Lorsque vous effectuez des modifications, assurez vous que les commentaires et les docstrings sont cohérents avec le code.

Il y a un PEP entier consacré aux docstrings, PEP 257, "Docstring Conventions".

La pratique a raison de la théorie

Il y a toujours des exceptions. Issu du PEP 8 :

Mais plus important : sachez ĂȘtre pertinents - parfois le style guide ne s'applique pas. Lorsque vous avez un doute, utilisez votre raison. Étudieèz d'autres possibilitĂ©s et dĂ©cidez de ce qui vous semble le mieux. Et n'hĂ©sitez pas Ă  demander ! Deux bonnes raisons de ne pas suivre une rĂšgle particuliĂšre :

(1) Lorsque appliquer la rĂšgle va rendre le code moins lisible, mĂȘme pour quelqu'un qui est habituĂ© Ă  lire du code qui suit les rĂšgles.

(2) Pour ĂȘtre cohĂ©rent avec du code prĂ©existant qui enfreint aussi ces rĂšgles (peut-ĂȘtre pour des raisons historiques) -- mĂȘme si c'est aussi une opportunitĂ© pour faire un peu de nettoyage (dans un pur style XP).

... mais la pratique ne doit pas réduire la théorie à néant !

On plonge maintenant au cƓur du tutoriel : les astuces. On va commencer avec les plus faciles et augmenter progressivement le niveau.

Variables intermédiaires

Dans les autres langages :

temp = a
a = b
b = temp

En Python :

b, a = a, b

Vous l'avez peut-ĂȘtre déĂ©jĂ  rencontrĂ© mais savez vous comment ça fonctionne ?

La partie à droite est unpackée dans les noms de tuple de la partie à gauche.

D'autres exemples:

>>> l =['David', 'Pythonista', '+1-514-555-1234']
>>> name, title, phone = l
>>> name
'David'
>>> title
'Pythonista'
>>> phone
'+1-514-555-1234'

Utile dans les boucles sur des données structurées (la variable l ci-dessus a été conservée) :

>>> people = [l, ['Guido', 'BDFL', 'unlisted']]
>>> for (name, title, phone) in people:
...     print name, phone
...
David +1-514-555-1234
Guido unlisted

Chaque item de people est unpackĂ© dans le tuple (name, êtitle, phone).

Il est aussi possible de faire le chemin inverse, il faut juste s'assurer d'avoir la mĂȘme structure Ă  droite et Ă  gauche :

>>> david, (gname, gtitle, gphone) = people
>>> gname
'Guido'
>>> gtitle
'BDFL'
>>> gphone
'unlisted'
>>> david
['David', 'Pythonista', '+1-514-555-1234']

Aller plus loin avec les tuples

On a vu que la virgule était le constructeur du tuple, pas les parenthÚses. Par exemple :

>>> 1,
(1,)

L'interprĂ©teur Python montre les parenthĂšses pour que ce soit plus clair et je vous conseille de faire de mĂȘme :

>>> (1,)
(1,)

Mais n'oubliez pas la virgule !

>>> (1)
1

Dans un tuple contenant un seul Ă©lĂ©ment, la virgule est nĂ©cessaire. Dans un tuple avec plus de 2 Ă©lĂ©ments, la virgule finale est optionnelle. Pour un tuple videë, une paire de parenthĂšses suffit :

>>> ()
()

>>> tuple()
()

Une erreur de typo courante est de laisser une virgule alors que vous ne souhaitez pas avoir un tuple. Il est trĂšs facile de l'oublier dans votre code :

>>> value = 1,
>>> value
(1,)

Donc si vous vous retrouvez avec un tuple alors que vous ne vous y attendiez pas, cherchez la virgule ! (Note du traducteur : de ma propre expérience, il est plus courant d'oublier la virgule pour un tuple ne contenant qu'un seul élément, dans les settings de Django par exemple, cherchez plutÎt la virgule manquante dans ces cas là).

Le "_" interactif

C'est une fonctionnalité trÚs utile que peu de développeurs connaissent. (Note du traducteur : bien entendu vous n'en faites pas partie et vous connaissez les dangers associés.)

ì

Dans un interpréteur interactif, que vous évaluiez une expression ou que vous appeliez une fonction, le résultat est stocké dans une variable temporaire, _ (un underscore) :

>>> 1 + 1
2
>>> _
2

_ stocke la derniÚre valeur affichée.

Lorsqu'un résultat vaut None, rien n'est affiché, donc _ ne change pas. C'est normal !

Ça ne marche que dans un interprĂ©teur interactif, pas dans un module.

C'est particuliÚrement utile lorsque vous travaillez sur un problÚme de maniÚre interactive, et que vous souhaitez stocker la valeur du dernier résultat :

>>> import math
>>> math.pi / 3
1.0471975511965976
>>> angle = _
>>> math.cos(angle)
0.50000000000000011
>>> _
0.50000000000000011

Construction de chaĂźnes de caractĂšres

Commençons avec une liste de chaßnes de caractÚres :

í
colors = ['red', 'blue', 'green', 'yellow']

On veut concaténer ces chaßnes ensemble pour en créer une longue. ParticuliÚrement lorsque le nombre de sous-chaßnes est gros...

Ne faites pas :

result = ''
for s in colors:
    result += s

C'est trĂšs lent. Ça utilise Ă©normĂ©ment de mĂ©moire et de performances. La somme va additionner, stocker, et ensuite passer Ă  la suite pour chaque Ă©tape intermĂ©diaire.

Faites plutĂŽt ceci :

result = ''.join(colors)

La méthode join() fait toute la copie en une seule passe.

Lorsque vous ne traitez qu'une petite centaine de chaßnes de caractÚres, ça ne fait aucune différence. Mais prenez l'habitude de construire vos chaßnes de façon optimale, car avec des milliers ou des boucles, ça va faire la différence.

Construire des chaĂźnes, solutions 1

Voici quelques techniques pour utiliser la mĂ©thodeî join().

Si vous voulez un espace comme séparateur :

result = ' '.join(colors)

ou une virgule et un espace :

result = ', '.join(colors)

voici un cas courant d'utilisation :

colors = ['red', 'blue', 'green', 'yellow']
print 'Choose', ', '.join(colors[:-1]), \
      'or', colors[-1]

Pour faire une phrase grammaticalement correcte, on veut des virgules entre chaque valeurs sauf la derniĂšre, oĂč l'on prĂ©fĂšre un "ou". La syntaxe de dĂ©coupage d'une liste s'occupe du reste. La "partie jusqu'Ă  -1" ([:-1]) retourne tout sauf la derniĂšre valeur, que l'on peut concatĂ©ner avec nos virgules.

Bien sûr, ce code ne fonctionnera pas avec les cas particuliers comme une liste de taille 0 ou 1. Ce qui retourne :

Choose red, blue, green or yellow

Construire des chaĂźnes, solutions 2

Vous avez besoin d'appliquer une fonction pour gĂï©nĂ©rer les chaĂźnes initiales :

result = ''.join(fn(i) for i in items)

Ça utilise une generator expression, dont on parlera plus tard.

Si vous devez modifier les chaßnes de maniÚre incrémentale, commencez par les stocker dans une liste pour commencer :

items = []
...
items.append(item)  # de nombreuses fois
...
# une fois la liste complétée
result = ''.join(fn(i) for i in items)

On accumule les parties de la liste afin de pouvoir appliquer le join, ce qui est plus rapide.

Utilisez in lorsque c'est possible (1)

Bon :

for key in d:
    print key

Mauvais :

for keyđ in d.keys():
    print key

C'est limité aux objects ayant une méthode keys().

Utilisez in lorsque c'est possible (2)

Mais .keys() est nécessaire lorsque vous modifiez le dictionnaire :

for key in d.keys():
    d[str(key)] = d[key]

d.keys() crée une liste statique des clés du dictionnaire. Sinon, vous allez lever une exception "RuntimeError: dictionary changed size during iteration".

Utilisez key in dict, et non dict.has_key() :

# faites ça :
if key in d:
    ...do something with d[key]

# mais pas ça :
if d.has_key(key):
    ...do something with d[key]

in est ici utilisé comme un opérateur.

La méthode get des dictionnaires

On doit souvent initialiser les entrées d'un dictionnaire avant de les utiliser:

Voici la maniĂšre naĂŻve de faire :<ń/p>

navs = {}
for (portfolio, equity, position) in data:
    if portfolio not in navs:
        navs[portfolio] = 0
    navs[portfolio] += position * prices[equity]

dict.get(key, default) permet de ne pas avoir Ă  se soucier du test :

navs = {}
for (portfolio, equity, position) in data:
    navs[portfolio] = (navs.get(portfolio, 0)
                       + position * prices[equity])

Beaucoup mieux.

La méthode setdefault des dictionnaires (1)

Ici on doit initialiser les valeurs d'un dictionnaire mutables. Chaque valeur du dictionnaire sera une liste. Voici la maniĂšre naĂŻve :

equities = {}
for (portfolio, equity) in data:
    if portfolio in equities:
        equities[portfolio].append(equity)
    else:
        equities[portfolio] = [equity]

dict.setdefault(key, default) s'occupe de ça de maniÚre beaucoup plus rapide :

equities = {}
fòor (portfolio, equity) in data:
    equities.setdefault(portfolio, []).append(equity)

dict.setdefault() est équivalent à "get ou set & get". Ou "set si nécessaire, puis get". C'est particuliÚrement rapide si votre clé de dictionnaire est coûteuse à générer ou longue à taper.

Le seul problĂšme avec dict.setdefault() c'est que la valeur par dĂ©faut est Ă©valuĂ©e, qu'elle soit utilisĂ©e ou non. Ça ne pose problĂšme que si la clĂ© est coĂ»teuse Ă  calculer.

Si la valeur par défaut est coûteuse à calculer, vous devriez plutÎt utiliser la classe defaultdict.

La méthode setdefault des dictionnaires (2)

On va voir qu'il est possible d'utiliser setdefault pour déclarer une valeur par défaut :

navs = {}
for (portfolio, equity, position) in data:
    navs.setdefault(portfolio, 0)
    navs[portfolio] += position * prices[equity]
ó

La méthode setdefault d'un dictionnaire retourne la valeur par défaut, mais nous l'ignorons ici. On tire profit d'une conséquence de l'utilisation de setdefault, la valeur n'est initialisée que si elle n'existe pas déjà.

defaultdict

Nouveau avec Python 2.5.

defaultdict est nouveau dans Python 2.5, il fait partie du module collections. defaultdict est identique aux dictionnaires classiques, excepté pour deux cas :

Il y a deux maniÚres d'accéder à defaultdict :

Voici l'exemple dĂ©jĂ  traitĂ©, oĂč chaque valeur du dictionnaire fois ĂȘtre initialisĂ© pour ĂȘtre une liste vide, réécrit en utilisant defaultdict :

from collections import defaultdict

equities = defaultdict(list)
for (portfolio, equity) in data:
    equities[portfolio].append(equity)

Il n'y a plus d'astuce ici. Dans ce cas, la fonction factory par défaut est list, ce qui retourne une liste vide.

C'est la maniÚre d'avoir un dictionnaire avec les valeurs par défaut à 0, utilisez int comme factory :

navs = defaultdict(int)
for (portfolio, equity, position) in data:
    navs[portfolio] += position * prices[equity]

Il faut faire attention Ă  defaultdict quand mĂȘme. Vouős ne pouvez pas utiliser l'exception KeyError sur un dictionnaire initialisĂ© avec defaultdict. Vous devez utiliser la condition "key in dict" si vous voulez vĂ©rifier l'existence d'une clĂ© de maniĂšre spĂ©cifique.

Construire et scinder des dictionnaires

Voila une technique utile pour construire un dictionnaire à partir de deux listes (ou séquences), une liste pour les clés, une liste pour les valeurs :

given = ['John', 'Eric', 'Terry', 'Michael']
family = ['Cleese', 'Idle', 'Gilliam', 'Palin']
pythons = dict(zip(given, family))
>>> pprint.pprint(pythons)
{'John': 'Cleese',
 'Michael': 'Palin',
 'Eric': 'Idle',
 'Terry': 'Gilliam'}

L'inverse est trivial bien sûr :

 >>> pythons.keys()
 ['John', 'Michael', 'Eric', 'Terry']
 >>> pythons.values()
 ['Cleese', 'Palin', 'Idle', 'Gilliam']

Notez que l'ordre du rĂ©sultat des .keys() et .values() Ă  est diffĂ©rent des ölistes utilisĂ©es lors de la crĂ©ation du dictionnaire. L'ordre d'entrĂ©e est diffĂ©rent de l'ordre de sortie car un dictionnaire n'est pas ordonnĂ©. Par contre, l'ordre des clĂ©s est consistant avec celui des valeurs, Ă  condition que le dictionnaire n'ait pas Ă©tĂ© modifiĂ© entre temps.

Tester des valeurs vraies

Il est élégant et rapide de tirer partie des avantages de Python en ce qui concerne les valeurs booléennes :

# faites ça :     # et pas ça :
if x:             if x == True:
    pass              pass

Test d'une liste :

# faites ça :     # et pas ça :
if items:         if len(items) != 0:
    pass              pass

                  # et surtout pas ça :
                  if items != []:
                      pass

Valeurs vraies

Les noms True et False sont des instances intrinsÚques à Python de type bool, des valeurs booléennes. Comme None, il n'existe qu'une seule instance de chaque.

False True
False (== 0) True (== 1)
"" (empty string) toutes les chaĂźnes Ă  part "" (" ", "nimportequoi")
0, 0.0 n'importe quel chiffre Ă  part 0 (1, 0.1, -1, 3.14)
[], (), ű {}, set() n'importe quel container non vide ([0], (None,), [''])
None pratiquement tous les objets qui ne sont explicitement équivalents à False

Voici par exemple un objet qui est toujours vrai :

>>> class C:
...  pass
...
>>> o = C()
>>> bool(o)
True
>>> bool(C)
True

Pour contrÎler la valeur booléenne d'une instance ou d'une classe définie, utilisez les méthodes spéciales __nonzero__ ou __len__. Utilisez __len__ si votre classe est un container qui a une taille :

class MyContainer(object):

    def __init__(self, data)ù:
        self.data = data

    def __len__(self):
        """Return my length."""
        return len(self.data)

Si votre classe n'est pas un container, utilisez __nonzero__ :

class MyClass(object):

    def __init__(self, value):
        self.value = value

    def __nonzero__(self):
        """Return my truth value (True or False)."""
        # This could be arbitrarily complex:
        return bool(self.value)

En Python 3.0, __nonzero__ a Ă©tĂ© renommĂ© __bool__ afin d'ĂȘtre consistant avec le type bool natif. Pour ĂȘtre compatible, ajoutez ceci Ă  la dĂ©finition de votre classe :

__bool__ = __nonzero__

Index & Item (1)

Voici une maniÚre élégante de vous épargner quelques lignes si vous avez besoin d'une liste de mots :

>>> items = 'zero one two three'.split()
>>> print items
['zero', 'one', 'two', 'three']

Prenons l'exemple d'un itération entre les items d'une liste, pour laquelle nous voulons à la fois l'item et la position (l'index) de cet item dans la liste :

                  - ou -
i = 0
for item in items:      for i in range(len(items)):
    print i, item               print i, items[i]
    i += 1

Index & Item (2): enumerate

La fonction enumerate prend une liste et retourne des paires (index, item) :

>>> print list(enumerate(items))
[(0, 'zero'), (1, 'one'), (2, 'two'), (3, 'three')]

Il est nĂ©cessaire d'avoir recours Ă  une list pour afficher les rĂ©sultats car enumerate est une fonction fainĂ©ante, gĂ©nĂ©rant un item (une paire) Ă  la fois, seulement lorsqu'il est demandĂ©. Une boucle for nĂ©cessite un tel mĂ©canisme. enumerate est un exemple de gĂ©nĂ©rateur dont on parlera plus tard des dĂ©tails. ûprint ne prend pas un rĂ©sultat Ă  la fois mais doit ĂȘtre en possession de la totalitĂ© du message Ă  afficher. On a donc converti automatiquement le gĂ©nĂ©rateur en une liste avant d'utiliser print.

Notre boucle devient beaucoup plus simple :

for (index, item) in enumerate(items):
    print index, item

# comparé à :              # comparé à :
index = 0               for i in range(len(items)):
for item in items:              print i, items[i]
    print index, item
    index += 1

La version avec enumerate est plus courte et plus simple que la version de gauche, et plus facile Ă  lire que les deux autres.

Un exemple montrant que la fonction enumerate retourne un itérateur (un générateur est une sorte d'itérateur) :

>>> enumerate(items)
<enumerate object at 0x011EA1C0>
>>> e = enumerate(items)
>>> e.next()
(0, 'zero')
>>> e.next()
(1, 'one')
>>ü;> e.next()
(2, 'two')
>>> e.next()
(3, 'three')
>>> e.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
StopIteration

Les autres langages ont des "variables"

Dans de nombreux autres langages, assigner une variable revient Ă  mettre une valeur dans une boĂźte.

int a = 1;

BoĂźte 1 a

La boĂźte "a" contient maintenant un integer 1.

Assigner une autre valeur Ă  la mĂȘme variable remplace le contenu de la boĂźte :

a = 2;

BoĂźte 2 a

Maintenant la boĂźte "a" contient un integer 2.

Assigner une variable à une autre crée une copie de la valeur et la met dans une nouvelle boßte :

int b = a;

BoĂźte 2 a

BoĂźte 2 b

"b" est une seconde boßte, avec une copie de l'entier 2. La boßte "a" en a une copie séparée.

Python a des "noms"

En Python, un "nom" ou "identifiant" est comme une étiquette attachée à un objet.

a = 1

Tag 1 a

Ici, un objet integer 1 a une étiquette appelée "a".

Si on réassigne "a", on déplace juste l'étiquette sur un autre objet :

a = 2

Tag 2 a

1

Maintețnant le nom "a" est attachĂ© Ă  un objet entier 2.

L'objet entier 1 n'a plus le tag "a". Il peut encore exister mais on n'y a plus accÚs via le nom "a". (Lorsqu'un objet n'a plus aucune référence ou étiquette, il est supprimé de la mémoire.)

Si l'on assigne un nom à un autre, on attache juste une autre étiquette à un objet existant :

b = a

Tag 2 a b

Le nom "b" est juste une seconde Ă©tiquette attachĂ©e au mĂȘme objet que "a".

Bien que l'on réfÚre communément aux "variables" en Python (car c'est une terminologie commune aux autres langages), on manipule vraiment de "noms" ou "identifiants". En Python, les "variables" sont des étiquettes pour des valeurs, non des boßtes nommés.

Si vous ne comprenez rien au reste de ce tutoriel, j'espĂšre que vous aurez$ au moins retenu la façon dont les noms fonctionnent. Une bonne ÿcomprĂ©hension vous permettra d'apprendre rapidement et d'Ă©viter des erreurs comme celle-ci:

Valeurs de paramÚtres par défaut

C'est une erreur courante que les dĂ©butants font souvent. MĂȘme les dĂ©veloppeurs plus expĂ©rimentĂ©s la font s'ils n'ont pas compris comment fonctionnent les noms en Python.

def bad_append(new_item, a_list=[]):
    a_list.append(new_item)
    return a_list

Le problĂšme ici c'est que la valeur par dĂ©faut a_list, une liste vide, est Ă©valuĂ©e lors de la dĂ©finition de la fonction. Ainsi Ă  chaque fois que vous appelez la fonction vous obtenez la mĂȘme valeur par dĂ©faut. Essayez plusieurs fois :

>>> print bad_append('one')
['one']

>>> print bad_append('two')
['one', 'two']

Les listes sont modifiables, vous pouvez modifier leur contenu. La bonne maniÚre d'avoir une liste par défaut (ou dictionnaire, ou set) est de la créer au moment du lancement, au sein de la fonction :

def good_append(new_item, a_list=None):
    if a_list is None:
        a_list = []
    a_list.append(new_item)
    return a_list

Formattage des chaĂźnes de caractĂšres avec %

L'opérateur % fonctionne en Python comme la fonction sprintf de C.

Bien sûr si vous ne connaissez pas C, ça ne vous aide pas. Pour faire simple, vous définissez un template ou format et des valeurs qui seront interprétées.

Dans cet exemple, le template contient deux spécifications de conversion "%s" signifie "insérer une chaßne de caractÚre ici" et "%i" signifie "convertir un integer en string et l'insérer ici". "%s" est particuliÚrement utile car il utilise la fonction standard str() pour convertir un objet en une chaßne de caractÚres.

Les valeurs proposées doivent correspondrent au template, on a deux valeurs ici, un tuple.

name = 'David'
messages = 3
text = ('Hello %s, you have %i messages'
        % (name, messages))
print text

Ce qui donne :

Hello David, you have 3 messages

Les détails sont dans la Python Library Reference, section 2.3.6.2, "String Formatting Operations". Mettez cette page en favoris !

Si vous ne l'avez pas encore fait, allez sur python.org, téléchargez la documentation en HTML (dans un .zip ou une archive), et installez la sur votre machine. Il n'y a rien de mieux que d'avoir la ressource de référence à portée de clavier.

Formattage des chaßnes de caractÚres avancé

Pourquoi est-ce qu'il y a autant de personnes qui ne réalisent pas qu'il y a d'autres façons de formater les chaßnes de caractÚres qui peuvent s'avérer plus puissantes ?

Avec des noms grĂące Ă  un dictionnaire :

values = {'name': name, 'messages': messages}
print ('Hello %(name)s, you have %(messages)i '
       'messages' % values)


Ici on a spécifié les noms des valeurs interprétées, qui constituent les clés du dictionnaire.

Vous trouvez qu'il y a de la redondance ? Les noms "name" et "messages" sont déjà définis localement. On peut en tirer parti.

En utilisant les variables locales :

print ('Hello %(name)s, you have %(messages)i '
       'messages' % locals())

La fonction locals() retourne un dictionnaire de toutes les variables locales disponibles.

C'est trÚs puissant. Grùce à ça, vous pouvez formater toutes les chaßnes de caractÚres que vous voulez sans avoir à vous soucier de la correspondance positionnelle avec les valeurs soumises en argument.

Mais le pouvoir peut ĂȘtre dangereux. ("With great power comes great responsibility.") Si vous utilisez locals() avec un template issu d'une ressource externe, vous exposez l'intĂ©gralitĂ© de votre espace de noms local. C'est une chose Ă  garder en tĂȘte.

Pour examiner votre espace de nom local :

>>> from pprint import pprint
>>> pprint(locals())

pprint est un module trĂšs utile. Si vous ne le connaissiez pas dĂ©jĂ , essayez de jouer avec. Ça rend le debugging des donnĂ©es structurĂ©es beaucoup plus simple !

Formattage des chaßnes de caractÚres avancé

L'espace de nom des attributs d'une instance d'objet est simplement un dictionnaire, self.__dict__.

En utilisant l'espace de nom d'une instance :

print ("We found %(error_count)d errors"
       % self.__dict__)

Equivalent Ă , mais moins flexible que :

print ("We found %d errors"
       % self.error_count)

Note: Les attributs d'une classe sont dans le __dict__ de la classe. Les espaces de noms sont hérités et constituent donc des dictionnaires chaßnés.

List Comprehensions

Les list comprehensions ("listcomps" pour les intimes) sont des raccourcis syntaxiques pour ce pattern généralement utilisé.

La maniĂšre traditionnelle avec for et if :

new_list = []
for item in a_list:
    if condition(item):
        new_list.append(fn(item))

En utilisant une list comprehension :

new_list = [fn(item) for item in a_list
            if condition(item)]

Les listcomps sont claires et concises, directes. Vous pouvez avoir plusieurs boucles for et conditions if au sein d'une mĂȘme listcomp, mais au-delĂ  de deux ou trois, ou si les conditions sont complexes, je vous suggĂšre d'utiliser l'habituelle boucle for. En appliquant le Zen de Python, utilisez la mĂ©thode la plus lisible.

Par exemple, la liste des carrés de 0 à 9 :

>>> [n ** 2 for n in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

La liste des nombres impairs au sein de la précédente liste :

>>> [n ** 2 for n in range(10) if n % 2]
[1, 9, 25, 49, 81]

Generator Expressions (1)

Faisons la somme des carrés des nombres inférieurs à 100 :

Avec une boucle :

total = 0
for num in range(1, 101):
    total += num * num

On peut aussi utiliser la fonction sum qui fait plus rapidement le travail pour nous en construisant la bonne séquence.

Avec une list comprehension :

total = sum([num * num for num in range(1, 101)])

Avec une generator expression :

total = sum(num * num for num in xrange(1, 101))

Les generator expressions ("genexps") sont comme les list comprehensions, excepté dans leur calcul, les genexps sont fainéantes. Les listcomps calculent l'intégralité du résultat en une seule passe, pour le stocker dans une liste. Les generator expressions calculent une valeur à la fois, lorsqu'elle est nécessaire. C'est particuliÚrement utile lorsque la séquence est trÚs longue lorsque la liste générée n'est qu'une étape intermédiaire et non le résultat final.

Dans ce cas, on est uniquement intĂ©ressĂ© par la somme, on n'a pas besoin de la liste des rĂ©sultats intermĂ©diaires. On utilise xrange pour la mĂȘme raison, ça gĂ©nĂšre les valeurs une par une.

Generator Expressions (2)

Par exemple si on doit faire la somme des carrés de plusieurs milliards d'entiers, on va arriver à une saturation de la mémoire avec une list comprehension, mais les generator expressions ne vont avoir aucun problÚme. Bon ça va prendre un certain temps par contre !

total = sum(num * num
            for num in xrange(1, 1000000000))

La différence de syntaxe est que les listcomps ont des crochets, alors que les genexps n'en ont pas. Les generator expressions nécessitent parfois des parenthÚses par contre, vous devriez donc toujours les utiliser.

En bref :

  • Utilisez une list comprehension lorsque le rĂ©sultat escomptĂ© est la liste.
  • Utilisez une generator expression lorsque la liste n'est qu'un rĂ©sultat intermĂ©diaire.

Voici un récent exemple de ce que j'ai vu au boulot.

On avait besoin d'un dictionnaire qui corresponde aux chiffres des mois (Ă  la fois via des chaĂźnes de caractĂšres et via des integers) au code des mois pour un client. Cela peut ĂȘtre fait avec une ligne de code.

Ça fonctionne de la maniùre suivante :

  • La fonction de rĂ©fĂ©rence dict() prend en argument une liste de paires de clĂ©s/valeurs (2-tuples).
  • On a une liste des codes des mois (chaque code est une simple lettre, et une chaĂźne de caractĂšres est aussi une simple liste de lettres). On parcours cette liste pour obtenir Ă  la fois le code du mois et l'index.
  • Le nombre des mois commence Ă  1 mais Python commence l'indexation Ă  0, le nombre des mois correspond dont Ă  index+1.
  • On veut avoir la correspondance Ă  la fois avec les nombres et les chaĂźnes de caractĂšres. On peut utiliser les fonctions int() et str() pour ça et itĂ©rer dessus.

L'exemple en question :

 month_codes = dict((fn(i+1), code)
     for i, code in enumerate('FGHJKMNQUVXZ')
     for fn in (int, str))

Le résultat obtenu pour month_codes :

{ 1:  'F',  2:  'G',  3:  'H',  4:  'J', ...
 '1': 'F', '2': 'G', '3': 'H', '4': 'J', ...}

Ordonner

Il est trĂšs simple d'ordonner une liste en Python :

a_list.sort()

(Notez que la liste est ordonnée sur place, la liste originale est ordonnée et la fonction sort ne retourne pas une liste ou une copie.)

Mais que faire lorsque vous avec une liste de données à ordonner, mais quelle ne s'ordonne pas de maniÚre naturelle ? Par exemple ordonner se lon la premiÚre colonne, puis la quatriÚme.

On peut utiliser la fonction de référence sort avec une méthode définie par nos soins :

def custom_cmp(item1, item2):
    returm cmp((item1[1], item1[3]),
               (item2[1], item2[3]))

a_list.sort(custom_cmp)

Ça marche, mais c'est extrĂȘmement lent pour les listes Ă©normes.

Ordonner avec DSU

DSU = Decorate-Sort-Undecorate

Note: DSU n'est bien souvent plus nécessaire, cf. section suivante.

Au lieu de crĂ©er une fonction de comparaison personnalisĂ©e, on crĂ©e une liste intermĂ©diaire qui va pourvoir ĂȘtre ordonnĂ©e naturellement :

# Decorate:
to_sort = [(item[1], item[3], item)
           for item in a_list]

# Sort:
to_sort.sort()

# Undecorate:
a_list = [item[-1] for item in to_sort]

La premiÚre ligne crée une liste contenant des tuples, une copie de la valeur à ordonner en premier argument, suivi de la valeur complÚte d e la liste.

La seconde ligne ordonne grĂące Ă  la fonction Python, ce qui est trĂšs rapide.

La troisiÚme ligne récupÚre la derniÚre valeur de la liste une fois ordonnée. Souvenez-vous, cette derniÚre valeur correspond à l'item complet. On n'utilise plus la partie ayant permis d'ordonner, elle a joué son rÎle et n'est plus utile.

C'est un compromis espace mémoire + complexité vs. temps. Plus simple et rapide mais on est obligé de dupliquer la liste originale.

Ordonner avec keys

Python 2.4 a introduit un nouvel argument à la méthode sort des listes, "key", qui permet de spécifier une fonction à un argument qui est utilisée pour comparer chaque élément d'une liste avec les autres. Par exemple :

def my_key(item):
    return (item[1], item[3])

to_sort.sort(key=my_key)

La fonction my_key va ĂȘtre appelĂ©e une fois par item de la liste to_sort.

Vous pouve z utiliser votre propre fonction ou utiliser une fonction existante qui ne prend qu'un seul argument :

  • str.lower pour ordonner alphabĂ©tiquement sans tenir compte de la casse.
  • len pour ordonner selon la taille des items (chaĂźnes de caractĂšres ou containers).
  • int ou float pour ordonner numĂ©riquement avec des valeurs qui sont des chaĂźnes de caractĂšres comme "2", "123", "35".

Generators

On a déjà vu les generator expressions. On peut créer nos propres generators, comme des fonctions :

def my_range_generator(stop):
    value = 0
    while value < stop:
        yield value
        value += 1

for i in my_range_generator(10):
    do_something(i)

Le mot-clé yield transforme une fonction en generator. Lorsque vous appelez une fonction generator, au lieu d'exécuter le code directement, Python retourne un objet generator, qui est un itérateur. Il a une méthode next. Les boucles for appellent la méthode next de l'itérateur, jusqu'à ce qu'une exception du type StopIteration soit levée. Vous pouvez lever l'exception StopIteration explicitement ou de maniÚre implicite comme dans le code ci-dessous.

Les gĂ©nĂ©rateurs peuvent simplifier la maniĂšre de gĂ©rer les sĂ©quences/itĂ©rateurs, car on n'a pas besoin de crĂ©er des listes intermĂ©diaires. Ça ne gĂ©nĂšre qu'une valeur Ă  la fois.

Voici comment la boucle for fonctionne réellement. Python analyse la séquence déclarée avec le mot-clé in. Si c'est un simple container (comme une liste, un tuple, un dictionnaire, un set ou un container défini par l'utilisateur) Python le converti en itérateur. Si c'est déjà un itérateur, Python ne fait rien.

Python appelle ensuite de maniÚre itérative la méthode next de l'itérateur, assignant la valeur retournée au compteu r de la boucle (i dans notre cas), et exécute le code indenté. C'est répété, encore et encore jusqu'à ce que StopIteration soit levée, ou qu'un break soit exécuté.

Une boucle for peut ĂȘtre dotĂ©e d'un else, au sein de laquelle le code est exĂ©cutĂ© si rien ne s'est produit dans la boucle for, mais non aprĂšs un break. Cette distinction permet de faire des choses Ă©lĂ©gantes. else est rarement utilisĂ© avec la boucle for mais peut s'avĂ©rer trĂšs puissant lorsque la logique correspond Ă  ce que vous souhaitez faire.

Par exemple, si on doit vérifier qu'une condition est toujours remplie par tous les items d'une liste :

for item in sequence:
    if condition(item):
        break
else:
    raise Exception('Condition not satisfied.')

Exemple de generator

Filtrer les colonnes vides Ă  partir d'un fichier CSV (ou des items d'une liste) :

def filter_rows(row_iterator):
    for row in row_iterator:
        if row:
            yield row

data_file = open(path, 'rb')
irows = filter_rows(csv.reader(data_file))

Lire les lignes d'un fichier de données

datafile = open('datafile')
for line in datafile:
    do_something(line)

C'est possible car les fichiers sont dotés d'une méthode next, comme d'autres itérateurs : les listes, les tuples, les dictionnaires (pour leurs clés), les generators.

Il y a un piÚge ici : étant donnée la façon dont sont mises en cache les données, vous ne pouvez pas utiliser à la fois les méthodes .next et .read* à moins que vous n'utilisez Python 2.5+.

EAFP vs. LBYL

Il est plus facile de demander le pardon que la permission (EAFP) vs. analyser avant d'échouer (LBYL). Généralement EAFP est préféré, mais pas toujours.

  • Duck typing Si ça marche comme un canard, parle comme un canard et ressemble Ă  un canard : c'est un canard.
  • Exceptions Essayez de forcer le type si un objet doit ĂȘtre d'un type particulier. Si x doit ĂȘtre une chaĂźne de caractĂšres pour que votre code fonctionne, pourquoi ne pas appeler str(x) au lieu d'essayer quelque` chose comme isinstance(x, str).

Exemple EAFP try/except

Vous pouvez encapsuler vos exceptions dans un bloc try/except pour pour récupérer les erreurs et vous allez probablement arriver à une solution qui est beaucoup plus générale que si vous aviez essayer d'anticiper chaque cas.

try:
    return str(x)
except TypeError:
    ...

Note: SpĂ©cifiez toujours l'exception Ă  attraper. N'utilisez jamais except tout seul. Sinon except va cacher d'autres exceptions qui risquent d'ĂȘtre levĂ©es rendant votre code trĂšs difficile Ă  debugger.

Importer

from module import *

Vous avez probablement dĂ©jĂ  vu cette maniĂšre de faires des imports avec une "Ă©toile". Vous l'apprĂ©ciez peut-ĂȘtre. Ne l'utilisez pas.

Pour paraphraser un exemple trĂšs connu :

LUKE: Est-ce que from module import * est meilleur que des imports explicites ?
YODA: Non, pas meilleur. Plus rapide, plus simple, plus séduisant.
LUKE: Mais comment saurais-je pourquoi les imports explicites sont meilleurs que les formes étoilées ?
YODA: Tu sauras lorsque ton code dans 6 mois tu essayeras de lire.

Les imports étoilés sont le mauvais cÎté de la Force en Python.

Les imports de type from module import * polluent votre espace de nom. Vous allez avoir des choses que vous n'attendiez pas. Vous pouvez avoir des conflits avec les noms que vous avez dĂ©fini localement. Vous n'allez plus savoir d'oĂč viennent certains noms. Bien que ce soit un raccourci pratique, ça ne doit pas arriver en production.

Morale : n'utilisez pas d'imports étoilés !

Il est bien meilleur de référencer les noms à partir de leurs modules :

import module
module.name

importer un module avec un nom plus court si nécessaire (avec alias) :

import long_module_name as mod
mod.name

ou importer juste les noms dont vous avez besoin de maniĂšre explicite :

from module import name
name

Notez qu'il est nécessaire d'utiliser "reload()" sur un module lorsque vous utilisez le prompt interactif si vous éditez celui-ci.

Modules et scripts

Pour faire à la fois un module importable et un script exécutable :

if __name__ == '__main__':
    # script code here

Lorsqu'il est importĂ©, un attribut__name__ est settĂ©, correspondant au nom du fichier du module, sans ".py". Le code ci-dessus ne va donc pas ĂȘtre lancĂ© lors d'un import. Lorsqu'il est lancĂ© comme un script, l'attribut __name__ est settĂ© Ă  "main" et le script va ĂȘtre exĂ©cutĂ©.

Excepté pour certains cas spéciaux, vous ne devriez placer aucun code important au plus haut niveau. Placez votre code dans des fonctions, classes, méthodes et protégez le avec if __name__ == '__main__'.

Structure d'un module

"""module docstring"""

# imports
# constants
# exception classes
# interface functions
# classes
# internal functions & classes

def main(...):
    ...

if __name__ == '__main__':
    status = main()
    sys.exit(status)

C'est la façon dont un module devrait ĂȘtre structurĂ©.

Utilisation de la ligne de commande

Exemple (Note du traducteur : j'ai déjà parlé de ça aussi) :

#!/usr/bin/env python

"""
Module docstring.
"""

import sys
import optparse

def process_command_line(argv):
    """
    Return a 2-tuple: (settings object, args list).
    `argv` is a list of arguments, or `None` for ``sys.argv[1:]``.
    """
    if argv is None:
        argv = sys.argv[1:]

    # initialize the parser object:
    parser = optparse.OptionParser(
        formatter=optparse.TitledHelpFormatter(width=78),
        add_help_option=None)

    # define options here:
    parser.add_option(      # customized description; put --help last
        '-h', '--help', action='help',
        help='Show this help message and exit.')

    settings, args = parser.parse_args(argv)

    # check number of arguments, verify values, etc.:
    if args:
        parser.error('program takes no command-line arguments; '
                     '"%s" ignored.' % (args,))

    # further process settings & args if necessary

    return settings, args

def main(argv=None):
    settings, args = process_command_line(argv)
    # application code here, like:
    # run(settings, args)
    return 0        # success

if __name__ == '__main__':
    status = main()
    sys.exit(status)

Packages

package/
    __init__.py
    module1.py
    subpackage/
        __init__.py
        module2.py
  • UtilisĂ©s pour organiser un projet.
  • RĂ©duisent le nombre d'entrĂ©es lors du chargement.
  • RĂ©duisent les conflits en cas d'imports.

Exemple :

import package.module1
from packages.subpackage import module2
from packages.subpackage.module2 import name

En Python 2.5 on a maintenant les imports absolus et relatifs via un import du futur :

from __future__ import absolute_import

Je n'ai pas encore eu l'occasion de tester ça moi-mĂȘme, on va donc couper court Ă  toute discussion Ă  ce sujet.

Simple is Better Than Complex

DĂ©bugger est deux fois plus difficile que d'Ă©crire du code en premier jet. De plus, si vous Ă©crivez le code aussi intelligemment que possible, vous ĂȘtes, par dĂ©finition, pas assez intelligent pour le dĂ©bugger.

-- Brian W. Kernighan, co-auteur de The C Programming Language et le "K" dans "AWK"

En d'autres termes, gardez vos programmes simples !

Ne réinventez pas la roue

Avant d'écrire une seule ligne de code,

  • VĂ©rifiez que cela n'est pas dans la bibliothĂšque standard de Python.
  • VĂ©rifiez que cela n'est pas dans le Python Package Index (the "Cheese Shop")
  • Cherchez sur le web. Google is your friend.

Retour du traducteur

Pour terminer, et si vous souhaitez aller plus loin, une excellente prĂ©sentation sur les gĂ©nĂ©rateurs que je n'aurais malheureusement pas le temps de traduire permet d'envisager la programmation Python d'une maniĂšre tout Ă  fait diffĂ©rente. Elle est orientĂ©e administration systĂšme mais elle peut vraiment ĂȘtre appliquĂ©e Ă  de nombreux cas. Et si vous voulez comprendre l'intĂ©rĂȘt des dĂ©corateurs, un bon exemple vaut mieux que tous les discours. Mangez du Python, c'est bon pour la santĂ© !

Logo biologeek Bonnes pratiques et astuces Python a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 11 Mai 2008. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

Ça faisait un moment que je n'avais pas parlĂ© des bonnes pratiques Python mais l'approche de Pycon fr (oĂč je prĂ©senterai Django : le pourquoi et le comment le 18 mai), l'Ă©vĂ©nement Python incontournable avec un programme des plus allĂ©chants, m'a bien motivĂ© pour effectuer la traduction de l'une des meilleures prĂ©sentation par David Goodger que je connaisse qui remet les bonnes pratiques Python Ă  plat, ce qui est toujours bon avant d'aller plus loin.

La lisibilité est importante

Les programmes doivent ĂȘtre Ă©crits pour ĂȘtre lus par des gens et accidentellement exĂ©cutĂ©s par les machines.

-- Abelson & Sussman, Structure and Interpretation of Computer Programs

Essayez de rendre vos programmes faciles à lire et évidents.

PEP 8 : Style Guide pour le code Python

Une lecture immanquable : http://www.python.org/dev/peps/pep-0008/ (PEP = Python Enhancement Proposal)

Un PEP est une document procurant des informations à la communauté Python, ou décrivant une nouvelle fonctionnalité de Python et ses processus ou de son environnement.

La communauté Python a ses propres standards sur ce à quoi doit ressembler le code, codifiés dans le PEP8. Ces standards sont différents de ceux des autres communautés, comme C, Java, etc.

L'indentation et les espaces étant si importants en Python, ce Style Guide est une standard. Il est important que vous adhériez au guide ! La plupart des projets suivent ces conventions.

Whitespace 1

  • 4 espaces par niveau d'indentation.
  • Pas de tabs.
  • Ne jamais mixer des tabs et des espaces.
  • Un saut de ligne entre les fonctions.
  • Deux sauts de ligne entre les classes.

Whitespace 2

  • Ajoutez un espace aprĂšs ", ", dans les dictionnaires, les listes, les tuples, les arguments d'une liste d'arguments et aprĂšs ":" dans les dictionnaires mais pas avant.
  • Mettez des espaces autour des assignements et des comparaisons (exceptĂ© pour les arguments d'une liste).
  • Pas d'espace aux ouvertures/fermetures de parenthĂšses ou juste avant une liste d'arguments.
  • Pas d'espace en ouverture/fermeture de docstrings.

    def make_squares(key, value=0): """Return a dictionary and a list...""" d = {key: value} l = [key, value] return d, l

Nommage

  • joined_lower pour les fonctions, mĂ©thodes et attributs
  • joined_lower ou ALL_CAPS pour les constantes
  • StudlyCaps pour les classes
  • camelCase seulement pour suivre des conventions prĂ©-existantes
  • Attributs: interface, _internal, __private

Mais essayez d'éviter la forme __privée. Je ne l'utilise jamais. Faites moi confiance. Si vous l'utilisez, vous le regretterez plus tard.

Longues lignes et continuité

Garder une taille de ligne inférieure à 80 caractÚres.

Utilisez la continuité implicite des lignes au sein des parenthÚses/crochets/accolades :

def __init__(self, first, second, third,
             fourth, fifth, sixth):
    output = (first + second + third
              + fourth + fifth + sixth)

Utilisez les backslashs en dernier recours :

VeryLong.left_hand_side \
    = even_longer.right_hand_side()

Les backslashs sont locaux, ils doivent terminer la ligne sur laquelle ils sont. Si vous ajoutez un espace aprÚs le backslash, ça ne sert à rien. Ah aussi, c'est laid.

Longues chaĂźnes de caractĂšres

Les chaßnes de caractÚres adjacentes sont concaténées par le parser:

>>> print 'o' 'n' "e"
one

Les espaces entre les chaßnes ne sont pas requis, mais aident à la lisibilité. Tous les types de quotes sont utilisable :

>>> print 't' r'\/\/' """o"""
t\/\/o

La chaßne précédée par "r" est une chaßne de type "raw". Les backslashs ne sont pas évalués comme étant des caractÚres d'échappement dans les chaßnes de type raw. Elles sont utiles pour les expressions réguliÚres et les chemins de fichiers Windows.

Notez que les chaßnes de caractÚres nommées ne sont pas concaténées :

>>> a = 'three'
>>> b = 'four'
>>> a b
  File "<stdin>", line 1
    a b
      ^
SyntaxError: invalid syntax

Cela vient du fait que la concaténation automatique est une fonctionnalité du parser/compiler Python, pas de l'interpréteur. Vous devez utiliser le signe "+" pour concaténer des chaßnes de caractÚres à l'éxecution.

text = ('Long strings can be made up '
        'of several shorter strings.')

Les parenthÚses autorisent la continuité implicite des lignes. Les chaßnes de caractÚres sur plusieurs lignes utilisent les triple quotes :

"""Triple
double
quotes"""

'''\
Triple
single
quotes\
'''

Dans le dernier exemple ci-dessus (simple triple quotes), notez l'utilisation du backslash pour Ă©chapper les nouvelles lignes. Cela Ă©limine les nouvelles lignes en conservant les quotes joliment alignĂ©es Ă  gauche. Les backslashs doivent ĂȘtre Ă  la fin de leurs lignes.

Déclarations

Bon :

if foo == 'blah':
    do_something()
do_one()
do_two()
do_three()

Mauvais :

if foo == 'blah': do_something()
do_one(); do_two(); do_three()

Les espaces et l'indentation sont de bons indicateurs visuels du flot du programme. L'indentation de la seconde ligne du "Bon" ci-dessus montre au lecteur que quelque chose va se produire, alors que le manque d'indentation dans le "Mauvais" exemple cache le "if".

Les dĂ©clarations multiples sur une mĂȘme ligne sont une torture. En Python, la lisibilitĂ© compte.

Docstrings et Commentaires

Docstrings = Comment utiliser le code

Commentaires = Pourquoi (rationnel) et comment le code fonctionne</p>

Les docstrings expliquent comment utiliser le code et sont lĂ  pour les utilisateurs de votre code. Quelques usages :

  • Expliquer le but d'une fonction mĂȘme si ça vous semble Ă©vident car ça ne semblera pas forcĂ©ment Ă©vident Ă  une personne plus tard.
  • DĂ©crire les paramĂštres attendus, les valeurs retournĂ©es et les exceptions levĂ©es.
  • Si la mĂ©thode est fortement couplĂ©e Ă  un seul appelant, mentionner la fonction appelante (attention au fait que celle-ci puisse changer).

Les commentaires expliquent pourquoi et sont pour les mainteneurs de votre code. Examples incluant des notes pour vous-mĂȘme, comme :

# !!! BUG: ...

# !!! FIX: This is a hack

# ??? Why is this here?

Les deux types sont de votre ressort donc écrivez de bonnes docstrings et de bons commentaires !

Les docstrings sont utiles pour un usage interactif (help()) et pour les systĂšmes d'auto-documentation.

Les commentaires et docstrings faux sont pire que tout. Donc conservez les à jour ! Lorsque vous effectuez des modifications, assurez vous que les commentaires et les docstrings sont cohérents avec le code.

Il y a un PEP entier consacré aux docstrings, PEP 257, "Docstring Conventions".

La pratique a raison de la théorie

Il y a toujours des exceptions. Issu du PEP 8 :

Mais plus important : sachez ĂȘtre pertinents - parfois le style guide ne s'applique pas. Lorsque vous avez un doute, utilisez votre raison. Étudiez d'autres possibilitĂ©s et dĂ©cidez de ce qui vous semble le mieux. Et n'hĂ©sitez pas Ă  demander ! Deux bonnes raisons de ne pas suivre une rĂšgle particuliĂšre :

(1) Lorsque appliquer la rĂšgle va rendre le code moins lisible, mĂȘme pour quelqu'un qui est habituĂ© Ă  lire du code qui suit les rĂšgles.

(2) Pour ĂȘtre cohĂ©rent avec du code prĂ©existant qui enfreint aussi ces rĂšgles (peut-ĂȘtre pour des raisons historiques) -- mĂȘme si c'est aussi une opportunitĂ© pour faire un peu de nettoyage (dans un pur style XP).

... mais la pratique ne doit pas réduire la théorie à néant !

On plonge maintenant au cƓur du tutoriel : les astuces. On va commencer avec les plus faciles et augmenter progressivement le niveau.

Variables intermédiaires

Dans les autres langages :

temp = a
a = b
b = temp

En Python :

b, a = a, b

Vous l'avez peut-ĂȘtre dĂ©jĂ  rencontrĂ© mais savez vous comment ça fonctionne ?

  • La virgule est la syntaxe de construction du tuple.
  • Un tuple est créé Ă  droite (tuple packing).
  • Un tuple en est la cible Ă  gauche (tuple unpacking).

La partie à droite est unpackée dans les n!oms de tuple de la partie à gauche.

D'autres exemples:

>>> l =['David', 'Pythonista', '+1-514-555-1234']
>>> name, title, phone = l
>>> name
'David'
>>> title
'Pythonista'
>>> phone
'+1-514-555-1234'

Utile dans les boucles sur des données structurées (la variable l ci-dessus a été conservée) :

>>> people = [l, ['Guido', 'BDFL', 'unlisted']]
>>> for (name, title, phone) in people:
...     print name, phone
...
David +1-514-555-1234
Guido unlisted

Chaque item de people est unpacké dans le tuple (name, title, phone).

Il est aussi possible de faire le chemin inverse, il faut juste s'assurer d'avoir la mĂȘme structure Ă  droite et Ă  gauche :

>>> david, (gname, gtitle, gphone) = people
>>> gname
'Guido'
>>> gtitle
'BDFL'
>>> gphone
'unlisted'
>>> david
['David"', 'Pythonista', '+1-514-555-1234']

Aller plus loin avec les tuples

On a vu que la virgule était le constructeur du tuple, pas les parenthÚses. Par exemple :

>>> 1,
(1,)

L'interprĂ©teur Python montre les parenthĂšses pour que ce soit plus clair et je vous conseille de faire de mĂȘme :

>>> (1,)
(1,)

Mais n'oubliez pas la virgule !

>>> (1)
1

Dans un tuple contenant un seul élément, la virgule est nécessaire. Dans un tuple avec plus de 2 éléments, la virgule finale est optionnelle. Pour un tuple vide, une paire de parenthÚses suffit :

>>> ()
()

>>> tuple()
()

Une erreur de typo courante est de laisser une virgule alors que vous ne souhaitez pas avoir un tuple. Il est trĂšs facile de l'oublier dans votre code :

>>> value = 1,
>>> value
(1,)

Donc si vous vous retrouvez avec un tuple alors que vous ne vous y attendiez pas, cherchez la virgule ! (Note du traducteur : de ma propre expérience, il est plus courant d'oublier la virgule pour un tuple ne contenant qu'un seul élément, dans les settings de Django par exemple, cherchez plutÎt la virgule manquante dans ces cas là).

Le "_" interactif

C'est une fonctionnalité trÚs utile que peu de développeurs connaissent. (Note du traducteur : bien entendu vous n'en faites pas partie et vous connaissez les dangers associés.)

Dans un interpréteur interactif, que vous évaluiez une expression ou que vous appeliez une fonction, le résultat est stocké dans une variable temporaire, _ (un underscore) :

>>> 1 + 1
2
>>> _
2

_ stocke la derniÚre valeur affichée.

Lorsqu'un résultat vaut None, rien n'est affiché, donc _ ne change pas. C'est normal !

Ça ne marche que dans un interprĂ©teur interactif, pas dans un module.

C'est particuliÚrement utile lorsque vous travaillez sur un problÚme de maniÚre interactive, et que vous souhaitez stocker la valeur du dernier résultat :

>>> import math
>>> math.pi / 3
1.0471975511965976
>>> angle = _
>>> math.cos(angle)
0.50000000000000011
>>> _
0.50000000000000011

Construction de chaĂźnes de caractĂšres

Commençons avec une liste de chaßnes de caractÚres :

colors = ['red', 'blue', 'green', 'yellow']

On veut concaténer ces chaßnes ensemble pour en créer une longue. ParticuliÚrement lorsque le nombre de sous-chaßnes est gros...

Ne faites pas :

result = ''
for s in colors:
    result += s

C'est trĂšs lent. Ça util%ise Ă©normĂ©ment de mĂ©moire et de performances. La somme va additionner, stocker, et ensuite passer Ă  la suite pour chaque Ă©tape intermĂ©diaire.

Faites plutĂŽt ceci :

result = ''.join(colors)

La méthode join() fait toute la copie en une seule passe.

Lorsque vous ne traitez qu'une petite centaine de chaßnes de caractÚres, ça ne fait aucune différence. Mais prenez l'habitude de construire vos chaßnes de façon optimale, car avec des milliers ou des boucles, ça va faire la différence.

Construire des chaĂźnes, solutions 1

Voici quelques techniques pour utiliser la méthode join().

Si vous voulez un espace comme séparateur :

result = ' '.join(colors)

ou une virgule et un espace :

result = ', '.join(colors)

voici un cas courant d'utilisation :

colors = ['red', 'blue', 'green', 'yellow']
print 'Choose&', ', '.join(colors[:-1]), \
      'or', colors[-1]

Pour faire une phrase grammaticalement correcte, on veut des virgules entre chaque valeurs sauf la derniĂšre, oĂč l'on prĂ©fĂšre un "ou". La syntaxe de dĂ©coupage d'une liste s'occupe du reste. La "partie jusqu'Ă  -1" ([:-1]) retourne tout sauf la derniĂšre valeur, que l'on peut concatĂ©ner avec nos virgules.

Bien sûr, ce code ne fonctionnera pas avec les cas particuliers comme une liste de taille 0 ou 1. Ce qui retourne :

Choose red, blue, green or yellow

Construire des chaĂźnes, solutions 2

Vous avez besoin d'appliquer une fonction pour générer les chaßnes initiales :

result = ''.join(fn(i) for i in items)

Ça utilise une generator expression, dont on parlera plus tard.

Si vous devez modifier les chaßnes de maniÚre incrémentale, commencez par les stocker dans une liste pour commencer :

items = []
'...
items.append(item)  # de nombreuses fois
...
# une fois la liste complétée
result = ''.join(fn(i) for i in items)

On accumule les parties de la liste afin de pouvoir appliquer le join, ce qui est plus rapide.

Utilisez in lorsque c'est possible (1)

Bon :

for key in d:
    print key
  • in est gĂ©nĂ©ralement plus rapide.
  • Ce pattern marche aussi pour des items dans des containers arbitraires (comme les listes, les tuples ou les tests).
  • in est aussi un opĂ©rateur (comme on va le voir).

Mauvais :

for key in d.keys():
    print key

C'est limité aux objects ayant une méthode keys().

Utilisez in lorsque c'est possible (2)

Mais .keys() est nécessaire lorsque vous modifiez le dictionnaire :

for key in d.keys():
    d[str(key)] = (d[key]

d.keys() crée une liste statique des clés du dictionnaire. Sinon, vous allez lever une exception "RuntimeError: dictionary changed size during iteration".

Utilisez key in dict, et non dict.has_key() :

# faites ça :
if key in d:
    ...do something with d[key]

# mais pas ça :
if d.has_key(key):
    ...do something with d[key]

in est ici utilisé comme un opérateur.

La méthode get des dictionnaires

On doit souvent initialiser les entrées d'un dictionnaire avant de les utiliser:

Voici la maniĂšre naĂŻve de faire :

navs = {}
for (portfolio, equity, position) in data:
    if portfolio not in navs:
        navs[portfolio] = 0
    navs[portfolio] += position * prices[equity]

dict.get(key, default) permet de ne pas avoir Ă  se soucier du test :

navs = {}
for (portfolio, equity, position)) in data:
    navs[portfolio] = (navs.get(portfolio, 0)
                       + position * prices[equity])

Beaucoup mieux.

La méthode setdefault des dictionnaires (1)

Ici on doit initialiser les valeurs d'un dictionnaire mutables. Chaque valeur du dictionnaire sera une liste. Voici la maniĂšre naĂŻve :

equities = {}
for (portfolio, equity) in data:
    if portfolio in equities:
        equities[portfolio].append(equity)
    else:
        equities[portfolio] = [equity]

dict.setdefault(key, default) s'occupe de ça de maniÚre beaucoup plus rapide :

equities = {}
for (portfolio, equity) in data:
    equities.setdefault(portfolio, []).append(equity)

dict.setdefault() est équivalent à "get ou set & get". Ou "set si nécessaire, puis get". C'est particuliÚrement rapide si votre clé de dictionnaire est coûteuse à générer ou longue à taper.

Le s*eul problĂšme avec dict.setdefault() c'est que la valeur par dĂ©faut est Ă©valuĂ©e, qu'elle soit utilisĂ©e ou non. Ça ne pose problĂšme que si la clĂ© est coĂ»teuse Ă  calculer.

Si la valeur par défaut est coûteuse à calculer, vous devriez plutÎt utiliser la classe defaultdict.

La méthode setdefault des dictionnaires (2)

On va voir qu'il est possible d'utiliser setdefault pour déclarer une valeur par défaut :

navs = {}
for (portfolio, equity, position) in data:
    navs.setdefault(portfolio, 0)
    navs[portfolio] += position * prices[equity]

La méthode setdefault d'un dictionnaire retourne la valeur par défaut, mais nous l'ignorons ici. On tire profit d'une conséquence de l'utilisation de setdefault, la valeur n'est initialisée que si elle n'existe pas déjà.

defaultdict

Nouveau avec Python 2.5.

<+code>defaultdict est nouveau dans Python 2.5, il fait partie du module collections. defaultdict est identique aux dictionnaires classiques, excepté pour deux cas :

  • il prend un premier argument optionnel : une fonction factory par dĂ©faut
  • lorsqu'une clĂ© de dictionnaire est rencontrĂ©e pour la premiĂšre fois, la fonction factory par dĂ©faut est appelĂ©e et le rĂ©sultat initialise la valeur du dictionnaire.

Il y a deux maniÚres d'accéder à defaultdict :

  • importer le module collections et l'appeler Ă  travers le module :

    import collections
    d = collections.defaultdict(...)
    
  • ou importer defaultdict directement :

    from collections import defaultdict
    d = defaultdict(...)
    

Voici l'exemple dĂ©jĂ  traitĂ©, oĂč chaque valeur du dictionnaire fois ĂȘtre initialisĂ© pour ĂȘtre une liste vide, réécrit en ,utilisant defaultdict :

from collections import defaultdict

equities = defaultdict(list)
for (portfolio, equity) in data:
    equities[portfolio].append(equity)

Il n'y a plus d'astuce ici. Dans ce cas, la fonction factory par défaut est list, ce qui retourne une liste vide.

C'est la maniÚre d'avoir un dictionnaire avec les valeurs par défaut à 0, utilisez int comme factory :

navs = defaultdict(int)
for (portfolio, equity, position) in data:
    navs[portfolio] += position * prices[equity]

Il faut faire attention Ă  defaultdict quand mĂȘme. Vous ne pouvez pas utiliser l'exception KeyError sur un dictionnaire initialisĂ© avec defaultdict. Vous devez utiliser la condition "key in dict" si vous voulez vĂ©rifier l'existence d'une clĂ© de maniĂšre spĂ©cifique.

Construire et scinder des dictionnaires

Voila une technique utile pour co-nstruire un dictionnaire à partir de deux listes (ou séquences), une liste pour les clés, une liste pour les valeurs :

given = ['John', 'Eric', 'Terry', 'Michael']
family = ['Cleese', 'Idle', 'Gilliam', 'Palin']
pythons = dict(zip(given, family))
>>> pprint.pprint(pythons)
{'John': 'Cleese',
 'Michael': 'Palin',
 'Eric': 'Idle',
 'Terry': 'Gilliam'}

L'inverse est trivial bien sûr :

 >>> pythons.keys()
 ['John', 'Michael', 'Eric', 'Terry']
 >>> pythons.values()
 ['Cleese', 'Palin', 'Idle', 'Gilliam']

Notez que l'ordre du résultat des .keys() et .values() à est différent des listes utilisées lors de la création du dictionnaire. L'ordre d'entrée est différent de l'ordre de sortie car un dictionnaire n'est pas ordonné. Par contre, l'ordre des clés est consistant avec celui des valeurs, à condition que le dictionnaire n'ait pas été modifié entre temps.

Tester des valeurs vraies

Il est élégant et rapide de tirer partie des avantages de Python en ce qui concerne les valeurs booléennes :

# faites ça :     # et pas ça :
if x:             if x == True:
    pass              pass

Test d'une liste :

# faites ça :     # et pas ça :
if items:         if len(items) != 0:
    pass              pass

                  # et surtout pas ça :
                  if items != []:
                      pass

Valeurs vraies

Les noms True et False sont des instances intrinsÚques à Python de type bool, des valeurs booléennes. Comme None, il n'existe qu'une seule instance de chaque.

/ 0
False True
False (== 0) True (== 1)
"" (empty string) toutes les chaĂźnes Ă  part "" (" ", "nimportequoi")
0, 0.0 n'importe quel chiffre Ă  part 0 (1, 0.1, -1, 3.14)
[], (), {}, set() n'importe quel container non vide ([0], (None,), [''])
None pratiquement tous les objets qui ne sont explicitement équivalents à False

Voici par exemple un objet qui est toujours vrai :

>>> class C:
...  pass
...
>>> o = C()
>>> bool(o)
True
>>> bool(C)
True

Pour contrÎler la valeur booléenne d'une instance ou d'une classe définie, utilisez les méthodes spéciales __nonzero__ ou __len__. Utilisez __len__ si votre classe est un container qui a une taille :

class MyContainer(object):

    def __init__(self, data):
        self.data = data

    def __len__(self):
        """Return my length."""
        return len(self.data)

Si votre classe n'est pas un container, utilisez __nonzero__ :

class MyClass(object):

    def __init__(self, value):
        self.value = value

    def __nonzero__(self):
   1     """Return my truth value (True or False)."""
        # This could be arbitrarily complex:
        return bool(self.value)

En Python 3.0, __nonzero__ a Ă©tĂ© renommĂ© __bool__ afin d'ĂȘtre consistant avec le type bool natif. Pour ĂȘtre compatible, ajoutez ceci Ă  la dĂ©finition de votre classe :

__bool__ = __nonzero__

Index & Item (1)

Voici une maniÚre élégante de vous épargner quelques lignes si vous avez besoin d'une liste de mots :

>>> items = 'zero one two three'.split()
>>> print items
['zero', 'one', 'two', 'three']

Prenons l'exemple d'un itération entre les items d'une liste, pour laquelle nous voulons à la fois l'item et la position (l'index) de cet item dans la liste :

                  - ou -
i = 0
for item in items:      for i in range(len(items)):
    print i, item               print i, items[i]
    i += 1
<2/code>

Index & Item (2): enumerate

La fonction enumerate prend une liste et retourne des paires (index, item) :

>>> print list(enumerate(items))
[(0, 'zero'), (1, 'one'), (2, 'two'), (3, 'three')]

Il est nĂ©cessaire d'avoir recours Ă  une list pour afficher les rĂ©sultats car enumerate est une fonction fainĂ©ante, gĂ©nĂ©rant un item (une paire) Ă  la fois, seulement lorsqu'il est demandĂ©. Une boucle for nĂ©cessite un tel mĂ©canisme. enumerate est un exemple de gĂ©nĂ©rateur dont on parlera plus tard des dĂ©tails. print ne prend pas un rĂ©sultat Ă  la fois mais doit ĂȘtre en possession de la totalitĂ© du message Ă  afficher. On a donc converti automatiquement le gĂ©nĂ©rateur en une liste avant d'utiliser print.

Notre boucle devient beaucoup plus simple :

for (index, item) in enumerate(items):
    print ind3ex, item

# comparé à :              # comparé à :
index = 0               for i in range(len(items)):
for item in items:              print i, items[i]
    print index, item
    index += 1

La version avec enumerate est plus courte et plus simple que la version de gauche, et plus facile Ă  lire que les deux autres.

Un exemple montrant que la fonction enumerate retourne un itérateur (un générateur est une sorte d'itérateur) :

>>> enumerate(items)
<enumerate object at 0x011EA1C0>
>>> e = enumerate(items)
>>> e.next()
(0, 'zero')
>>> e.next()
(1, 'one')
>>> e.next()
(2, 'two')
>>> e.next()
(3, 'three')
>>> e.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
StopIteration

Les autres langages ont des "variables"

Dans de nombreux autres langages, assigner une variable revient Ă  mettre une valeur dans une boĂź4te.

int a = 1;

BoĂźte 1 a

La boĂźte "a" contient maintenant un integer 1.

Assigner une autre valeur Ă  la mĂȘme variable remplace le contenu de la boĂźte :

a = 2;

BoĂźte 2 a

Maintenant la boĂźte "a" contient un integer 2.

Assigner une variable à une autre crée une copie de la valeur et la met dans une nouvelle boßte :

int b = a;

BoĂźte 2 a

BoĂźte 2 b

"b" est une seconde boßte, avec une copie de l'entier 2. La boßte "a" en a une copie séparée.

Python a des "noms"

En Python, un "nom" ou "identifiant" est comme une étiquette attachée à un objet.

a = 1

Tag 1 a

Ici, un objet integer 1 a une étiquette appelée "a".

Si on réassigne "a", on déplace juste l'étiquette sur un autre objet :

a = 2

Tag 2 a

1

Maintenant le nom "a" est attaché à un objet entier 2.

L'objet entier 1 n'a plus le tag "a". Il peut encore exister mais on n'y a plus accÚs via le nom "a". (Lorsqu'un objet n'a plus aucune référence ou étiquette, il est supprimé de la mémoire.)

Si l'on assigne un nom à un autre, on attache juste une autre étiquet6te à un objet existant :

b = a

Tag 2 a b

Le nom "b" est juste une seconde Ă©tiquette attachĂ©e au mĂȘme objet que "a".

Bien que l'on réfÚre communément aux "variables" en Python (car c'est une terminologie commune aux autres langages), on manipule vraiment de "noms" ou "identifiants". En Python, les "variables" sont des étiquettes pour des valeurs, non des boßtes nommés.

Si vous ne comprenez rien au reste de ce tutoriel, j'espÚre que vous aurez$ au moins retenu la façon dont les noms fonctionnent. Une bonne compréhension vous permettra d'apprendre rapidement et d'éviter des erreurs comme celle-ci:

Valeurs de paramÚtres par défaut

C'est une erreur courante que les dĂ©butants font souvent. MĂȘme les dĂ©veloppeurs plus expĂ©rimentĂ©s la font s'ils n'ont pas compris comment fonctionnent les noms en Python.

def bad_append(new_item, a_list=[]):
    a_list.append(new_item)
    return a_list

Le problĂšme ici c'est que la valeur par dĂ©faut a_list, une liste vide, est Ă©valuĂ©e lors de la dĂ©finition de la fonction. Ainsi Ă  chaque fois que vous appelez la fonction vous obtenez la mĂȘme valeur par dĂ©faut. Essayez plusieurs fois :

>>> print bad_append('one')
['one']

>>> print bad_append('two')
['one', 'two']

Les listes sont modifiables, vous pouvez modifier leur contenu. La bonne maniÚre d'avoir une liste par défaut (ou dictionnaire, ou set) est de la créer au moment du lancement, au sein de la fonction :

def good_append(new_item, a_list=None):
    if a_list is None:
        a_list = []
    a_list.append(new_item)
    return a_list

Formattage des chaĂźnes de caractĂšres avec %

L'opérateur % fonctionne en Python comme la fonction sprintf de C.

Bien sûr si vous ne connaissez pas C, ça ne vous aide pas. Pour faire simple, vous définissez un template ou format et des valeurs qui seront interprétées.

Dans cet exemple, le template contient deux spécifications de conversion "%s" signifie "insérer une chaßne de caractÚre ici" et "%i" signifie "convertir un integer en string et l'insérer ici". "%s" est particuliÚrement utile car il utilise la fonction standard str() pour convertir un objet en une chaßne de caractÚres.

Les valeurs proposées doivent correspondrent au template, on a deux valeurs ici, un tuple.

name = 'David'
messages = 3
text = ('Hello %s, you have %i messages'
        % (name, messages))
print text

Ce qui donne :

Hello David, you have 3 messages

Les détails sont dans la Python Library Reference, section 2.3.6.2, "String Formatting Operations". Mettez cette page en favoris !

Si9 vous ne l'avez pas encore fait, allez sur python.org, téléchargez la documentation en HTML (dans un .zip ou une archive), et installez la sur votre machine. Il n'y a rien de mieux que d'avoir la ressource de référence à portée de clavier.

Formattage des chaßnes de caractÚres avancé

Pourquoi est-ce qu'il y a autant de personnes qui ne réalisent pas qu'il y a d'autres façons de formater les chaßnes de caractÚres qui peuvent s'avérer plus puissantes ?

Avec des noms grĂące Ă  un dictionnaire :

values = {'name': name, 'messages': messages}
print ('Hello %(name)s, you have %(messages)i '
       'messages' % values)

Ici on a spécifié les noms des valeurs interprétées, qui constituent les clés du dictionnaire.

Vous trouvez qu'il y a de la redondance ? Les noms "name" et "messages" sont déjà définis localement. On peut en tirer parti.

En utilisant les variables locales :

print ('Hello %(name)s, you ha:ve %(messages)i '
       'messages' % locals())

La fonction locals() retourne un dictionnaire de toutes les variables locales disponibles.

C'est trÚs puissant. Grùce à ça, vous pouvez formater toutes les chaßnes de caractÚres que vous voulez sans avoir à vous soucier de la correspondance positionnelle avec les valeurs soumises en argument.

Mais le pouvoir peut ĂȘtre dangereux. ("With great power comes great responsibility.") Si vous utilisez locals() avec un template issu d'une ressource externe, vous exposez l'intĂ©gralitĂ© de votre espace de noms local. C'est une chose Ă  garder en tĂȘte.

Pour examiner votre espace de nom local :

>>> from pprint import pprint
>>> pprint(locals())

pprint est un module trĂšs utile. Si vous ne le connaissiez pas dĂ©jĂ , essayez de jouer avec. Ça rend le debugging des donnĂ©es structurĂ©es beaucoup plus simple !

Formattage d;es chaßnes de caractÚres avancé

L'espace de nom des attributs d'une instance d'objet est simplement un dictionnaire, self.__dict__.

En utilisant l'espace de nom d'une instance :

print ("We found %(error_count)d errors"
       % self.__dict__)

Equivalent Ă , mais moins flexible que :

print ("We found %d errors"
       % self.error_count)

Note: Les attributs d'une classe sont dans le __dict__ de la classe. Les espaces de noms sont hérités et constituent donc des dictionnaires chaßnés.

List Comprehensions

Les list comprehensions ("listcomps" pour les intimes) sont des raccourcis syntaxiques pour ce pattern généralement utilisé.

La maniĂšre traditionnelle avec for et if :

new_list = []
for item in a_list:
    if condition(item):
        new_list.append(fn(item))

En utilisant une list comprehension :

<
new_list = [fn(item) for item in a_list
            if condition(item)]

Les listcomps sont claires et concises, directes. Vous pouvez avoir plusieurs boucles for et conditions if au sein d'une mĂȘme listcomp, mais au-delĂ  de deux ou trois, ou si les conditions sont complexes, je vous suggĂšre d'utiliser l'habituelle boucle for. En appliquant le Zen de Python, utilisez la mĂ©thode la plus lisible.

Par exemple, la liste des carrés de 0 à 9 :

>>> [n ** 2 for n in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

La liste des nombres impairs au sein de la précédente liste :

>>> [n ** 2 for n in range(10) if n % 2]
[1, 9, 25, 49, 81]

Generator Expressions (1)

Faisons la somme des carrés des nombres inférieurs à 100 :

Avec une boucle :

total = 0
for num in range(1, 101):
    total += num * num
<=p>On peut aussi utiliser la fonction sum qui fait plus rapidement le travail pour nous en construisant la bonne séquence.

Avec une list comprehension :

total = sum([num * num for num in range(1, 101)])

Avec une generator expression :

total = sum(num * num for num in xrange(1, 101))

Les generator expressions ("genexps") sont comme les list comprehensions, excepté dans leur calcul, les genexps sont fainéantes. Les listcomps calculent l'intégralité du résultat en une seule passe, pour le stocker dans une liste. Les generator expressions calculent une valeur à la fois, lorsqu'elle est nécessaire. C'est particuliÚrement utile lorsque la séquence est trÚs longue lorsque la liste générée n'est qu'une étape intermédiaire et non le résultat final.

Dans ce cas, on est uniquement intĂ©ressĂ© par la somme, on n'a pas besoin de la liste des rĂ©sultats intermĂ©diaires. On utilise xrange pour l>a mĂȘme raison, ça gĂ©nĂšre les valeurs une par une.

Generator Expressions (2)

Par exemple si on doit faire la somme des carrés de plusieurs milliards d'entiers, on va arriver à une saturation de la mémoire avec une list comprehension, mais les generator expressions ne vont avoir aucun problÚme. Bon ça va prendre un certain temps par contre !

total = sum(num * num
            for num in xrange(1, 1000000000))

La différence de syntaxe est que les listcomps ont des crochets, alors que les genexps n'en ont pas. Les generator expressions nécessitent parfois des parenthÚses par contre, vous devriez donc toujours les utiliser.

En bref :

  • Utilisez une list comprehension lorsque le rĂ©sultat escomptĂ© est la liste.
  • Utilisez une generator expression lorsque la liste n'est qu'un rĂ©sultat intermĂ©diaire.

Voici un récent exemple de ce que j'ai vu au boulot.

On avait besoin d'un dictionnaire qui corresp?onde aux chiffres des mois (Ă  la fois via des chaĂźnes de caractĂšres et via des integers) au code des mois pour un client. Cela peut ĂȘtre fait avec une ligne de code.

Ça fonctionne de la maniùre suivante :

  • La fonction de rĂ©fĂ©rence dict() prend en argument une liste de paires de clĂ©s/valeurs (2-tuples).
  • On a une liste des codes des mois (chaque code est une simple lettre, et une chaĂźne de caractĂšres est aussi une simple liste de lettres). On parcours cette liste pour obtenir Ă  la fois le code du mois et l'index.
  • Le nombre des mois commence Ă  1 mais Python commence l'indexation Ă  0, le nombre des mois correspond dont Ă  index+1.
  • On veut avoir la correspondance Ă  la fois avec les nombres et les chaĂźnes de caractĂšres. On peut utiliser les fonctions int() et str() pour ça et itĂ©rer dessus.

L'exemple en question :

 month_codes = dict((fn(i+1), code)
     for i, code in enume@rate('FGHJKMNQUVXZ')
     for fn in (int, str))

Le résultat obtenu pour month_codes :

{ 1:  'F',  2:  'G',  3:  'H',  4:  'J', ...
 '1': 'F', '2': 'G', '3': 'H', '4': 'J', ...}

Ordonner

Il est trĂšs simple d'ordonner une liste en Python :

a_list.sort()

(Notez que la liste est ordonnée sur place, la liste originale est ordonnée et la fonction sort ne retourne pas une liste ou une copie.)

Mais que faire lorsque vous avec une liste de données à ordonner, mais quelle ne s'ordonne pas de maniÚre naturelle ? Par exemple ordonner selon la premiÚre colonne, puis la quatriÚme.

On peut utiliser la fonction de référence sort avec une méthode définie par nos soins :

def custom_cmp(item1, item2):
    returm cmp((item1[1], item1[3]),
               (item2[1], item2[3]))

a_list.sort(custom_cmp)

Ça marche, maAis c'est extrĂȘmement lent pour les listes Ă©normes.

Ordonner avec DSU

DSU = Decorate-Sort-Undecorate

Note: DSU n'est bien souvent plus nécessaire, cf. section suivante.

Au lieu de crĂ©er une fonction de comparaison personnalisĂ©e, on crĂ©e une liste intermĂ©diaire qui va pourvoir ĂȘtre ordonnĂ©e naturellement :

# Decorate:
to_sort = [(item[1], item[3], item)
           for item in a_list]

# Sort:
to_sort.sort()

# Undecorate:
a_list = [item[-1] for item in to_sort]

La premiÚre ligne crée une liste contenant des tuples, une copie de la valeur à ordonner en premier argument, suivi de la valeur complÚte de la liste.

La seconde ligne ordonne grĂące Ă  la fonction Python, ce qui est trĂšs rapide.

La troisiÚme ligne récupÚre la derniÚre valeur de la liste une fois ordonnée. Souvenez-vous, cette derniÚre valeur correspond à l'item complet. On n'utilise plus la partie ayant permis d'ordonner, elle a Bjoué son rÎle et n'est plus utile.

C'est un compromis espace mémoire + complexité vs. temps. Plus simple et rapide mais on est obligé de dupliquer la liste originale.

Ordonner avec keys

Python 2.4 a introduit un nouvel argument à la méthode sort des listes, "key", qui permet de spécifier une fonction à un argument qui est utilisée pour comparer chaque élément d'une liste avec les autres. Par exemple :

def my_key(item):
    return (item[1], item[3])

to_sort.sort(key=my_key)

La fonction my_key va ĂȘtre appelĂ©e une fois par item de la liste to_sort.

Vous pouvez utiliser votre propre fonction ou utiliser une fonction existante qui ne prend qu'un seul argument :

  • str.lower pour ordonner alphabĂ©tiquement sans tenir compte de la casse.
  • len pour ordonner selon la taille des items (chaĂźnes de caractĂšres ou containers).
  • int Cou float pour ordonner numĂ©riquement avec des valeurs qui sont des chaĂźnes de caractĂšres comme "2", "123", "35".

Generators

On a déjà vu les generator expressions. On peut créer nos propres generators, comme des fonctions :

def my_range_generator(stop):
    value = 0
    while value < stop:
        yield value
        value += 1

for i in my_range_generator(10):
    do_something(i)

Le mot-clé yield transforme une fonction en generator. Lorsque vous appelez une fonction generator, au lieu d'exécuter le code directement, Python retourne un objet generator, qui est un itérateur. Il a une méthode next. Les boucles for appellent la méthode next de l'itérateur, jusqu'à ce qu'une exception du type StopIteration soit levée. Vous pouvez lever l'exception StopIteration explicitement ou de maniÚre implicite comme dans le code ci-dessous.

Les gDĂ©nĂ©rateurs peuvent simplifier la maniĂšre de gĂ©rer les sĂ©quences/itĂ©rateurs, car on n'a pas besoin de crĂ©er des listes intermĂ©diaires. Ça ne gĂ©nĂšre qu'une valeur Ă  la fois.

Voici comment la boucle for fonctionne réellement. Python analyse la séquence déclarée avec le mot-clé in. Si c'est un simple container (comme une liste, un tuple, un dictionnaire, un set ou un container défini par l'utilisateur) Python le converti en itérateur. Si c'est déjà un itérateur, Python ne fait rien.

Python appelle ensuite de maniÚre itérative la méthode next de l'itérateur, assignant la valeur retournée au compteur de la boucle (i dans notre cas), et exécute le code indenté. C'est répété, encore et encore jusqu'à ce que StopIteration soit levée, ou qu'un break soit exécuté.

Une boucle for peut ĂȘtre dotĂ©e d'un else, au sein de laquelle le code est exĂ©cutĂ© si Erien ne s'est produit dans la boucle for, mais non aprĂšs un break. Cette distinction permet de faire des choses Ă©lĂ©gantes. else est rarement utilisĂ© avec la boucle for mais peut s'avĂ©rer trĂšs puissant lorsque la logique correspond Ă  ce que vous souhaitez faire.

Par exemple, si on doit vérifier qu'une condition est toujours remplie par tous les items d'une liste :

for item in sequence:
    if condition(item):
        break
else:
    raise Exception('Condition not satisfied.')

Exemple de generator

Filtrer les colonnes vides Ă  partir d'un fichier CSV (ou des items d'une liste) :

def filter_rows(row_iterator):
    for row in row_iterator:
        if row:
            yield row

data_file = open(path, 'rb')
irows = filter_rows(csv.reader(data_file))

Lire les lignes d'un fichier de données

datafile = open('datafile')
for line in datafile:
    doF_something(line)

C'est possible car les fichiers sont dotés d'une méthode next, comme d'autres itérateurs : les listes, les tuples, les dictionnaires (pour leurs clés), les generators.

Il y a un piÚge ici : étant donnée la façon dont sont mises en cache les données, vous ne pouvez pas utiliser à la fois les méthodes .next et .read* à moins que vous n'utilisez Python 2.5+.

EAFP vs. LBYL

Il est plus facile de demander le pardon que la permission (EAFP) vs. analyser avant d'échouer (LBYL). Généralement EAFP est préféré, mais pas toujours.

  • Duck typing Si ça marche comme un canard, parle comme un canard et ressemble Ă  un canard : c'est un canard.
  • Exceptions Essayez de forcer le type si un objet doit ĂȘtre d'un type particulier. Si x doit ĂȘtre une chaĂźne de caractĂšres pour que votre code fonctionne, pourquoi ne pas appeler str(x) au lieu d'essayer quelque` cGhose comme isinstance(x, str).

Exemple EAFP try/except

Vous pouvez encapsuler vos exceptions dans un bloc try/except pour pour récupérer les erreurs et vous allez probablement arriver à une solution qui est beaucoup plus générale que si vous aviez essayer d'anticiper chaque cas.

try:
    return str(x)
except TypeError:
    ...

Note: SpĂ©cifiez toujours l'exception Ă  attraper. N'utilisez jamais except tout seul. Sinon except va cacher d'autres exceptions qui risquent d'ĂȘtre levĂ©es rendant votre code trĂšs difficile Ă  debugger.

Importer

from module import *

Vous avez probablement dĂ©jĂ  vu cette maniĂšre de faires des imports avec une "Ă©toile". Vous l'apprĂ©ciez peut-ĂȘtre. Ne l'utilisez pas.

Pour paraphraser un exemple trĂšs connu :

LUKE: Est-ce que from module import *H est meilleur que des imports explicites ?
YODA: Non, pas meilleur. Plus rapide, plus simple, plus séduisant.
LUKE: Mais comment saurais-je pourquoi les imports explicites sont meilleurs que les formes étoilées ?
YODA: Tu sauras lorsque ton code dans 6 mois tu essayeras de lire.

Les imports étoilés sont le mauvais cÎté de la Force en Python.

Les imports de type from module import * polluent votre espace de nom. Vous allez avoir des choses que vous n'attendiez pas. Vous pouvez avoir des conflits avec les noms que vous avez dĂ©fini localement. Vous n'allez plus savoir d'oĂč viennent certains noms. Bien que ce soit un raccourci pratique, ça ne doit pas arriver en production.

Morale : n'utilisez pas d'imports étoilés !

Il est bien meilleur de référencer les noms à partir de leurs modules :

import module
module.name

importer un module avec un nom plus court si nĂI©cessaire (avec alias) :

import long_module_name as mod
mod.name

ou importer juste les noms dont vous avez besoin de maniĂšre explicite :

from module import name
name

Notez qu'il est nécessaire d'utiliser "reload()" sur un module lorsque vous utilisez le prompt interactif si vous éditez celui-ci.

Modules et scripts

Pour faire à la fois un module importable et un script exécutable :

if __name__ == '__main__':
    # script code here

Lorsqu'il est importĂ©, un attribut__name__ est settĂ©, correspondant au nom du fichier du module, sans ".py". Le code ci-dessus ne va donc pas ĂȘtre lancĂ© lors d'un import. Lorsqu'il est lancĂ© comme un script, l'attribut __name__ est settĂ© Ă  "main" et le script va ĂȘtre exĂ©cutĂ©.

Excepté pour certains cas spéciaux, vous ne devriez placer aucun code important au plus haut niveau. PlaceJz votre code dans des fonctions, classes, méthodes et protégez le avec if __name__ == '__main__'.

Structure d'un module

"""module docstring"""

# imports
# constants
# exception classes
# interface functions
# classes
# internal functions & classes

def main(...):
    ...

if __name__ == '__main__':
    status = main()
    sys.exit(status)

C'est la façon dont un module devrait ĂȘtre structurĂ©.

Utilisation de la ligne de commande

Exemple (Note du traducteur : j'ai déjà parlé de ça aussi) :

#!/usr/bin/env python

"""
Module docstring.
"""

import sys
import optparse

def process_command_line(argv):
    """
    Return a 2-tuple: (settings object, args list).
    `argv` is a list of arguments, or `None` for ``sys.argv[1:]``.
    """
    if argv is None:
        argv = sys.argv[1:]

    # initKialize the parser object:
    parser = optparse.OptionParser(
        formatter=optparse.TitledHelpFormatter(width=78),
        add_help_option=None)

    # define options here:
    parser.add_option(      # customized description; put --help last
        '-h', '--help', action='help',
        help='Show this help message and exit.')

    settings, args = parser.parse_args(argv)

    # check number of arguments, verify values, etc.:
    if args:
        parser.error('program takes no command-line arguments; '
                     '"%s" ignored.' % (args,))

    # further process settings & args if necessary

    return settings, args

def main(argv=None):
    settings, args = process_command_line(argv)
    # application code here, like:
    # run(settings, args)
    return 0        # success

if __name__ == '__main__':
    status = main()
    sys.exit(status)

Packages

package/
    __init__.py
    module1.py
    subpackage/
        __init__.py
        module2.py
  • UtilisĂ©s pour organiser un projet.
  • RĂ©duisent le nombre d'entrĂ©es lors du chargement.
  • RĂ©duisent les conflits en cas d'imports.

Exemple :

import package.module1
from packages.subpackage import module2
from packages.subpackage.module2 import name

En Python 2.5 on a maintenant les imports absolus et relatifs via un import du futur :

from __future__ import absolute_import

Je n'ai pas encore eu l'occasion de tester ça moi-mĂȘme, on va donc couper court Ă  toute discussion Ă  ce sujet.

Simple is Better Than Complex

DĂ©bugger est deux fois plus difficile que d'Ă©crire du code en premier jet. De plus, si vous Ă©crivez le code aussi intelligemment que possible, vous ĂȘtes, par dĂ©finition, pas assez intelligent pour le dĂ©bugger.

-- Brian W. Kernighan, co-auteur de The C Programming Language et le "K" dans "AWK"

M

En d'autres termes, gardez vos programmes simples !

Ne réinventez pas la roue

Avant d'écrire une seule ligne de code,

  • VĂ©rifiez que cela n'est pas dans la bibliothĂšque standard de Python.
  • VĂ©rifiez que cela n'est pas dans le Python Package Index (the "Cheese Shop")
  • Cherchez sur le web. Google is your friend.

Retour du traducteur

Pour terminer, et si vous souhaitez aller plus loin, une excellente prĂ©sentation sur les gĂ©nĂ©rateurs que je n'aurais malheureusement pas le temps de traduire permet d'envisager la programmation Python d'une maniĂšre tout Ă  fait diffĂ©rente. Elle est orientĂ©e administration systĂšme mais elle peut vraiment ĂȘtre appliquĂ©e Ă  de nombreux cas. Et si vous voulez comprendre l'intĂ©rĂȘt des dĂ©corateurs, un bon exemple vaut mieux que tous les discours. Mangez du Python, c'est bon pour la santĂ© !

Logo biologeek Bonnes pratiques et astuces Python a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 11 Mai 2008. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

[Biologeek] Bonnes pratiques et astuces PythonBonnes pratiques et astuces PythonOp://tamblague.canalblog.com/archives/2007/09/25/6329791.html">Ă  Ottawa
  • le kebab quebecois
  • le village Huron et la cabane Ă  sucre
  • les baleines et l'hydravion
  • et enfin Ă  la pourvoirie
  • Bon mĂȘme si je rĂąle un peu (je suis un peu français aussi non ?), c'Ă©tait vraiment de super vacances !

    On enchaine avec un billet de Jeff Croft intitulĂ© Tools do not a designer make qui nous rappelle que les qualitĂ©s d'un dĂ©veloppeur/grPaphiste ne rĂ©sident pas dans ses outils mais bien dans ses capacitĂ©s :

    Hopefully only a small percentage of my salary is because I know CSS and Photoshop. [...] Think about it: do you go to the doctor because of her ability to use a stethoscope? [...] If being a great web designer is your goal, I would suggest most of your time ought not be spent on learning tools.

    Il faudra que je reparle de ça dans un prochain billet.

    Je n'ai pas vraiment eu l'occasion de connaĂźtre la mutilation de la dĂ©connexion de Christian FaurĂ© durant ces vacances car tous les hĂŽtels avaient le Wi-Fi, mais je vous laisse apprĂ©cier un passage criant de vĂ©ritĂ© :

    La dĂ©connexion pendant les vacances est un moment qui, depuis quelques annĂ©es, prend de plus en plus d’importance. Cette annĂ©e, j’ai eu l’impression d’ĂȘtre mis sur la touche. DQe ne plus vivre aussi pleinement que lorsque je suis connectĂ©. J’ai eu l’impression Ă  la fois de ne plus progresser et d’ĂȘtre comme privĂ© d’une partie de mon corps.

    J'aime bien la derniĂšre citation qui colle bien avec ce billet et les commentaires sont aussi excellents :

    Le travail du blogueur consiste Ă  amasser des URLs dans un but de publication.

    Une interview longue mais intĂ©ressante du crĂ©ateur de Textmate :

    Like I had to do a presentation in LaTeX Beamer, and I had never used Beamer before, and it was like, when I do ‘frame’, it completes it, and when i do ‘itemize’, it adds in which slide the item should appear on, and it’s like, “I don’t have to read the manual for this language.”

    Titus Brown nous dĂ©crit comment Writing Code That Doesn't Suck en Python et mĂȘme si c'est du connu il est bon de s'en rappeler quelques fois :

    Not interested in conforming? Well, I know you're brilliant and idiosyncratic and your personal naming conventions, or spacing choice, or homegrown test framework, are important signs of your individuality and creativity -- but unfortunately they're likely to get in my way when I try to use your code. What I'm really interested in is the creativity of your approach and algorithms.

    On m'a reprochĂ© (Ă  juste titre) lors des JournĂ©es Francophones Python de ne pas assez m'intĂ©resser Ă  Zope 3, heureusement Lorenzo Gil s'en est chargĂ© avec un tutoriel en 3 parties pour les djangonautes :

    J'attends la suite pour donner mon avis.

    Babozor m'a demandĂ© par mail de parler de l'enquĂȘte sur les salaires des travailleurs du web. Dommage que ça ait Ă©tĂ© aussi impersonnel, surtout pour une lecture quotidienne de qualitĂ©... ça doit ĂȘtre la rançon de l'influence (huhu).

    J'ai dĂ©couvert le blog de Nicolas Cynober qui parle du web sĂ©mantique et qui aurait Ă  mon avis sa place sur le planete web sĂ©mantique. C'est bien si ça commence un peu Ă  bouger sur Tle web sĂ©mantique en France, ça nous changera des dĂ©finitions comiques :

    J’ai eu l’idĂ©e de crĂ©er ce blog suite au mouvement “Madame Irma” qui a saisi la blogosphĂšre. Beaucoup de monde en ce moment a des visions (I had a dream last night
), et je pense qu’il serait intĂ©ressant d’apporter sur la scĂšne française un peu de tempĂ©rament, un autre regard sur le web.

    Il faut que je trouve le temps de lire enGooglés, ainsi que les conseils pour jeune startup web, pareil pour le Python Magazine, premier tirage en libre téléchargement.

    CĂŽtĂ© social network portability (Ă©voquĂ© dans le billet sur le web social), l'idĂ©e d'associer FOAF et OpenID poursuit son chemin avec un conseil d'utilisation d'Alexandre Passant et une rĂ©flexion chez captsolo :

    FOAF was created with identification of objects in mind. It is built on RDF, which is a generic format for linked data on the web. As such, it gives us some flexibility on how pieces of data can be distributed across the web.

    Tout comme Loïc d'Anterroches, je m'inquiÚte de la fin de Thunderbird... ça serait bien dommage aprÚs tant d'années de bons et loyaux services.

    Vous n'avez pas eu la chance d'assister aux conférences de FOWA, rattrapez vous en lisant les comptes rendus complets de Stéphanie Booth, merci.

    Voila, sinon j'ai aussi d'autres liens mais il faudra que je leur consacre un billet complet.

    Logo biologeek Des vacances et des liens a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 07 Octobre 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (pWresque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

    AprĂšs ĂȘtre venu Ă  bout du 1000+ de Google Reader, autant partager avec vous mes derniĂšres dĂ©couvertes car les billets de qualitĂ© ont Ă©tĂ© nombreux au cours de mes vacances. J'ai un peu la flemme de tout classer, au moins vous lirez jusqu'au bout ;-).

    On commence avec mes vacances en dessins, grĂące Ă  ma CdG qui raconte beaucoup mieux que moi :

    Bon mĂȘme si je rĂąle un peu (je suis un peu français aussi non ?), c'Ă©tait vraiment de super vacances !

    On enchaine avec un billet de Jeff Croft intitulĂ© Tools do not a designer make qui nous rappelle que les qualitĂ©s d'un dĂ©veloppeur/graphiste ne rĂ©sident pas dans ses outils mais bien dans ses capacitĂ©s :

    Hopefully only a small percentage of my salary is because I know CSS and Photoshop. [...] Think about it: Ydo you go to the doctor because of her ability to use a stethoscope? [...] If being a great web designer is your goal, I would suggest most of your time ought not be spent on learning tools.

    Il faudra que je reparle de ça dans un prochain billet.

    Je n'ai pas vraiment eu l'occasion de connaĂźtre la mutilation de la dĂ©connexion de Christian FaurĂ© durant ces vacances car tous les hĂŽtels avaient le Wi-Fi, mais je vous laisse apprĂ©cier un passage criant de vĂ©ritĂ© :

    La dĂ©connexion pendant les vacances est un moment qui, depuis quelques annĂ©es, prend de plus en plus d’importance. Cette annĂ©e, j’ai eu l’impression d’ĂȘtre mis sur la touche. De ne plus vivre aussi pleinement que lorsque je suis connectĂ©. J’ai eu l’impression Ă  la fois de ne plus progresser et d’ĂȘtre comme privĂ© d’une partie de mon corps.

    <Zp>J'aime bien la derniĂšre citation qui colle bien avec ce billet et les commentaires sont aussi excellents :

    Le travail du blogueur consiste Ă  amasser des URLs dans un but de publication.

    Une interview longue mais intĂ©ressante du crĂ©ateur de Textmate :

    Like I had to do a presentation in LaTeX Beamer, and I had never used Beamer before, and it was like, when I do ‘frame’, it completes it, and when i do ‘itemize’, it adds in which slide the item should appear on, and it’s like, “I don’t have to read the manual for this language.”

    Titus Brown nous dĂ©crit comment Writing Code That Doesn't Suck en Python et mĂȘme si c'est du connu il est bon de s'en rappeler quelques fois :

    Not interested in conformin[g? Well, I know you're brilliant and idiosyncratic and your personal naming conventions, or spacing choice, or homegrown test framework, are important signs of your individuality and creativity -- but unfortunately they're likely to get in my way when I try to use your code. What I'm really interested in is the creativity of your approach and algorithms.

    On m'a reprochĂ© (Ă  juste titre) lors des JournĂ©es Francophones Python de ne pas assez m'intĂ©resser Ă  Zope 3, heureusement Lorenzo Gil s'en est chargĂ© avec un tutoriel en 3 parties pour les djangonautes :

    J'attends la suite pour donner mon avis.

    Babozor m'a demandĂ© par mail de parler de l'enquĂȘte sur les salaires des travailleurs du web. Dommage que ça ait Ă©tĂ© aussi impersonnel, surtout pour une lecture quotidienne de qualitĂ©... ça doit ĂȘtre la rançon de l'influence (huhu).

    J'ai dĂ©couvert le blog de Nicolas Cynober qui parle du web sĂ©mantique et qui aurait Ă  mon avis sa place sur le planete web sĂ©mantique. C'est bien si ça commence un peu Ă  bouger sur le web sĂ©mantique en France, ça nous changera des dĂ©finitions comiques :

    J’ai eu l’idĂ©e ]de crĂ©er ce blog suite au mouvement “Madame Irma” qui a saisi la blogosphĂšre. Beaucoup de monde en ce moment a des visions (I had a dream last night
), et je pense qu’il serait intĂ©ressant d’apporter sur la scĂšne française un peu de tempĂ©rament, un autre regard sur le web.

    Il faut que je trouve le temps de lire enGooglés, ainsi que les conseils pour jeune startup web, pareil pour le Python Magazine, premier tirage en libre téléchargement.

    CĂŽtĂ© social network portability (Ă©voquĂ© dans le billet sur le web social), l'idĂ©e d'associer FOAF et OpenID poursuit son chemin avec un conseil d'utilisation d'Alexandre Passant et une rĂ©flexion chez captsolo :

    FOAF was created with identification of objects in mind. It is built on RDF, which is a generic format for linked data on the web. As such, it gives us some flexibility on how pieces of data can be distributed across the web.

    Tout comme Loïc d'Anterroches, je m'inquiÚte de la fin de Thunderbird... ça serait bien dommage aprÚs tant d'années de bons et loyaux services.

    Vous n'avez pas eu la chance d'assister aux conférences de FOWA, rattrapez vous en lisant les comptes rendus complets de Stéphanie Booth</a>, merci.

    Voila, sinon j'ai aussi d'autres liens mais il faudra que je leur consacre un billet complet.

    Logo biologeek Des vacances et des liens a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 07 Octobre 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

    [Biologeek] Des vacances et des liensDes vacances et des liens »»x‚eAAŒŒW?http://www.biologeek.com/django,informatique,python,web-frameworks,web-semantique/des-vacances-et-des-liens/2008-08-31 17:41:09.4585912007-10-06 23:05:43.000000

    AprĂšs ĂȘtre venu Ă  bout du 1000+ de Google Reader, autant partager avec vous mes derniĂšres dĂ©couvertes car les billets de qualitĂ© ont Ă©tĂ© nombreux au cours de mes vacances. J'ai un peu la flemme de tout classer, au moins vous lirez jusqu'au bout ;-).

    On commence avec mes vacances en dessins, grĂące Ă  ma CdG qui raconte beaucoup mieux que moi :

    • les chutes du Niagara
    • sur le Saint-Laurent
    • cours pour apprendrce Python le livre How to Think Like a (Python) Programmer mais je ne l'ai pas encore lu. Si quelqu'un a dĂ©jĂ  eu ce courage (malgrĂ© son statut de draft), je suis avide de retours.

      Vous pouvez consulter l'ensemble de mes critiques de livres.

      Logo biologeek Envie de dĂ©velopper agilement en Python ? Suivez le guide ! a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 05 Septembre 2007. À part exceptions, c'est ©2008 David Ldarlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      J'ai beaucoup de mal Ă  critiquer un livre pour lequel j'ai fait une relecture (c'est la raison pour laquelle je n'avais pas parlĂ© de la seconde Ă©dition du livre Ubuntu) car j'ai gĂ©nĂ©ralement dĂ©jĂ  fait mes remarques Ă  l'auteur avant la parution. En ce qui concerne le Petit guide Ă  l’usage du dĂ©veloppeur agile, je me sens obligĂ© d'en parler car je suis trop jaloux de ne pas l'avoir Ă©crit :-).

      Ce livre est bien plus qu'un livre sur Python, c'est tout ce que vous ne trouverez pas dans les ouvrages classiques ou sur le net : de la mĂ©thodologie, des bonnes pratiques, des conseils pour progresser en tant que dĂ©veloppeur (pas forcĂ©ment Python), etc c'eset vraiment un ouvrage qui se place au-dessus des ouvrages de rĂ©fĂ©rence. Le concentrĂ© d'expĂ©rience de Tarek et la rĂ©flexion qu'il peut avoir sur le mĂ©tier de dĂ©veloppeur donne un savant mĂ©lange d'Ă©panouissement personnel et de progression au niveau de Python mais aussi de votre carriĂšre si vous ĂȘtes amenĂ© Ă  Ă©voluer vers la gestion de projet. J'aurais vraiment aimĂ© pouvoir lire ce livre il y a quelques annĂ©es !

      Je pense sincÚrement que l'industrie de l'édition devrait se tourner vers ce type de livre car les ouvrages de référence ont bien souvent leur pendant sur le net alors que cette expérience est plus difficile à trouver, on la retrouve parfois sur les blogs mais l'information est fractionnée <teasing>(pour le moment)</teasing>.

      Cette parenthĂšse Ă©tant faite, j'ai trouvĂ© un dĂ©faut en le relisant une n-iĂšme fois, c'est au niveau du sous-chapitre sur la syntaxe de Python. Ça ne concerne que quelques pages mais je trouve que c'est ufn peu dĂ©placĂ© car ce livre s'adresse plus Ă  mon avis aux personnes connaissant dĂ©jĂ  Python ou ayant une certaine expĂ©rience en programmation et j'ai eu l'impression Ă  la relecture que les exemples Ă©taient de toute façon un peu trop compliquĂ©s pour les vrais dĂ©butants. Enfin rassurez-vous ça ne concerne que quelques pages.

      Bonus, le format permet de le glisser facilement dans un sac pour le lire dans le métro.

      Petite parenthÚse puisque j'en suis à parler de Python, j'ai ajouté à mes cours pour apprendre Python le livre How to Think Like a (Python) Programmer mais je ne l'ai pas encore lu. Si quelqu'un a déjà eu ce courage (malgré son statut de draft), je suis avide de retours.

      Vous pouvez consulter l'ensemble de mes critiques de livres.

      Logo biologeek Envie de dĂ©velopper agilement en Python ? Suivez le guide ! a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 05 Septembre 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      [Biologeek] Envie de dĂ©velopper agilement en Python ? Suivez le guide !Envie de dĂ©velopper agilement en Python ? Suivez le guide ! ëë»q‚[AAčQčQhttp://www.biologeek.com/critique,livre,python/envie-de-developper-agilement-en-python-suivez-le-guide/2008-08-31 17:41:09.5055232007-09-05 09:39:27.000000

      J'ai beaucoup de mal Ă  critiquer un livre pour lequel j'ai fait une relecture (c'est la raison pour laquelle je n'avais pas parlĂ© de la seconde Ă©dition du livre Ubuntu) car j'ai gĂ©nĂ©ralement dĂ©jĂ  fait mes remarques Ă  l'auteur avant la parution. En ce qui concerne le Petit guide Ă  l’usage du dĂ`in d'une solution maintenant. Enfin notez bien le une dans le titre qui est trĂšs important, il y a Ă©normĂ©ment d'interprĂ©tations de l'architecture REST, cette implĂ©mentation essaye de s'inspirer de celle dĂ©finie dans le livre RESTful Web Services : l'architecture orientĂ©e ressource (ROA).

      Objectif ressource

      Le but principal de cette solution est de simplifier le dĂ©veloppement de l'accĂšs Ă  vos ressources. Pour cela une classe gĂ©nĂ©rique s'occupe de dispatcher votre requĂȘte dans la bonne mĂ©thode en fonction du verbe HTTP. Dans le cas d'une application authentifiĂ©e, vous pouvez contrĂŽler les accĂšs aux ressources en fonction des permissions de Django. Enfin la notion d'annulation a Ă©tĂ© incluse car j'apprĂ©cie cette approche (cf. en fin de billet).j

      Préparons le terrain

      La premiĂšre chose Ă  faire est d'utiliser le middleware permettant d'effectuer de fausses requĂȘtes HTTP PUT et DELETE Ă  partir d'un navigateur (ce qui n'est pas possible actuellement) :

      _SUPPORTED_TRANSFORMS = ['PUT', 'DELETE']
      _MIDDLEWARE_KEY = '_method'
       
      class HttpMethodsMiddleware(object):
          def process_request(self, request):
              if request.POST and _MIDDLEWARE_KEY in request.POST:
                  if request.POST[_MIDDLEWARE_KEY].upper() in _SUPPORTED_TRANSFORMS:
                      request.method = request.POST[_MIDDLEWARE_KEY].upper()
              return None

      Cela permet de passer de convertir le verbe POST en PUT ou DELETE en fonction de l'argument _method (généralement caché dans un formulaire).

      Les permissions par dĂ©faut de Django n'incluent pas la notion d'affichage, il est donc nĂ©cessaire d'ajouter cette permission Ă  tous vos modĂšles. Comme tout ce qui est long et fastidieux avec Django, il existke une solution Ă©lĂ©gante utilisant les signals pour automatiser tout ça :

      def create_retrieve_permissions(app, created_models, verbosity):
          app_models = get_models(app)
          for klass in app_models:
              ctype = ContentType.objects.get_for_model(klass)
              codename = _get_permission_codename('retrieve', klass._meta)
              name = 'Can %s %s' % ('retrieve', klass._meta.verbose_name)
              p, created = Permission.objects.get_or_create(codename=codename, 
                  content_type__pk=ctype.id,
                  defaults={'name': name, 'content_type': ctype})
              if created and verbosity >= 2:
                  print "Adding permission '%s'" % p
      
      dispatcher.connect(create_retrieve_permissions, signal=signals.post_syncdb)

      La permission est créée à chaque fin de syncdb pour l'ensemble des modÚles existants.

      Passons aux choses sérieuses

      Je ne vais pas trop coller de code ici, vous le retrouverez commenté dans le paquet. Je valis plus expliquer les concepts pour comprendre comment l'utiliser.

      Nous allons implĂ©menter une todo liste basique permettant d'exploiter les diffĂ©rentes fonctionnalitĂ©s dĂ©veloppĂ©es. Nos URI devront avoir le modĂšle suivant (conformĂ©ment au design dĂ©finit par Joe Gregorio) :

      /{model}/{id};{noun}

      Vous savez qu'une URL se construit avec Django de la façon suivante :

      urlpatterns = patterns('',
          (expression réguliÚre, fonction de la vue),
      )

      L'idĂ©e ici est de passer non pas une fonction Ă  votre pattern mais une classe, ou plus prĂ©cisĂ©ment une instance de classe. En instanciant cette classe, vous allez appeler la mĂ©thode __call__ de la classe (ça c'est du python) qui va faire tout le travail de redirection vers la bonne mĂ©thode de la classe en fonction du verbe HTTP de la requĂȘte.

      On va donc avoir une dĂ©finition des URL qui va ressembler Ă  ça :

      umrlpatterns = patterns('',
          (r'^/todos/(?:(?P<id>\d+)/?)?(?:;(?P<noun>\w+))?/?$',
              TodoCollection()),
      )

      Ok, maintenant voyons voir ce qui se cache dans TodoCollection :

      class TodoCollection(GenericCollection):
          def __call__(self, request, **kw):
              return super(TodoCollection, self).__call__(request, 'todo', 'todo', **kw)

      TodoCollection hĂ©rite de GenericCollection qui est la classe de base permettant d'automatiser l'accĂšs aux ressources. Seule la fonction __call__ doit ĂȘtre réécrite pour tenir compte du nom de l'application et du modĂšle (vous pouvez encore plus automatiser en passant ces argument dans l'URL ou dans un dictionnaire mais nous verrons par la suite que cette nouvelle classe peut ĂȘtre utile pour y placer les fonction spĂ©cifiques Ă  nos ressources).

      ArrivĂ© dans GenericCollection, la requĂȘte va ĂȘtre redirigĂ©e vers la fonction appropriĂ©e selon les Ă©quivalences suivantes (notez le caractĂšre facultatif des parnamĂštres id et noun dans l'expression rĂ©guliĂšre) :

      • si c'est un GET sans id, redirection vers la fonction list ;
      • si c'est un POST, redirection vers la fonction create ;
      • si c'est un GET avec id, redirection vers la fonction retrieve ;
      • si c'est un PUT avec id, redirection vers la fonction update ;
      • si c'est un DELETE avec id, redirection vers la fonction delete ;

      Dans le cas oĂč il y a argument noun, la redirection s'effectue vers la fonction verbeHTTP_noun ce qui permet d'ajouter des vues si vous avez des besoins spĂ©cifiques, typiquement pour afficher un formulaire de mise Ă  jour d'une ressource vous devrez pointer vers une URI de ce type :

      /todos/{id};update_form

      qui redirigera vers la fonction get_update_form de votre classe Collectiono.

      Vous avez compris le principe ? Étudions maintenant une fonctionnalitĂ© en particulier (attention la suite est un peu brutale, pour un vrai exemple je vous recommande celui du paquet).

      TrĂȘve de confirmation

      Un récent article sur A List Apart évoquait les avantages d'une annulation possible d'une action par rapport à une confirmation préalable. Il est vrai que les messages de confirmation sont toujours frustrants et sont de toute maniÚre tellement banalisés aujourd'hui qu'ils ne sont plus lus par l'utilisateur.

      Suite à cet article, une discussion intéressante sur son implémentation dans Django chez Simon Willison a aboutit à son implémentation chez Nathan Ostgard m'ont permis d'intégrer cette fonctionnalité à moindre coût.

      Elle impose toutp de mĂȘme d'ajouter un champ, deux fonctions et un manager Ă  votre modĂšle :

      class TrashManager(models.Manager):
          def get_query_set(self):
              return super(TrashManager, self) \
                  .get_query_set().filter(trashed_at__isnull=True)
                  
          def get_trashed(self):
              return super(TrashManager, self) \
                  .get_query_set().filter(trashed_at__isnull=False)
      
      
      class Todo(models.Model):
          [...]
          trashed_at = models.DateTimeField(blank=True, null=True, editable=False)
          objects = TrashManager()
              
          def trash(self):
              self.trashed_at = datetime.now()
              self.save()
      
          def restore(self):
              self.trashed_at = None
              self.save()

      Cela vous permet de placer les ressources « supprimĂ©es » dans une corbeille temporaire permettant leur rĂ©cupĂ©ration aprĂšs suppression malencontreuse (l'effet Ooops!). La base doit ensuite ĂȘtre rĂ©guliĂšrement purgĂ©e ce qui est simplifiĂ© par l'accĂšs aux Ă©lĂ©ments de la corbeilqle avec le manager :

      model.objects.get_trashed()

      Voyons maintenant ce que ça donne avec ma solution. Ce cas est trĂšs particulier et c'est intĂ©ressant car on va accĂ©der aux limites de la solution justement. En effet, la suppression doit normalement ĂȘtre effectuĂ©e via un DELETE mais dans notre cas une mise dans la corbeille signifie une modification de la ressource et donc un PUT. Cruel dilemme !

      Nous allons devoir crĂ©er une nouvelle mĂ©thode Ă  notre classe gĂ©rant ce cas particulier, celle-ci sera accessible via :

      /todos/{id};trash

      qui redirigera vers la fonction (simplifiĂ©e pour l'exemple) :

          def put_trash(self):
              self.item_instance.trash()
              message = _("Item trashed successfully. \
                  <a href=\"%s;recover?_method=put\" title=\"\">Restore?</a> \
                  " % self.id)
              self.request.user.message_set.create(message=message)

      Cette fonction est bien accessible rvia un PUT ce qui reste correct (si un client Ă  ce service web est implĂ©mentĂ©, il utilisera directement DELETE sans avoir besoin de confirmation). Un lien est ensuite proposĂ© Ă  l'utilisateur pour annuler cette « suppression » qui lui est beaucoup moins RESTful...

      En effet, pour simplifier la rĂ©cupĂ©ration j'ai prĂ©fĂ©rĂ© placer un lien (ce qui n'est pas forcĂ©ment conforme aux rĂšgles d'ergonomie qui stipulent qu'une donnĂ©e ne doit ĂȘtre modifiĂ©e qu'Ă  travers un formulaire, d'oĂč l'aspect si hideux reconnaissable des boutons de formulaires). Du coup je suis obligĂ© de passer la mĂ©thode en argument pour faire un faux PUT, histoire d'ĂȘtre tout de mĂȘme cohĂ©rent au niveau de ma classe :

          def put_recover(self):
              self.model.objects.get_trashed().get(pk=self.id).restore()
              message = _("Item recovered successfully.")
              self.request.user.message_set.create(message=message)
              return HttpResponseRedirect('.')

      Ouf, on y esst tout de mĂȘme arrivĂ© (il faut modifier le middleware du dĂ©but pour qu'il utilise request.REQUEST et non request.POST si vous souhaitez faire du faux PUT avec du GET).

      Conclusion et évolutions

      La solution permettant de gĂ©rer des collections gĂ©nĂ©riques est satisfaisante (mĂȘme s'il manque encore quelques fonctionnalitĂ©s) et constitue un bon exemple de ce qui peut ĂȘtre fait Ă  la fois avec Django et avec REST et c'est plus dans cette optique que je la publie.

      Il est parfois difficile de s'en tenir Ă  une architecture RESTful dans les cas extrĂȘmes et certains impĂ©ratifs peuvent nĂ©cessiter quelques entorses aux rĂšgles que vous vous ĂȘtes fixĂ©. Le plus important est d'en ĂȘtre conscient et d'assumer ses choix en connaissance de cause. Dans mon exemple sur l'annulation je sais trĂšs bien que c'est une fonctionnalitĂ© qui ne sera pas utilisĂ©e par un programme tiers.

      Enfin deux mots sur ce qu'il resterait Ă  implĂ©menter (je reste dans le condittionnel car je pense que le GSoC permettra prochainement de faire la mĂȘme chose en mieux, du moins je l'espĂšre et je participe en ce sens) :

      • GĂ©rer diffĂ©rents formats de reprĂ©sentation des ressources (json, xml, etc).
      • GĂ©rer les diffĂ©rentes erreurs possibles avec les codes appropriĂ©s (403, etc).
      • Rendre possible l'utilisation d'une classe avec url_reverse, notamment pour utiliser le tag {% url %} dans les templates.

      En attendant, vous pouvez toujours tĂ©lĂ©charger la version actuelle et jouer avec ! (n'oubliez pas d'ajouter le dossier Ă  votre $PYTHONPATH...)

      Logo biologeek Une solution pour faciliter la conception d'applications web RESTful avec Django a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 07 AoĂ»t 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      Voila la solution Ă  laquelle je suis arrivĂ© aprĂšs avoir testĂ© les solutions existantes : django collection, django crudapi et django restful model views. J'attends beaucoup du GSoC consacrĂ© Ă  l'inclusion native de REST dans Django et les choses vont dans le bon sens de ce cĂŽtĂ© lĂ  mais j'avais besoin d'une solution maintenant. Enfin notez bien le une dans le titre qui est trĂšs important, il y a Ă©normĂ©ment d'interprĂ©tations de l'architecture REST, cette implĂ©mentation essaye de s'inspirer de celle dĂ©finie dans le livre RESTful Web Services : l'architecture orientĂ©e ressource (ROA).

      Objectif ressource

      Le but principal de cette solution est de simplifier le dĂ©veloppement de l'accĂšs Ă  vos ressources. Pour cela une classe gĂ©nĂ©rique s'occupe de dispatcher votre requĂȘte dans la bonne mĂ©thode en fonction du verbe HTTP. Dans le cas d'unwe application authentifiĂ©e, vous pouvez contrĂŽler les accĂšs aux ressources en fonction des permissions de Django. Enfin la notion d'annulation a Ă©tĂ© incluse car j'apprĂ©cie cette approche (cf. en fin de billet).

      Préparons le terrain

      La premiĂšre chose Ă  faire est d'utiliser le middleware permettant d'effectuer de fausses requĂȘtes HTTP PUT et DELETE Ă  partir d'un navigateur (ce qui n'est pas possible actuellement) :

      _SUPPORTED_TRANSFORMS = ['PUT', 'DELETE']
      _MIDDLEWARE_KEY = '_method'
       
      class HttpMethodsMiddleware(object):
          def process_request(self, request):
              if request.POST and _MIDDLEWARE_KEY in request.POST:
                  if request.POST[_MIDDLEWARE_KEY].upper() in _SUPPORTED_TRANSFORMS:
                      request.method = request.POST[_MIDDLEWARE_KEY].upper()
              return None

      Cela permet de passer de convertir le verbe POST en PUT ou DELETE en fonction de l'argument _method (généralement caché dans un formulaire).

      x

      Les permissions par dĂ©faut de Django n'incluent pas la notion d'affichage, il est donc nĂ©cessaire d'ajouter cette permission Ă  tous vos modĂšles. Comme tout ce qui est long et fastidieux avec Django, il existe une solution Ă©lĂ©gante utilisant les signals pour automatiser tout ça :

      def create_retrieve_permissions(app, created_models, verbosity):
          app_models = get_models(app)
          for klass in app_models:
              ctype = ContentType.objects.get_for_model(klass)
              codename = _get_permission_codename('retrieve', klass._meta)
              name = 'Can %s %s' % ('retrieve', klass._meta.verbose_name)
              p, created = Permission.objects.get_or_create(codename=codename, 
                  content_type__pk=ctype.id,
                  defaults={'name': name, 'content_type': ctype})
              if created and verbosity >= 2:
                  print "Adding permission '%s'" % p
      
      dispatcher.connect(create_retrieve_permissions, signal=signals.post_syncdb)

      La permission est créée à chyaque fin de syncdb pour l'ensemble des modÚles existants.

      Passons aux choses sérieuses

      Je ne vais pas trop coller de code ici, vous le retrouverez commenté dans le paquet. Je vais plus expliquer les concepts pour comprendre comment l'utiliser.

      Nous allons implĂ©menter une todo liste basique permettant d'exploiter les diffĂ©rentes fonctionnalitĂ©s dĂ©veloppĂ©es. Nos URI devront avoir le modĂšle suivant (conformĂ©ment au design dĂ©finit par Joe Gregorio) :

      /{model}/{id};{noun}

      Vous savez qu'une URL se construit avec Django de la façon suivante :

      urlpatterns = patterns('',
          (expression réguliÚre, fonction de la vue),
      )

      L'idĂ©e ici est de passer non pas une fonction Ă  votre pattern mais une classe, ou plus prĂ©cisĂ©ment une instance de classe. En instanciant cette classe, vous allez appeler la mĂ©thode __call__ de la classe (ça c'est du python)z qui va faire tout le travail de redirection vers la bonne mĂ©thode de la classe en fonction du verbe HTTP de la requĂȘte.

      On va donc avoir une dĂ©finition des URL qui va ressembler Ă  ça :

      urlpatterns = patterns('',
          (r'^/todos/(?:(?P<id>\d+)/?)?(?:;(?P<noun>\w+))?/?$',
              TodoCollection()),
      )

      Ok, maintenant voyons voir ce qui se cache dans TodoCollection :

      class TodoCollection(GenericCollection):
          def __call__(self, request, **kw):
              return super(TodoCollection, self).__call__(request, 'todo', 'todo', **kw)

      TodoCollection hĂ©rite de GenericCollection qui est la classe de base permettant d'automatiser l'accĂšs aux ressources. Seule la fonction __call__ doit ĂȘtre réécrite pour tenir compte du nom de l'application et du modĂšle (vous pouvez encore plus automatiser en passant ces argument dans l'URL ou dans un dictionnaire mais nous verrons par la suite que cette nouvelle classe peut ĂȘtre utile pour y placer les {fonction spĂ©cifiques Ă  nos ressources).

      ArrivĂ© dans GenericCollection, la requĂȘte va ĂȘtre redirigĂ©e vers la fonction appropriĂ©e selon les Ă©quivalences suivantes (notez le caractĂšre facultatif des paramĂštres id et noun dans l'expression rĂ©guliĂšre) :

      • si c'est un GET sans id, redirection vers la fonction list ;
      • si c'est un POST, redirection vers la fonction create ;
      • si c'est un GET avec id, redirection vers la fonction retrieve ;
      • si c'est un PUT avec id, redirection vers la fonction update ;
      • si c'est un DELETE avec id, redirection vers la fonction delete ;

      Dans le cas oĂč il y a argument noun, la redirection s'effectue vers la fonction verbeHTTP_noun ce qui permet d'ajouter des vues si vous avez des besoins spĂ©cifiques, typiquement pour afficher un formulaire| de mise Ă  jour d'une ressource vous devrez pointer vers une URI de ce type :

      /todos/{id};update_form

      qui redirigera vers la fonction get_update_form de votre classe Collection.

      Vous avez compris le principe ? Étudions maintenant une fonctionnalitĂ© en particulier (attention la suite est un peu brutale, pour un vrai exemple je vous recommande celui du paquet).

      TrĂȘve de confirmation

      Un récent article sur A List Apart évoquait les avantages d'une annulation possible d'une action par rapport à une confirmation préalable. Il est vrai que les messages de confirmation sont toujours frustrants et sont de toute maniÚre tellement banalisés aujourd'hui qu'ils ne sont plus lus par l'utilisateur.

      Suite à cet article, une discussion intéressante sur son implémentation dans Django chez Simon Willison a ab}outit à son implémentation chez Nathan Ostgard m'ont permis d'intégrer cette fonctionnalité à moindre coût.

      Elle impose tout de mĂȘme d'ajouter un champ, deux fonctions et un manager Ă  votre modĂšle :

      class TrashManager(models.Manager):
          def get_query_set(self):
              return super(TrashManager, self) \
                  .get_query_set().filter(trashed_at__isnull=True)
                  
          def get_trashed(self):
              return super(TrashManager, self) \
                  .get_query_set().filter(trashed_at__isnull=False)
      
      
      class Todo(models.Model):
          [...]
          trashed_at = models.DateTimeField(blank=True, null=True, editable=False)
          objects = TrashManager()
              
          def trash(self):
              self.trashed_at = datetime.now()
              self.save()
      
          def restore(self):
              self.trashed_at = None
              self.save()

      Cela vous permet de placer les ressources « supprimĂ©es » dans une c~orbeille temporaire permettant leur rĂ©cupĂ©ration aprĂšs suppression malencontreuse (l'effet Ooops!). La base doit ensuite ĂȘtre rĂ©guliĂšrement purgĂ©e ce qui est simplifiĂ© par l'accĂšs aux Ă©lĂ©ments de la corbeille avec le manager :

      model.objects.get_trashed()

      Voyons maintenant ce que ça donne avec ma solution. Ce cas est trĂšs particulier et c'est intĂ©ressant car on va accĂ©der aux limites de la solution justement. En effet, la suppression doit normalement ĂȘtre effectuĂ©e via un DELETE mais dans notre cas une mise dans la corbeille signifie une modification de la ressource et donc un PUT. Cruel dilemme !

      Nous allons devoir crĂ©er une nouvelle mĂ©thode Ă  notre classe gĂ©rant ce cas particulier, celle-ci sera accessible via :

      /todos/{id};trash

      qui redirigera vers la fonction (simplifiĂ©e pour l'exemple) :

          def put_trash(self):
              self.item_instance.trash()
              message = _("Item trashed successfully. \
                  <a href=\"%s;recover?_method=put\" title=\"\">Restore?</a> \
                  " % self.id)
              self.request.user.message_set.create(message=message)

      Cette fonction est bien accessible via un PUT ce qui reste correct (si un client Ă  ce service web est implĂ©mentĂ©, il utilisera directement DELETE sans avoir besoin de confirmation). Un lien est ensuite proposĂ© Ă  l'utilisateur pour annuler cette « suppression » qui lui est beaucoup moins RESTful...

      En effet, pour simplifier la rĂ©cupĂ©ration j'ai prĂ©fĂ©rĂ© placer un lien (ce qui n'est pas forcĂ©ment conforme aux rĂšgles d'ergonomie qui stipulent qu'une donnĂ©e ne doit ĂȘtre modifiĂ©e qu'Ă  travers un formulaire, d'oĂč l'aspect si hideux reconnaissable des boutons de formulaires). Du coup je suis obligĂ© de passer la mĂ©thode en argument pour faire un faux PUT, histoire d'ĂȘtre tout de mĂȘme cohĂ©rent au niveau de ma classe :

          def put_recover(self):
              self.model.objects.g€et_trashed().get(pk=self.id).restore()
              message = _("Item recovered successfully.")
              self.request.user.message_set.create(message=message)
              return HttpResponseRedirect('.')

      Ouf, on y est tout de mĂȘme arrivĂ© (il faut modifier le middleware du dĂ©but pour qu'il utilise request.REQUEST et non request.POST si vous souhaitez faire du faux PUT avec du GET).

      Conclusion et évolutions

      La solution permettant de gĂ©rer des collections gĂ©nĂ©riques est satisfaisante (mĂȘme s'il manque encore quelques fonctionnalitĂ©s) et constitue un bon exemple de ce qui peut ĂȘtre fait Ă  la fois avec Django et avec REST et c'est plus dans cette optique que je la publie.

      Il est parfois difficile de s'en tenir Ă  une architecture RESTful dans les cas extrĂȘmes et certains impĂ©ratifs peuvent nĂ©cessiter quelques entorses aux rĂšgles que vous vous ĂȘtes fixĂ©. Le plus important est d'en ĂȘtre conscient et d'assumer ses choix en connaissance de cause. Dans mon exemple sur l'annulation je sais trĂšs bien que c'est une fonctionnalitĂ© qui ne sera pas utilisĂ©e par un programme tiers.

      Enfin deux mots sur ce qu'il resterait Ă  implĂ©menter (je reste dans le conditionnel car je pense que le GSoC permettra prochainement de faire la mĂȘme chose en mieux, du moins je l'espĂšre et je participe en ce sens) :

      • GĂ©rer diffĂ©rents formats de reprĂ©sentation des ressources (json, xml, etc).
      • GĂ©rer les diffĂ©rentes erreurs possibles avec les codes appropriĂ©s (403, etc).
      • Rendre possible l'utilisation d'une classe avec url_reverse, notamment pour utiliser le tag {% url %} dans les templates.

      En attendant, vous pouvez toujours tĂ©lĂ©charger la version actuelle et jouer avec ! (n'oubliez pas d'ajouter le dossier Ă  votre $PYTHONPATH...)

      Logo biologeek Une solution pour faciliter la conception d'applications web RESTful avec Django a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 07 AoĂ»t 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      [Biologeek] Une solution pour faciliter la conception d'applications web RESTful avec DjangoUne solution pour faciliter la conception d'applications web RESTful avec Django ÉɁŐF‚‚%AAÒWÒWE-http://www.biologeek.com/django,python,rest,web-frameworks/une-solution-pour-faciliter-la-conception-d-applications-web-restful-avec-django/2008-08-31 17:41:09.5459882007-08-06 23:03:11.000000

      Voila la solution Ă  laquelle je suis arrivĂ© aprĂšs avoir testĂ© les solutions existantes : django collection, django crudapi et django restful model views. J'attends beaucoup du GSoC consacrĂ© Ă  l'inclusion native de REST dans Django et les choses vont dans le bon sens de ce cĂŽtĂ© lĂ  mais j'avais besoih„ les 2 et 3 juin prochains Ă  la CitĂ© des Sciences de la Villette. J'y ferais une prĂ©sentation intitulĂ©e « Tout savoir sur Django » le dimanche aprĂšs-midi qui pourra ĂȘtre utile Ă  tous ceux qui n'ont pas encore eu l'occasion de faire le grand saut ou qui sont tout simplement curieux.

      Pour ĂȘtre plus prĂ©cis, voici le contenu de la prĂ©sentation :

      De la dĂ©couverte Ă  l'explication des concepts avancĂ©s, vous serez Ă  mĂȘme de vous faire votre propre opinion sur Django grĂące Ă  des exemples d'applications simples.

      Depuis 2005, la popularité de Django n'a cessé de croßtre jusqu'à devenir aujourd'hui une solution incontournable dans le développement web python. Ses points forts sont assurément la rapidité de développement et la courbe d'apprentissage ne laissant pas le temps au débutant de se décourager.

      Cette prĂ©sentation fera le point sur ce qu'est Djan…go et sur ses grands principes de fonctionnement avant de dĂ©crire plus en dĂ©tail les concepts avancĂ©s permettant de progresser et de dĂ©velopper agilement des applications web robustes et flexibles.

      Je mettrais le support de présentation en ligne aprÚs mon intervention, probablement avec des commentaires additionnels pour mieux comprendre de quoi il retourne.

      J'espĂšre vous y rencontrer nombreux ! (enfin pas trop non plus je suis un grand timide ;-))

      Logo biologeek PrĂ©sentation de Django aux journĂ©es Python francophones a Ă©tĂ© rĂ©digĂ© par David Larlet pour bio†logeek.com et a Ă©tĂ© originellement postĂ© le 19 Mai 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      Un petit billet pour signaler que les prochaines journĂ©es Python francophones se tiendront les 2 et 3 juin prochains Ă  la CitĂ© des Sciences de la Villette. J'y ferais une prĂ©sentation intitulĂ©e « Tout savoir sur Django » le dimanche aprĂšs-midi qui pourra ĂȘtre utile Ă  tous ceux qui n'ont pas encore eu l'occasion de faire le grand saut ou qui sont tout simplement curieux.

      Pour ĂȘtre plus prĂ©cis, voici le contenu de la prĂ©sentation :

      De la dĂ©couverte Ă  l'explication des‡ concepts avancĂ©s, vous serez Ă  mĂȘme de vous faire votre propre opinion sur Django grĂące Ă  des exemples d'applications simples.

      Depuis 2005, la popularité de Django n'a cessé de croßtre jusqu'à devenir aujourd'hui une solution incontournable dans le développement web python. Ses points forts sont assurément la rapidité de développement et la courbe d'apprentissage ne laissant pas le temps au débutant de se décourager.

      Cette présentation fera le point sur ce qu'est Django et sur ses grands principes de fonctionnement avant de décrire plus en détail les concepts avancés permettant de progresser et de développer agilement des applications web robustes et flexibles.

      Je mettrais le support de présentation en ligne aprÚs mon intervention, probablement avec des commentaires additionnels pour mieux comprendre de quoi il retourne.

      J'espĂšre vous y rencontrer nombreux ! (enfin pas trop non plus je suis un grand timide ;-))

      Logo biologeek PrĂ©sentation de Django aux journĂ©es Python francophones a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 19 Mai 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      [Biologeek] PrĂ©sentation de Django aux journĂ©es Python francophonesPrĂ©sentation de Django aux journĂ©es Python francophones )Æ)Œ8‚mAAčč+http://www.biologeek.com/python,web-frameworks/developpement-web-python-et-frameworks-tour-d-horizon-debut-2007/2008-08-31 17:41:09.6500002007-03-30 19:23:28.000000

      Un article intitulĂ© « Python web development and frameworks in 2007 » trĂšs intĂ©ressant que j'aurais aimĂ© traduire fait le bilan sur le dĂ©veloppement web python et ses principaux frameworks, de web.py Ă  Zope, en passant par Django, Pylons et journĂ©es Python francophones se tiendrontƒH“]“˜ą§Ź±¶»ÀĆÊÏÔÙȚăèíòśü $).38=BGLQV[`ejoty~ƒˆ’—œĄŠ«°”șżÄÉÎÓŰĘâèîôú        !#!$"&#($*',(-).*0,1-2.3/40617283:4;5=7?8B9C:D;FL@OARBUCXE[F]G`HcJfKiLkMnOqPtQvRyT|UVWYZ [of7Œ’˜ž€Ș°¶ŒÂÈÎÔÚàæìòűț "(.4:@FLRX^djpv|‚ˆŽ”š ŠŹČžŸÄÊĐÖÜâèîôú†€ztnhb\VPJD>82,& üöđêäȚŰÒÌÆÀșŽźšąœ–Š„~xrlf1‚a*‚`(‚_&‚^%‚\‚[‚Y‚W‚Vú‚Uű‚Rś‚Pö‚Oô‚Mò‚Kđ‚Jí‚Iæ‚Gă‚Eá‚DۂCŚ‚BւAՂ@ӂ?҂>т=Ђ<ς;͂:ʂ8œ‚7«‚6Š‚4˜‚3Š‚1t‚/l‚-V‚,L‚+F‚*2‚) ‚'‚&ś‚%Ƃ$Ž‚!«‚ ˆ‚^_`acde g#h&j)k,l/n2o5p8q;s>tAuDwGxJyMzO|Q}S~VY[‚^ƒa„d†g‡jˆmЁp‹rŒsvށxy‘{’~“‚”‚•‚–‚—‚ ™‚ š‚ ›‚œ‚‚ž‚Ÿ‚Ą‚Ł‚€‚„‚ʂ_‚g‚‚‚ @‹Ą9Űi š@e‚&Ihttp://www.biologeek.com/bonnes-pratiques,python/un-template-python-pour-parser-des-arguments/&^‚%;http://www.biologeek.com/bonnes-pratiques,python/principales-nouveautes-dans-python-25/%]‚$9http://www.biologeek.com/critique,livre,python/critique-du-livre-programmation-python/$l‚#Whttp://www.biologeek.com/python,web/les-100-premiers-mots-cles-recherches-par-les-utilisateurs-d-aol/#^‚";http://www.biologeek.com/python,web/analyse-des-donnees-utilisateur-d-aol-suite-et-fin/"e‚!Ihttp://www.biologeek.com/bonnes-pratiques,python/benchmarks-map-filter-vs-list-comprehensions/!m‚ Yhttp://www.biologeek.com/django,python,web-frameworks/modelisation-d-un-workflow-lineaire-avec-django/ w‚mhttp://www.biologeek.com/python,web-frameworks/developpement-web-python-et-frameworks-tour-d-horizon-debut-2007/r‚chttp://www.biologeek.com/conferences,django,python/presentation-de-django-aux-journees-python-francophones/urbogears.org/">TurboGears. J'ai appris de nombreuses choses donc je vous invite Ă  aller le lire sur place mais c'est vrai que c'est assez long donc en voici un rĂ©sumĂ© accompagnĂ© de mes commentaires.

      Rappel prĂ©liminaire : alors que David H. (principal dĂ©veloppeur de Ruby on Rails) se moque gentiment du nombre de frameworks python assez paradoxal compte tenu de la maxime de Python : There Is Only One Way To Do It (en opposition Ă  Perl), l'auteur de l'article rappelle que la diversitĂ© appelle l'Ă©mulation (et le choix pour les utilisateurs) et que la situation actuelle donne raison Ă  Python compte-tenu du manque de rĂ©activitĂ© dans le dĂ©veloppement de Ruby on Rails. Je ne sais pas oĂč en est le dĂ©veloppement actuel de RoR donc je ne peux pas commenter cette affirmation mĂȘme si je soupçonne un certain parti pris... quelqu'un pour confirmer/infirmer ?

      Pour commencer, l'auteur fait le point sur les deux solutions que l'on peut considĂ©rer comme Ă©tant aux antipodes du dĂ©veloppement web python : Zope et web.py. Zope a longtemps Ă©tĂ© la seule solution pour faire du web sĂ©rieusement en Python et souffre (malheureusement ?) de l'image d'usine Ă  gaz qui la poursuit depuis l'arrivĂ©e des « nouveaux » frameworks web. Ce n'est pourtant pas une solution Ă  rejeter pour certaines tĂąches car de nombreux composants sont disponibles et malgrĂ© une courbe d'apprentissage assez raide, la tendance actuelle est Ă  sa simplification.

      À l'opposĂ©, web.py est quasiment l'anti-framework. Ironiquement, c'est le premier framework que j'ai dĂ©couvert (probablement grĂące Ă  Simon) et qui m'a fait entrevoir l'Ă©tendue des possibilitĂ©s offertes par Python dans le dĂ©veloppement web. À l'origine, un seul fichier Ă©tait nĂ©cessaire pour faire tourner une application, aujourd'hui ce framework a Ă©voluĂ© mais il est toujours aussi simpliste/minimaliste. Il est donc Ă  mon avis dĂ©conseillĂ© pour les dĂ©veloppements consĂ©quents qui seront plus rapidement rĂ©alisĂ©s via des frameworks permettant d'avoir des raccourcis Ă  tous les niveaux. En revanche, pour comprendre comment fonctionne un framework web dans ses moindres rouages, il y a difficilement mieux (lire auparavant l'excellent article de Joe Gregorio peu aider).

      Django : le tout en un fonctionnel

      Je ne sais pas s'il est nécessaire de vous rappeler l'idéologie sous-jacente car j'en ai déjà parlé ici mais en gros il s'agit d'avoir un ensemble de composants cohérents entre eux, autant dans leur fonctionnalités que dans leur documentation. Tout a donc été écrit from scratch (argument supplémentaire, au début des développements les bibliothÚques actuelles n'existaient pas) pour arriver à la récente version 0.96 actuelle.

      Le gros avantage de Django c'est sa communauté importante (ici l'annonce de Guido y est aussi pour quelque chose à mon avis) et sa documentation (c'est quasiment un des buts initial donc ça semble normal).

      Les inconvĂ©nients soulevĂ©s ne sont pas forcĂ©ment tous valables Ă  mon avis mais pour ceux qui sont indiscutables, concernent l'impossibilitĂ© rĂ©elle d'utiliser d'autres briques Python que celles dĂ©finies par dĂ©faut. L'exemple donnĂ© est celui de SQLAlchemy et les arguments donnĂ©s sont bons : la branche ouverte pour gĂ©rer ce cas vĂ©gĂšte (comme beaucoup d'autres d'ailleurs).

      Les vues gĂ©nĂ©riques et l'administration auto-gĂ©nĂ©rĂ©e finissent toujours par dĂ©cevoir, ce qui est logique Ă©tant donnĂ© la maniĂšre dont c'est mis en avant dans la documentation (heureusement que la situation est clarif‘iĂ©e dans le livre).

      Il manque un dĂ©pĂŽt centralisĂ© d'applications. Django snippets est un excellent dĂ©but en ce sens mais il faudrait pouvoir dĂ©poser des applications complĂštes aussi. Pour l'instant ces ressources sont Ă©parpillĂ©es un peu partout... edit du lendemain : c'est en cours de rĂ©flexion.

      Le manque de réactivité de la part de l'équipe de développement est soulevé et je suis assez d'accord sur ce point (plusieurs de mes mails sont restés lettres mortes sur la liste de diffusion). La situation est en cours d'évolution avec l'élargissement de l'équipe et c'est une bonne chose.

      En conclusion, Django est tout de mĂȘme un excellent framework qui a le mĂ©rite d'ĂȘtre fonctionnel maintenant et dont les rĂ©centes amĂ©liorations (newforms) sont prometteuses. Je ne m'Ă©tends pas plus sur django mais de nombreux points sont Ă©voquĂ©s, preuve que l'auteur sait trĂšs bien de quoi il parle, autant pour les avantages que pour les inconvĂ©nients.

      Pylons : le framework Ă  la carte

      La philosophie de Pylons est à l'opposé de celle de Django, il s'agit de laisser le choix à l'utilisateur à chacun des niveaux pour l'utilisation de la bibliothÚque existante qui lui convient. Par défaut, le framework ressemble beaucoup à Ruby on Rails et si vous souhaitez essayer Python en connaissant RoR, c'est le framework qu'il vous faut.

      Le gros avantage de Pylons rĂ©side donc dans sa capacitĂ© d'adaptation, un peu Ă  la sauce UNIX : laisser le choix Ă  l'utilisateur en proposant des utilitaires simples que l'on peut enchaĂźner via des pipes. Par ailleurs, il est Ă  noter que le principal dĂ©veloppeur est apparemment accessible ce qui “est toujours intĂ©ressant.

      Le problĂšme de pouvoir utiliser autant de briques est le manque de consistance de la documentation. Et mĂȘme le meilleur des frameworks est inutilisable si l'on ne sait pas s'en servir (bon ok, j'exagĂšre un peu ;-)).

      Les composants fournis par défaut sont en train de changer pour fournir une meilleure base de développement. En particulier Toscawidgets, développé par l'équipe de TurboGears, mais aussi Mako pour les templates.

      Quoi qu'il en soit, Pylons est conceptuellement vraiment intéressant et sera probablement à moyen terme une solution des plus alléchantes, surtout si la réutilisation d'applications venant d'autres frameworks devient possible. Aller vers une inter-opérabilité en ce sens serait une petite révolution.

      TurboGears : un framework pour les unir tous et...

      La ”philosophie de ce framework est de prendre les meilleurs composants Python existants et de mettre la glu permettant de les lier pour arriver au framework optimal. L'idĂ©e est trĂšs bonne mais je ne suivais plus depuis quelques temps le dĂ©veloppement de ce framework (on peut difficilement tout suivre, heureusement qu'il y a de tels articles rĂ©capitulatifs !). J'ai Ă©tĂ© vraiment trĂšs surpris d'apprendre la tournure prise par son dĂ©veloppement.

      Le concept est trĂšs bon mais et c'est lĂ  oĂč TurboGears a Ă©chouĂ©, il ne faut pas se tromper lorsque l'on choisit les composants initiaux, au risque de devoir tout recommencer. Et c'est ce qui arrive apparemment Ă  ce framework, ce qui me cause un peu de soucis pour le projet actuel de Guillaume par exemple...

      D'aprĂšs ce que j'ai pu comprendre, la version actuelle (1.0) est gelĂ©e en attendant le dĂ©veloppement de la v2 qui devrait voir• quasiment l'ensemble des composants changĂ©s (soit de version, soit d'orientation). C'est un choix qui est difficile Ă  prendre et qui annonce un long hiver pour TurboGears, ce qui se reflĂšte dans le dĂ©sintĂ©ressement de la part de sa communautĂ© apparemment. Je rejoins l'avis de l'auteur dans l'idĂ©e d'un rapprochement avec Pylons qui laisserait le choix de changer aisĂ©ment Ă  l'utilisateur et qui se baserait sur certaines des bibliothĂšques dĂ©veloppĂ©es spĂ©cifiquement pour TurboGears comme Toscawidgets.

      En tout cas j'en reviens pas d'un tel revirement de situation, j'espĂšre que le projet pourra tout de mĂȘme se relever car c'Ă©tait vraiment bien parti et ça avait dopĂ©, entre autres, le buzz autour des frameworks web Python au dĂ©but de l'annĂ©e derniĂšre. Il Ă©tait alors aussi populaire que Django !

      Conclusion

      Django et Pylons sont de–ux solutions ayant fait des choix diffĂ©rents dans l'implĂ©mentation de leur framework mais qui sont toutes deux actuellement fonctionnelles. Le choix entre les deux se fera Ă  mon avis en fonction de votre expĂ©rience et de votre propre avis sur leur philosophie.

      Comme je le disais prĂ©cĂ©demment, le dĂ©veloppeur est aujourd'hui confrontĂ© au difficile dilemme d'utiliser un framework adaptĂ© Ă  ses besoins sans pouvoir connaĂźtre tous les frameworks existant en dĂ©tail car ils sont trop nombreux et Ă©voluent trop rapidement. Ne serait-ce que pour ĂȘtre compĂ©tent sur Django, Pylons et Ruby on Rails par exemple, c'est mission quasi-impossible... et je ne parle mĂȘme pas des frameworks PHP !

      Quelle solution alors ? Il ne reste plus que les drogues dures je crois Apprenez ce qui vous plaĂźt. Vous travaillez pour un client, ok. Mais vous travaillez dans le dĂ©veloppement web aussi pour le « fun » que ça procure de coder, n'oubliez jamais— ça. Prenez du plaisir dans votre travail et arrĂȘtez de vous prendre la tĂȘte sur le choix du framework, si vous travaillez deux fois plus rapidement car ce que vous faites vous plaĂźt, le client sera toujours content. Et vous aussi :-).

      Logo biologeek DĂ©veloppement web python et frameworks, tour d'horizon dĂ©but 2007 a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 30 Mars 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      Un article intitulĂ© « Python web development and frameworks in 2007 » trĂšs intĂ©ressant que j'aurais aimĂ© traduire fait le bilan sur le dĂ©veloppement web python et ses principaux frameworks, de web.py Ă  Zope, en passant par Django, Pylons et TurboGears. J'ai appris de nombreuses choses donc je vous invite Ă  aller le lire sur place mais c'est vrai que c'est assez long donc en voici un rĂ©sumĂ© accompagnĂ© de mes commentaires.

      Rappel prĂ©liminaire : alors que David H. (principal dĂ©veloppeur de Ruby on Rails) se moque gentiment du nombre de frameworks python assez paradoxal compte tenu de la maxime de Python : There Is Only One Way To Do It (en opposition Ă  Perl), l'auteur de l'article rappelle que la diversitĂ© appelle l'Ă©mulation (et le choix pour les utilisateurs) et que la situation actuelle donne raison Ă  Python compte-tenu du manque de rĂ©activitĂ© dans le dĂ©veloppement de Ruby on Rails. Je ne sais pas oĂč en est le dĂ©veloppement actuel de RoR donc je ne peux pas commenter cette affirmation mĂȘme si je soupçonne un certain parti pris... quelqu'un pour confirmer/infirmer ?

      Pour commencer, l'auteur fait le point sur les deux solutions que l'on peut considĂ©rer comme Ă©tant aux antipodes du dĂ©veloppement web python : Zope et web.py. Zope a longtemps Ă©tĂ© la seule solution pour faire du web sĂ©rieusement en Python et souffre (malheureusement ?) de l'image d'usine Ă  gaz qui la poursuit dšepuis l'arrivĂ©e des « nouveaux » frameworks web. Ce n'est pourtant pas une solution Ă  rejeter pour certaines tĂąches car de nombreux composants sont disponibles et malgrĂ© une courbe d'apprentissage assez raide, la tendance actuelle est Ă  sa simplification.

      À l'opposĂ©, web.py est quasiment l'anti-framework. Ironiquement, c'est le premier framework que j'ai dĂ©couvert (probablement grĂące Ă  Simon) et qui m'a fait entrevoir l'Ă©tendue des possibilitĂ©s offertes par Python dans le dĂ©veloppement web. À l'origine, un seul fichier Ă©tait nĂ©cessaire pour faire tourner une application, aujourd'hui ce framework a Ă©voluĂ© mais il est toujours aussi simpliste/minimaliste. Il est donc Ă  mon avis dĂ©conseillĂ© pour les dĂ©veloppements consĂ©quents qui seront plus rapidement rĂ©alisĂ©s via des frameworks permettant d'avoir des raccourcis Ă  tous les niveaux. En revanche, pour comprendre comment fonctionne un framework web dans ses moi›ndres rouages, il y a difficilement mieux (lire auparavant l'excellent article de Joe Gregorio peu aider).

      Django : le tout en un fonctionnel

      Je ne sais pas s'il est nécessaire de vous rappeler l'idéologie sous-jacente car j'en ai déjà parlé ici mais en gros il s'agit d'avoir un ensemble de composants cohérents entre eux, autant dans leur fonctionnalités que dans leur documentation. Tout a donc été écrit from scratch (argument supplémentaire, au début des développements les bibliothÚques actuelles n'existaient pas) pour arriver à la récente version 0.96 actuelle.

      Le gros avantage de Django c'est sa communauté importante (ici l'annonce de Guido y est aussi pour quelque chose à mon avis) et sa documentation (c'est quasiment un des buts initial donc ça semble normal).

      Les inconvĂ©nients soulevĂ©s ne sont pas forcĂ©ment tous valables Ă  mon avis mais pour ceux qui sont indiscutables, concernent l'impossibilitĂ© rĂ©elle d'utiliser d'autres briques Python que celles dĂ©finies par dĂ©faut. L'exemple donnĂ© est celui de SQLAlchemy et les arguments donnĂ©s sont bons : la branche ouverte pour gĂ©rer ce cas vĂ©gĂšte (comme beaucoup d'autres d'ailleurs).

      Les vues génériques et l'administration auto-générée finissent toujours par décevoir, ce qui est logique étant donné la maniÚre dont c'est mis en avant dans la documentation (heureusement que la situation est clarifiée dans le livre).

      Il manque un dĂ©pĂŽt centralisĂ© d'applications. Django snippets est un excellent dĂ©but en ce sens mais il faudrait pouvoir dĂ©poser des applications complĂštes aussi. Pour l'instant ces ressources sont Ă©parpillĂ©es un peu partout... edit du lendemain : c'est en cours de rĂ©flexion.

      Le manque de réactivité de la part de l'équipe de développement est soulevé et je suis assez d'accord sur ce point (plusieurs de mes mails sont restés lettres mortes sur la liste de diffusion). La situation est en cours d'évolution avec l'élargissement de l'équipe et c'est une bonne chose.

      En conclusion, Django est tout de mĂȘme un excellent framework qui a le mĂ©rite d'ĂȘtre fonctionnel maintenant et dont les rĂ©centes amĂ©liorations (newforms) sont prometteuses. Je ne m'Ă©tends pas plus sur django mais de nombreux points sont Ă©voquĂ©s, preuve que l'auteur sait trĂšs bien de quoi il parle, autant pour les avantages que pour les inconvĂ©nients.

      Pylons : le framework Ă  la carte

      La philosophie de Pylons est Ă  l'ožpposĂ© de celle de Django, il s'agit de laisser le choix Ă  l'utilisateur Ă  chacun des niveaux pour l'utilisation de la bibliothĂšque existante qui lui convient. Par dĂ©faut, le framework ressemble beaucoup Ă  Ruby on Rails et si vous souhaitez essayer Python en connaissant RoR, c'est le framework qu'il vous faut.

      Le gros avantage de Pylons rĂ©side donc dans sa capacitĂ© d'adaptation, un peu Ă  la sauce UNIX : laisser le choix Ă  l'utilisateur en proposant des utilitaires simples que l'on peut enchaĂźner via des pipes. Par ailleurs, il est Ă  noter que le principal dĂ©veloppeur est apparemment accessible ce qui est toujours intĂ©ressant.

      Le problĂšme de pouvoir utiliser autant de briques est le manque de consistance de la documentation. Et mĂȘme le meilleur des frameworks est inutilisable si l'on ne sait pas s'en servir (bon ok, j'exagĂšre un peu ;-)).

      Les composants fournis par dĂ©faut sont en train de chŸanger pour fournir une meilleure base de dĂ©veloppement. En particulier Toscawidgets, dĂ©veloppĂ© par l'Ă©quipe de TurboGears, mais aussi Mako pour les templates.

      Quoi qu'il en soit, Pylons est conceptuellement vraiment intéressant et sera probablement à moyen terme une solution des plus alléchantes, surtout si la réutilisation d'applications venant d'autres frameworks devient possible. Aller vers une inter-opérabilité en ce sens serait une petite révolution.

      TurboGears : un framework pour les unir tous et...

      La philosophie de ce framework est de prendre les meilleurs composants Python existants et de mettre la glu permettant de les lier pour arriver au framework optimal. L'idĂ©e est trĂšs bonne mais je ne suivais plus depuis quelques temps le dĂ©veloppement de ce framework (on peut difficilement tout suivre, heureusement qu'il y a de tels  articles rĂ©capitulatifs !). J'ai Ă©tĂ© vraiment trĂšs surpris d'apprendre la tournure prise par son dĂ©veloppement.

      Le concept est trĂšs bon mais et c'est lĂ  oĂč TurboGears a Ă©chouĂ©, il ne faut pas se tromper lorsque l'on choisit les composants initiaux, au risque de devoir tout recommencer. Et c'est ce qui arrive apparemment Ă  ce framework, ce qui me cause un peu de soucis pour le projet actuel de Guillaume par exemple...

      D'aprĂšs ce que j'ai pu comprendre, la version actuelle (1.0) est gelĂ©e en attendant le dĂ©veloppement de la v2 qui devrait voir quasiment l'ensemble des composants changĂ©s (soit de version, soit d'orientation). C'est un choix qui est difficile Ă  prendre et qui annonce un long hiver pour TurboGears, ce qui se reflĂšte dans le dĂ©sintĂ©ressement de la part de sa communautĂ© apparemment. Je rejoins l'avis de l'auteur dans l'idĂ©e d'un rapprochement avec PyloĄns qui laisserait le choix de changer aisĂ©ment Ă  l'utilisateur et qui se baserait sur certaines des bibliothĂšques dĂ©veloppĂ©es spĂ©cifiquement pour TurboGears comme Toscawidgets.

      En tout cas j'en reviens pas d'un tel revirement de situation, j'espĂšre que le projet pourra tout de mĂȘme se relever car c'Ă©tait vraiment bien parti et ça avait dopĂ©, entre autres, le buzz autour des frameworks web Python au dĂ©but de l'annĂ©e derniĂšre. Il Ă©tait alors aussi populaire que Django !

      Conclusion

      Django et Pylons sont deux solutions ayant fait des choix différents dans l'implémentation de leur framework mais qui sont toutes deux actuellement fonctionnelles. Le choix entre les deux se fera à mon avis en fonction de votre expérience et de votre propre avis sur leur philosophie.

      Comme je le disais prĂ©cĂ©demment, le dĂ©veloppeur est aujourąd'hui confrontĂ© au difficile dilemme d'utiliser un framework adaptĂ© Ă  ses besoins sans pouvoir connaĂźtre tous les frameworks existant en dĂ©tail car ils sont trop nombreux et Ă©voluent trop rapidement. Ne serait-ce que pour ĂȘtre compĂ©tent sur Django, Pylons et Ruby on Rails par exemple, c'est mission quasi-impossible... et je ne parle mĂȘme pas des frameworks PHP !

      Quelle solution alors ? Il ne reste plus que les drogues dures je crois Apprenez ce qui vous plaĂźt. Vous travaillez pour un client, ok. Mais vous travaillez dans le dĂ©veloppement web aussi pour le « fun » que ça procure de coder, n'oubliez jamais ça. Prenez du plaisir dans votre travail et arrĂȘtez de vous prendre la tĂȘte sur le choix du framework, si vous travaillez deux fois plus rapidement car ce que vous faites vous plaĂźt, le client sera toujours content. Et vous aussi :-).

      Logo biologeek DĂ©veloppement web python et frameworks, tour d'horizon dĂ©but 2007 a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 30 Mars 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      [Biologeek] DĂ©veloppement web python et frameworks, tour d'horizon dĂ©but 2007DĂ©veloppement web python et frameworks, tour d'horizon dĂ©but 2007€avec-django/2008-08-31 17:41:09.6897842007-03-23 21:55:48.000000

      Pour le boulot, je devais réaliser un prototype implémentant des processus simples, c'est-à-dire représentés par une suite d'étapes ordonnées. On peut facilement se représenter un tel processus en considérant une ligne de métro avec ses stations sans ramifications.

      C'est relativement simple Ă  Ă©noncer mais c'est un peu plus difficile Ă  modĂ©liser, commençons par le modĂšle de donnĂ©es appliquĂ© Ă  Django (simplifiĂ©) :

      class Step(models.Model):
          title = models.CharField()
      
      class Process(models.Model):
          title = models.CharField()
      
      class ProcessWorkflow(models.Model):
          source = models.ForeignKey(Step)
          target = models.ForeignKey(Step)
          process = models.ForeignKey(Process)

      On dispose donc maintenant d'étapes et de processus. La classe/table ProcessWorkflow permet de lier les étapes entre elles au sein d'un processus.

      Une fois ce modĂšle créé, il s'agit de reconstruire „le workflow lorsqu'on en a besoin. Pour cela, un fonction rĂ©cursive permet assez Ă©lĂ©gamment de se sortir d'affaire. C'est peut-ĂȘtre ici qu'il peut y avoir mieux en termes de performance mais dans le cadre de mon prototype c'est suffisant :

      def build_linear_workflow(items, steps=None, source=None):
          """ Recursive function to build a linear workflow, return a step list. """
          if steps is None:
              steps = []
          for item in items:
              if item.source == source:
                  if item.target is None:
                      return steps
                  else:
                      steps.append(item.target)
                      return build_linear_workflow(items, steps, item.target)

      La fonction est relativement gĂ©nĂ©rique car elle me permet de former des workflows d'Ă©tapes, de processus, de projets, etc. Je pense qu'elle est relativement facile Ă  comprendre avec le nom des variables choisies (le problĂšme de performance est au niveau de la boucle sur l'ensemble des items, je pense que je poŠurrais facilement retirer l'item ajoutĂ© Ă  steps).

      Il ne reste plus qu'Ă  ajouter cette ressource sous la forme d'un propriĂ©tĂ© au prĂ©cĂ©dent modĂšle, la classe Process devient alors :

      class Process(models.Model):
          title = models.CharField()
      
          def get_workflow(self):
              return build_linear_workflow(ProcessWorkflow.objects.filter(process=self.id))
          workflow = property(get_workflow)

      On peut maintenant utiliser directement le workflow dans un template de la façon suivante :

      <h3>{{ process.title }}</h3>
      {% if process.workflow %}
      <ul>
      	{% for step in process.workflow %}
      		<li>{{ step.title }}</li>
      	{% endfor %}
      </ul>
      {% endif %}

      Simple comme Django :-).

      Voici le fruit de mes recherches, merci Ă  tous ceux qui ont contribuĂ© au rĂ©sultat final, n'hĂ©sitez pas Ă  rĂ©agir si vous avez une solution plus simple/Ă©lĂ©gante. La prochaine Ă©tape, c'est de passer aux workflows plus complexes, po§uvant prĂ©senter des arborescences ascendantes et/ou descendantes. Le casse-tĂȘte ne fait que commencer...

      Logo biologeek ModĂ©lisation d'un workflow linĂ©aire avec Django a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 23 Mars 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      Pour le boulot, je devais rĂ©aliser un prototype impšlĂ©mentant des processus simples, c'est-Ă -dire reprĂ©sentĂ©s par une suite d'Ă©tapes ordonnĂ©es. On peut facilement se reprĂ©senter un tel processus en considĂ©rant une ligne de mĂ©tro avec ses stations sans ramifications.

      C'est relativement simple Ă  Ă©noncer mais c'est un peu plus difficile Ă  modĂ©liser, commençons par le modĂšle de donnĂ©es appliquĂ© Ă  Django (simplifiĂ©) :

      class Step(models.Model):
          title = models.CharField()
      
      class Process(models.Model):
          title = models.CharField()
      
      class ProcessWorkflow(models.Model):
          source = models.ForeignKey(Step)
          target = models.ForeignKey(Step)
          process = models.ForeignKey(Process)

      On dispose donc maintenant d'étapes et de processus. La classe/table ProcessWorkflow permet de lier les étapes entre elles au sein d'un processus.

      Une fois ce modĂšle créé, il s'agit de reconstruire le workflow lorsqu'on en a besoin. Pour cela, un fonction rĂ©cursive permet assez Ă©lĂ©gamment de se sortir d'affaire. ©C'est peut-ĂȘtre ici qu'il peut y avoir mieux en termes de performance mais dans le cadre de mon prototype c'est suffisant :

      def build_linear_workflow(items, steps=None, source=None):
          """ Recursive function to build a linear workflow, return a step list. """
          if steps is None:
              steps = []
          for item in items:
              if item.source == source:
                  if item.target is None:
                      return steps
                  else:
                      steps.append(item.target)
                      return build_linear_workflow(items, steps, item.target)

      La fonction est relativement générique car elle me permet de former des workflows d'étapes, de processus, de projets, etc. Je pense qu'elle est relativement facile à comprendre avec le nom des variables choisies (le problÚme de performance est au niveau de la boucle sur l'ensemble des items, je pense que je pourrais facilement retirer l'item ajouté à steps).

      Il ne reste plus qu'Ă  ajouter cette ressource sous la forȘme d'un propriĂ©tĂ© au prĂ©cĂ©dent modĂšle, la classe Process devient alors :

      class Process(models.Model):
          title = models.CharField()
      
          def get_workflow(self):
              return build_linear_workflow(ProcessWorkflow.objects.filter(process=self.id))
          workflow = property(get_workflow)

      On peut maintenant utiliser directement le workflow dans un template de la façon suivante :

      <h3>{{ process.title }}</h3>
      {% if process.workflow %}
      <ul>
      	{% for step in process.workflow %}
      		<li>{{ step.title }}</li>
      	{% endfor %}
      </ul>
      {% endif %}

      Simple comme Django :-).

      Voici le fruit de mes recherches, merci Ă  tous ceux qui ont contribuĂ© au rĂ©sultat final, n'hĂ©sitez pas Ă  rĂ©agir si vous avez une solution plus simple/Ă©lĂ©gante. La prochaine Ă©tape, c'est de passer aux workflows plus complexes, pouvant prĂ©senter des arborescences ascendantes et/ou descendantes. Le casse-tĂȘte ne fait que commencer...

      Logo biologeek ModĂ©lisation d'un workflow linĂ©aire avec Django a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 23 Mars 2007. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      [Biologeek] ModĂ©lisation d'un workflow linĂ©aire avec DjangoModĂ©lisation d'un workflow linĂ©aire avec Django ‘‘À‚ YAAœœohttp://www.biologeek.com/django,python,web-frameworks/modelisation-d-un-workflow-lineaire-Ł­rammation-en-python">dĂ©jĂ  essayĂ© d'autres fonctions mais autant innover un peu.

      Allons-y donc avec le dĂ©corateur suivant :

      from test import pystone
      import time
      
      kPs = 1000
      TOLERANCE = 0.5 * kPs
      
      def mesure_pystone():
          pystone.pystones(loops=pystone.LOOPS)
          pystone.pystones(loops=pystone.LOOPS)
          return pystone.pystones(loops=pystone.LOOPS)
      
      def timedtest(function, local_pystones=mesure_pystone()):
          """ Decorator to measure execution time in pystones """
          def wrapper(*args, **kw):
              all = []
              for i in range(3):
                  start_time = time.time()
                  try:
                      res = function(*args, **kw)
                  finally:
                      total_time = time.time() - start_time
                      if total_time == 0:
                          temps = 0
                      else:
                          ratio = local_pystones[0] / local_pystones[1]
                          temps = total_time / ratio
                      all.append(temps)
              print '%d pystones' % min(all)ź
              return res
          return wrapper

      J'ai testĂ© les fonctions suivantes qui ne sont pas les mĂȘmes que les exemples de Seb mais qui retournent (elles, merci Haypo :-)) le mĂȘme rĂ©sultat :

      @timedtest
      def map_without_list_comprehension():
          for i in range(10000):
              map(abs, [-5,7,-12])
      
      @timedtest
      def map_with_list_comprehension():
          for i in range(10000):
              [abs(i) for i in [-5,7,-12]]
      
      print '=== map vs. list-comprehension ==='
      print 'map without list-comprehension:'
      map_without_list_comprehension()
      print 'map with list-comprehension:'
      map_with_list_comprehension()
      
      @timedtest
      def filter_without_list_comprehension():
          for i in range(10000):
              filter(abs, [-5,7,0,-12] )
      
      @timedtest
      def filter_with_list_comprehension():
          for i in range(10000):
              [i for i in [-5,7,0,-12] if i]
      
      print '=== filter vs. list-comprehension ==='
      print 'filter without list-comprehension:'
      filter_without_list_comprehension()
      Żprint 'filter with list-comprehension:'
      filter_with_list_comprehension()

      Et voila les rĂ©sultats obtenus :

      === map vs. list-comprehension ===
      map without list-comprehension:
      638 pystones
      map with list-comprehension:
      534 pystones
      === filter vs. list-comprehension ===
      filter without list-comprehension:
      612 pystones
      filter with list-comprehension:
      550 pystones

      Il me semble que c'est sans appel : les list-comprehensions sont toujours plus rapides que map ou filter avec Python 2.4. Il faudrait tester tout ça avec Python 2.5 mais je pense que les rĂ©sultats seraient encore plus significatifs.

      Logo biologeek Ben°chmarks map, filter vs. list-comprehensions a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 25 Octobre 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      Je viens de tomber sur les snyppets de Seb Sauvage (site que j'apprĂ©cie beaucoup par ailleurs) et il y a une phrase qui m'a interpellĂ© sur le paragraphe consacrĂ© Ă  zip, map, filter et aux list-comprehensions :

      Except that {map|filter} is faster. (than list-comprehensions)

      Ni une, ni deux, je récupÚre l'article de Tarek qui est trÚs bon et qui comporte une fonction testant la durée d'execution des fonctions pour pouvoir comparer. J'avais déjà essayé d'autres fonctions mais autant innover un peu.

      Allons-y donc avec le dĂ©corateur suivant :

      from test import pystone
      import time
      
      kPs = 1000
      TOLERANCE = 0.5 * kPs
      
      def mesure_pystone():
          pystone.pystones(loops=pystone.LOOPS)
          pystone.pystones(loops=pystone.LOOPS)
          return pystone.pystones(loops=pystone.LOOPS)
      
      def timedtest(function, local_pystones=mesure_pystone()):
          """ Decorator to measure execution time in pystones """
          def wrapper(*args, **kw):
              all = []
              for i in range(3):
                  start_time = time.time()
                  try:
                      res = function(*args, **kČw)
                  finally:
                      total_time = time.time() - start_time
                      if total_time == 0:
                          temps = 0
                      else:
                          ratio = local_pystones[0] / local_pystones[1]
                          temps = total_time / ratio
                      all.append(temps)
              print '%d pystones' % min(all)
              return res
          return wrapper

      J'ai testĂ© les fonctions suivantes qui ne sont pas les mĂȘmes que les exemples de Seb mais qui retournent (elles, merci Haypo :-)) le mĂȘme rĂ©sultat :

      @timedtest
      def map_without_list_comprehension():
          for i in range(10000):
              map(abs, [-5,7,-12])
      
      @timedtest
      def map_with_list_comprehension():
          for i in range(10000):
              [abs(i) for i in [-5,7,-12]]
      
      print '=== map vs. list-comprehension ==='
      print 'map without list-comprehension:'
      map_without_list_comprehension()
      print 'map with list-comprehension:'
      map_with_list_comprehension()
      
      @timełdtest
      def filter_without_list_comprehension():
          for i in range(10000):
              filter(abs, [-5,7,0,-12] )
      
      @timedtest
      def filter_with_list_comprehension():
          for i in range(10000):
              [i for i in [-5,7,0,-12] if i]
      
      print '=== filter vs. list-comprehension ==='
      print 'filter without list-comprehension:'
      filter_without_list_comprehension()
      print 'filter with list-comprehension:'
      filter_with_list_comprehension()

      Et voila les rĂ©sultats obtenus :

      === map vs. list-comprehension ===
      map without list-comprehension:
      638 pystones
      map with list-comprehension:
      534 pystones
      === filter vs. list-comprehension ===
      filter without list-comprehension:
      612 pystones
      filter with list-comprehension:
      550 pystones

      Il me semble que c'est sans appel : les list-comprehensions sont toujours plus rapides que map ou filter avec Python 2.4. Il faudrait tester tout ça avec Python 2.5 mais je pense que les rĂ©sultats seraient encore plus significatifs.

      Logo biologeek Benchmarks map, filter vs. list-comprehensions a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 25 Octobre 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      [Biologeek] Benchmarks map, filter vs. list-comprehensionsBenchmarks map, filter vs. list-comprehensions 33Ç%‚! IAAĆ+Ć+ihttp://www.biologeek.com/bonnes-pratiques,python/benchmarks-map-filter-vs-list-comprehensions/2008-08-31 17:41:09.7312542006-10-25 17:00:06.000000

      Je viens de tomber sur les snyppets de Seb Sauvage (site que j'apprĂ©cie beaucoup par ailleurs) et il y a une phrase qui m'a interpellĂ© sur le paragraphe consacrĂ© Ă  zip, map, filter et aux list-comprehensions :

      Except that {map|filter} is faster. (than list-comprehensions)

      Ni une, ni deux, je rĂ©cupĂšre l'article de Tarek qui est trĂšs bon et qui comporte une fonction testant la durĂ©e d'execution des fonctions pour pouvoir comparer. J'avais premier opus, au passage merci NiKo, j'ai dĂ©cidĂ© de faire des analyses plus poussĂ©es. Ça m'a donnĂ© l'occasion de faire une vraie classe Python et d'obtenir de beaux graphes grĂące Ă  matplotlib.

      La classe Python

      Elle est vraiment basique mais ça ne l'empĂȘche pas d'ĂȘtre bien documentĂ©e donc elle devrait ĂȘtre facile Ă  prendre en main. Voici le lien pour la tĂ©lĂ©charger.

      Attention, la classe charge toutes les donnĂ©es en mĂ©moire (contrairement aux scripts prĂ©cĂ©dents) donc il vaut mieux avoir pas mal de mĂ©moire vive si vous voulez faire vos tests sur l'ensemble des donnĂ©es. Je n'ai actuellement que mon portabl·e pour travailler donc je n'ai considĂ©rĂ© pour la suite que les 2 000 000 premiĂšres lignes de requĂȘtes.

      Satisfaction en fonction du nombre de mots-clés

      Script

      Il faut bien justifier la catĂ©gorie du billet quand mĂȘme ;-).

      from pylab import *
      Analysis = AOLDataAnalysis()
      Analysis.load_data('user-ct-test-collection-01-head2000000.txt')
      satisfaction = []
      for i in range(1,11):
          followed, notfollowed, followed_rank = Analysis.get_satisfaction(keywords_number=i)
          satisfaction.append(round(followed/float(notfollowed)*100., 2))
      plot(range(1,11), satisfaction, 'k', range(1,11), satisfaction, 'bo')
      ylabel('Indice de satisfaction')
      xlabel('Nombre de mots-cles')
      title('Courbe de satisfaction des utilisateurs en fonction du nombre de mots-cles')
      show()

      J'utilise matplotlib qui est packagĂ© sous Ubuntu et probablement pour de nombreuses distribution car cette bibliothĂšque permet de s'amuser avec le rĂ©sultat une fois qu'il est gĂ©nĂ©rĂ©, je vous laisse tžester.

      Résultat

      Courbe de satisfaction des utilisateurs en fonction du nombre de mots-clés

      Interprétation

      Je pense que la courbe illustre assez bien le rĂ©sultat ! L'optimum de satisfaction est obtenu pour 4 mots-clĂ©s par recherche. En revanche la courbe diminue ensuite ce qui pourrait paraĂźtre Ă©tonnant mais cela doit correspondre aux personnes mettant des questions complĂštes dans les requĂȘtes (?). Personnellement en effet je dois rarement dĂ©passer les 5 mots-clĂ©s pour mes recherches. Lorsqu'on en arrive Ă  mettre de trop nombreux mots-clĂ©s c'est qu'on effectue des recherches sur un sujet bien prĂ©cis qui n'est pas forcĂ©ment bien documentĂ©, d'oĂč la baisse de satisfaction.

      Différents types d'utilisateurs

      J'avais commencĂ© Ă  faire des courbes mais je ne suis pas le seul Ă  m'intĂ©resser Ă  ces dočnnĂ©es donc les principaux profils ont Ă©tĂ© Ă©tablis avec humour. Si ça vous intĂ©resse, la classe permet de traiter les exclusions de mots (il y a un exemple dans la doc).

      Les sites les plus visités en fonction du nombre de mots-clés

      Le script

      from pylab import *
      Analysis = AOLDataAnalysis()
      Analysis.load_data('user-ct-test-collection-01-head2000000.txt')
      for i in range(4):
          if i == 0:
              real_i, i = i, '*'
          else:
              real_i = i
          items, total = Analysis.get_popular_links(rank_filter=i)
          color_per_site = {
              'http://www.google.com' : 'b',
              'http://en.wikipedia.org' : 'g',
              'http://www.ebay.com' : 'r',
              'http://www.myspace.com' : 'c',
              'http://www.amazon.com' : 'm',
              'http://www.imdb.com' : 'y',
              'http://www.yahoo.com' : 'k'
          }
          numbers, legends, colors = [], [], []
          for item in items[1:11]:
              numbers.append(item[1])
              legends.append(item[0])
              try:
                  colors.appșend(color_per_site[item[0]])
              except KeyError:
                  colors.append('w')
          subplot(str(41)+str(real_i+1))
          bar(range(1,11), numbers, color=colors)
          ylabel('Pour '+str(i)+' mots-cles')
          legend(legends)
      show()

      Résultat

      Barplot de la popularité des sites en fonction du nombre de mots-clés

      Interprétation

      C'est vraiment surprenant, je me demande ce que ça donnerait avec l'ensemble des donnĂ©es (d'ailleurs si une Ăąme charitable avec 2Go de ram se manifestait :-)). On constate pour l'ensemble des requĂȘtes que Google arrive vraiment en tĂȘte. En mĂȘme temps c'est le moteur employĂ© donc il faudrait voir ce qu'ils comptabilisent comme Ă©tant des sorties vers Google. Viennent ensuite myspace, yahoo et wikipedia ce qui me semble logique. Pas de vĂ©ritable surprise dans ce top 10 si ce n'est la prĂ©sence de yahoo mail ?! Est-ce la messagerie par dĂ©faut des aoliens&nb»sp;?

      Si l'on passe maintenant Ă  la recherche avec un seul mot-clĂ©. Alors si j'ai bien compris, certains utiliseraient le champ de recherche comme un champ d'url. Soit. Donc en fait les sites sortant avec un seul mot-clĂ© sont la plupart du temps des sites ayant Ă©tĂ© insĂ©rĂ©s avec une URL complĂšte. Étrangement on ne retrouve plus Google, l'hypothĂšse prĂ©cĂ©dente est donc en partie vĂ©rifiĂ©e. Mapquest qui Ă©tait dĂ©jĂ  trĂšs populaire se retrouve dans le top 5.

      Lorsque l'on passe Ă  deux mots-clĂ©s, lĂ  je pense qu'on peut vĂ©ritablement commencer Ă  parler de recherche. Et les rĂ©sultats sont en accord avec cette hypothĂšse, les deux premiers sites Ă©tant Amazon et Wikipedia. Vient ensuite Yahoo search et lĂ  je sais pas trop quoi penser, un moteur de recherche sort rarement des recherches sur d'autres moteurs. Enfin en tout cas pas entre les 3 grands. Étrange...

      Le passage Ă  3 mots-clĂ©s confirme la domination d'Amazon, on retrouve ensuite Yahoo mail (encore plus fou !Œ) puis IMDb ce qui est plus logique. Les recherches avancĂ©es Ă©tant faites pour les livres, la musique et les films. On note l'absence de WikipĂ©dia lors du passage Ă  3 mots-clĂ©s, l'encyclopĂ©die Ă©tant surtout utilisĂ©e pour un seul mot (normalement).

      En conclusion, on peut noter le bon rĂ©fĂ©rencement d'Amazon qui arrive Ă  attirer le plus grand nombre de « vrais » chercheurs et la popularitĂ© de certains sites que je ne connaissais pas pour ma part. Pas dans les deux premiers graphes mais aprĂšs oui (d'ailleurs je me demande si c'est pas dĂ» au nombre limitĂ© de requĂȘtes que j'ai Ă©tudiĂ©).

      Et voila, le traitement de donnĂ©es c'est intĂ©ressant... Ă  condition d'avoir un sujet intĂ©ressant Ă  traiter avec. L'Ă©tude de cas des utilisateurs d'AOL n'est pas vraiment passionnante mais peut ĂȘtre significative selon la cible Ă  laquelle vous vous adressez. J'espĂšre ne jamais avoir Ă  me prĂ©occuper plus en avant de celle-ci ;-)œ.

      Logo biologeek Analyse des donnĂ©es utilisateur d'AOL : suite et fin a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 14 AoĂ»t 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      Devant le franc succĂšs remportĂ© par le premier opus, au passage merci NiKo, j'ai dĂ©cidĂ© de faire des analyses plus poussĂ©es. Ça m'a donnĂ© l'occasion de faire une vraie classe Python et d'obtenir de beaux graphes grĂące Ă  matplotlib.

      La classe Python

      Elle est vraiment basique mais ça ne l'empĂȘche pas d'ĂȘtre bien documentĂ©e donc elle devrait ĂȘtre facile Ă  prendre en main. Voici le lien pour la tĂ©lĂ©charger.

      Attention, la classe charge toutes les donnĂ©es en mĂ©moire (contrairement aux scripts prĂ©cĂ©dents) donc il vaut mieux avoir pas mal de mĂ©moire vive si vous voulez faire vos tests sur l'ensemblże des donnĂ©es. Je n'ai actuellement que mon portable pour travailler donc je n'ai considĂ©rĂ© pour la suite que les 2 000 000 premiĂšres lignes de requĂȘtes.

      Satisfaction en fonction du nombre de mots-clés

      Script

      Il faut bien justifier la catĂ©gorie du billet quand mĂȘme ;-).

      from pylab import *
      Analysis = AOLDataAnalysis()
      Analysis.load_data('user-ct-test-collection-01-head2000000.txt')
      satisfaction = []
      for i in range(1,11):
          followed, notfollowed, followed_rank = Analysis.get_satisfaction(keywords_number=i)
          satisfaction.append(round(followed/float(notfollowed)*100., 2))
      plot(range(1,11), satisfaction, 'k', range(1,11), satisfaction, 'bo')
      ylabel('Indice de satisfaction')
      xlabel('Nombre de mots-cles')
      title('Courbe de satisfaction des utilisateurs en fonction du nombre de mots-cles')
      show()

      J'utilise matplotlib qui est packagĂ© sous Ubuntu et probablement pour de nombreuses distribution car cette bibliothĂšque permet de s'amuser avec le rĂ©sÀultat une fois qu'il est gĂ©nĂ©rĂ©, je vous laisse tester.

      Résultat

      Courbe de satisfaction des utilisateurs en fonction du nombre de mots-clés

      Interprétation

      Je pense que la courbe illustre assez bien le rĂ©sultat ! L'optimum de satisfaction est obtenu pour 4 mots-clĂ©s par recherche. En revanche la courbe diminue ensuite ce qui pourrait paraĂźtre Ă©tonnant mais cela doit correspondre aux personnes mettant des questions complĂštes dans les requĂȘtes (?). Personnellement en effet je dois rarement dĂ©passer les 5 mots-clĂ©s pour mes recherches. Lorsqu'on en arrive Ă  mettre de trop nombreux mots-clĂ©s c'est qu'on effectue des recherches sur un sujet bien prĂ©cis qui n'est pas forcĂ©ment bien documentĂ©, d'oĂč la baisse de satisfaction.

      Différents types d'utilisateurs

      J'avais commencé à faire des courbes mais je ne suis pas le seul à m'intéresser à ces données donc les principaux profils ont été établis avec humour. Si ça vous intéresse, la classe permet de traiter les exclusions de mots (il y a un exemple dans la doc).

      Les sites les plus visités en fonction du nombre de mots-clés

      Le script

      from pylab import *
      Analysis = AOLDataAnalysis()
      Analysis.load_data('user-ct-test-collection-01-head2000000.txt')
      for i in range(4):
          if i == 0:
              real_i, i = i, '*'
          else:
              real_i = i
          items, total = Analysis.get_popular_links(rank_filter=i)
          color_per_site = {
              'http://www.google.com' : 'b',
              'http://en.wikipedia.org' : 'g',
              'http://www.ebay.com' : 'r',
              'http://www.myspace.com' : 'c',
              'http://www.amazon.com' : 'm',
              'http://www.imdb.com' : 'y',
              'http://www.yahoo.com' : 'k'
          }
          numbers, legends, colors = [], [], []
          for item in items[1:11]:
              numbers.append(item[1])
              legendsÂ.append(item[0])
              try:
                  colors.append(color_per_site[item[0]])
              except KeyError:
                  colors.append('w')
          subplot(str(41)+str(real_i+1))
          bar(range(1,11), numbers, color=colors)
          ylabel('Pour '+str(i)+' mots-cles')
          legend(legends)
      show()

      Résultat

      Barplot de la popularité des sites en fonction du nombre de mots-clés

      Interprétation

      C'est vraiment surprenant, je me demande ce que ça donnerait avec l'ensemble des donnĂ©es (d'ailleurs si une Ăąme charitable avec 2Go de ram se manifestait :-)). On constate pour l'ensemble des requĂȘtes que Google arrive vraiment en tĂȘte. En mĂȘme temps c'est le moteur employĂ© donc il faudrait voir ce qu'ils comptabilisent comme Ă©tant des sorties vers Google. Viennent ensuite myspace, yahoo et wikipedia ce qui me semble logique. Pas de vĂ©ritable surprise dans ce top 10 si ce n'est la prĂ©sence de yahoo maiĂl ?! Est-ce la messagerie par dĂ©faut des aoliens ?

      Si l'on passe maintenant Ă  la recherche avec un seul mot-clĂ©. Alors si j'ai bien compris, certains utiliseraient le champ de recherche comme un champ d'url. Soit. Donc en fait les sites sortant avec un seul mot-clĂ© sont la plupart du temps des sites ayant Ă©tĂ© insĂ©rĂ©s avec une URL complĂšte. Étrangement on ne retrouve plus Google, l'hypothĂšse prĂ©cĂ©dente est donc en partie vĂ©rifiĂ©e. Mapquest qui Ă©tait dĂ©jĂ  trĂšs populaire se retrouve dans le top 5.

      Lorsque l'on passe Ă  deux mots-clĂ©s, lĂ  je pense qu'on peut vĂ©ritablement commencer Ă  parler de recherche. Et les rĂ©sultats sont en accord avec cette hypothĂšse, les deux premiers sites Ă©tant Amazon et Wikipedia. Vient ensuite Yahoo search et lĂ  je sais pas trop quoi penser, un moteur de recherche sort rarement des recherches sur d'autres moteurs. Enfin en tout cas pas entre les 3 grands. Étrange...

      Le passage Ă  3 mots-clĂ©s confirme la domination d'AmazoÄn, on retrouve ensuite Yahoo mail (encore plus fou !) puis IMDb ce qui est plus logique. Les recherches avancĂ©es Ă©tant faites pour les livres, la musique et les films. On note l'absence de WikipĂ©dia lors du passage Ă  3 mots-clĂ©s, l'encyclopĂ©die Ă©tant surtout utilisĂ©e pour un seul mot (normalement).

      En conclusion, on peut noter le bon rĂ©fĂ©rencement d'Amazon qui arrive Ă  attirer le plus grand nombre de « vrais » chercheurs et la popularitĂ© de certains sites que je ne connaissais pas pour ma part. Pas dans les deux premiers graphes mais aprĂšs oui (d'ailleurs je me demande si c'est pas dĂ» au nombre limitĂ© de requĂȘtes que j'ai Ă©tudiĂ©).

      Et voila, le traitement de donnĂ©es c'est intĂ©ressant... Ă  condition d'avoir un sujet intĂ©ressant Ă  traiter avec. L'Ă©tude de cas des utilisateurs d'AOL n'est pas vraiment passionnante mais peut ĂȘtre significative selon la cible Ă  laquelle vous vous adressez. J'espĂšre ne jamais avoir Ă  me prĂ©occuper plus en avant de celle-ci ;-).

      Logo biologeek Analyse des donnĂ©es utilisateur d'AOL : suite et fin a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 14 AoĂ»t 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      [Biologeek] Analyse des donnĂ©es utilisateur d'AOL : suite et finAnalyse des donnĂ©es utilisateur d'AOL : suite et fin ŸŸÒ@‚$ 9AAĐ_Đ_qYhttp://www.biologeek.com/critique,livre,python/critique-du-livre-programmation-python/2008-08-31 17:41:09.8589672006-03-19 12:26:26.000000

      C'est LE livre que j'attendais, un peu comme beaucoup de personnes qui connaissent les bases du langage et qui souhaitent aller plus loin mais qui n'arrivent pas forcĂ©ment Ă  trouver l'information sur interʁ·M‚#WAA”!”!)http://www.biologeek.com/python,web/les-100-premiers-mots-cles-recherches-par-les-utiliƁ‚8‚";AA€5€5whttp://www.biologeek.com/python,web/analyse-des-donnees-utilisateur-d-aol-suite-et-fin/2008-08-31 17:41:09.7742602006-08-14 21:42:22.000000

      Devant le franc sucӂsateurs-d-aol/2008-08-31 17:41:09.8171772006-08-09 06:49:35.000000

      Vous n'ĂȘtes pas sans savoir que des donnĂ©es reatives aux utilisateurs d'AOL ont Ă©tĂ© mises en ligne derniĂšrement (version anglaise, je pense que les serveurs sont plus rĂ©guliĂšrement mis Ă  jour si vous voulez rĂ©cupĂ©rer les donnĂ©es). Voici le script et les 100 premiers mots-clĂ©s de recherche rĂ©alisĂ©es par ces utilisateurs. Attention les donnĂ©es n'ont pas Ă©tĂ© filtrĂ©es donc ce post peut contenir des mots heurtant la sensibilitĂ© des plus jeunes lecteurs.

      Les 100 premiers mots-clés

      Un site est déjà en ligne pour fouiller dans toutes ces données mais je voulais connaßtre les meilleurs mots-clés.

      Script Python
      freq = {}
      for i in range(1, 11):
          if i in range(1, 10): i = '0'+str(i)
          for line in open('user-ct-test-collection-'+str(i)+'.txt'):
              for word in line.split('\t')[1].split():
                  if len(word) >= 3:
                      try:
                          freq[word] += 1
                      except KeyError:
                          freq[word] = 1
      
      total = float(sum(freq.values()))
      items = freq.items()
      items.sort(lambda a, b: -cmp(a[1], b[1]))
      for word, count in items[:100]:
          print count, word, round(count/total*100., 2)

      Résultats

      Les résultats sont dans l'ordre décroissant, chaque ligne correspond à position. occurences, mot-clé, taux d'apparition

      1. 837298 the 1.03
      2. 698426 for 0.86
      3. 692358 and 0.85
      4. 449102 free 0.55
      5. 363020 google 0.45
      6. 270158 new 0.33
      7. 251125 http 0.31
      8. 236473 pictures 0.29
      9. 231574 county 0.28
      10. 217750 yahoo 0.27
      11. 208600 how 0.26
      12. 188800 Élyrics 0.23
      13. 182564 school 0.22
      14. 176714 myspace 0.22
      15. 166225 sex 0.2
      16. 160174 ebay 0.2
      17. 159871 florida 0.2
      18. 155790 com 0.19
      19. 145346 sale 0.18
      20. 144472 with 0.18
      21. 144242 city 0.18
      22. 140896 home 0.17
      23. 138907 american 0.17
      24. 136993 state 0.17
      25. 127214 www 0.16
      26. 121237 .com 0.15
      27. 120478 what 0.15
      28. 119897 games 0.15
      29. 118366 texas 0.15
      30. 117860 music 0.14
      31. 115674 york 0.14
      32. 110711 yahoo.com 0.14
      33. 109857 bank 0.13
      34. 108839 black 0.13
      35. 108607 beach 0.13
      36. 108228 nude 0.13
      37. 104911 high 0.13
      38. 102669 online 0.13
      39. 102016 aol 0.13
      40. 101424 news 0.12
      41. 101226 map 0.12
      42. 101138 pics 0.12
      43. 98942 girls 0.12
      44. 96254 college 0.12
      45. 96063 you 0.12
      46. 92866 2006 0.11
      47. 92701 car 0.11
      48. 91862 real 0.11
      49. 89954 mapquest 0.11
      50. 89768 from 0.11
      51. 88975 university 0.11
      52. 87936 jobs 0.11
      53. 87283 center 0.11
      54. 86572 google.com 0.11
      55. 86083 myspace.com 0.11
      56. 85265 homes 0.1
      57. 85156 porn 0.1
      58. 84175 ohio 0.1
      59. 82530 california 0.1
      60. 80015 women 0.1
      61. 79429 white 0.1
      62. 78212 photos 0.1
      63. 77077 san 0.09
      64. 74934 estate 0.09
      65. 74360 club 0.09
      66. 74161 day 0.09
      67. 73791 art 0.09
      68. 72760 park 0.09
      69. 72728 house 0.09
      70. 72437 world 0.09
      71. 71346 baby 0.09
      72. 70068 big 0.09
      73. 69716 parts 0.09
      74. 69413 hotel 0.09
      75. 68313 weather 0.08
      76. 67802 furniture 0.08
      77. 67756 airlines 0.08
      78. 65458 blue 0.08
      79. 65332 credit 0.08
      80. 64648 movie 0.08
      81. 64619 south 0.08
      82. 64333 lottery 0.08
      83. 64138 internet 0.08
      84. 64137 island 0.08
      85. 64003 john 0.08
      86. 63017 your 0.08
      87. 62882 video 0.08
      88. 62866 north 0.08
      89. 62574 hot 0.Ë08
      90. 62137 air 0.08
      91. 62059 wedding 0.08
      92. 61841 lake 0.08
      93. 61674 best 0.08
      94. 61363 used 0.08
      95. 61103 dog 0.08
      96. 60942 hotels 0.07
      97. 60749 america 0.07
      98. 60702 love 0.07
      99. 59443 department 0.07
      100. 59153 pages 0.07

      Interprétation

      Des commentaires sur ces résultats ce soir, faut que j'aille bosser là ;-). La pause déjeuner devrait suffire.

      On remarque dĂ©jĂ  que les 3 premiers (the, for et and) sont Ă  exclure... ou pas. Le and est probablement utilisĂ© en tant qu'opĂ©rateur logique mais le the par exemple est un bon indicateur de l'utilisation des articles dans les moteurs de recherche. Il faut donc peut-ĂȘtre se tourner vers une rĂ©fĂ©rencement avec article et non plus par suite de mots-clĂ©s (d'oĂč la pertinence d'avoir un contexte).

      Ensuite le champ lexical de la pornographie est trĂšs ÌprĂ©sent mais beaucoup moins que ce que je pensais. HĂŽnnetement, je m'attendais Ă  sex dans le top 5. C'est presque rassurant (bon je me suis pas risquĂ© Ă  faire le total pour rester optimiste).

      Ce qui est Ă©tonnant aussi c'est l'absence du mot mp3 des recherches. Je ne sais pas si c'est par peur de la RIAA, qui sait ? Les personnes utilisant le moteur de recherche d'AOL sont sĂ»rement trĂšs respectueuses des lois (ou alors ont compris qu'il existait d'autres outils pour ça).

      Les recherches sont un bon indicateur des tendances avec myspace qui a le vent en poupe, par contre il n'y a aucune star qui arrive Ă  entrer dans le top 100 (bon Ă  part John...). On remarque aussi qu'il y a beaucoup de recherches effectuĂ©es en utilisant en mot-clĂ© le nom d'un autre moteur de recherche (j'avoue ne pas trop comprendre). De mĂȘme, les mots-clĂ©s http, www ou com montrent l'ignorance de leur signification par les chercheurs.

      Je trouve que l'on retrouve aussi beaucoup de localitĂ©s prĂ©sentes dans ces recherches, il faudrait pouvoir comparer Ă  des donnĂ©es datant de quelques annĂ©es mais c'est peut-ĂȘtre un nouvel aspect du web (ce qui m'Ă©tonne Ă  moitiĂ© sinon personne n'aurait lancĂ© la cartographie en ligne).

      Quels liens sont suivis ?

      On dit souvent que les 3 premiers liens d'un moteur de recherche sont les seuls suivis. Je voulais vĂ©rifier si cela Ă©tait vrai pour ces donnĂ©es, c'est pas tous les jours qu'on a cette d'aubaine !

      Script python :

      nofollowed, followed, first_rank, second_rank, third_rank = 0, 0, 0, 0, 0
      for i in range(1, 11):
          if i in range(1, 10): i = '0'+str(i)
          for line in open('user-ct-test-collection-'+str(i)+'.txt'):
              #for line in open('user-ct-test-collection-01.txt'):
              rank = line.split('\t')[3]
              if rank:
      Î            followed += 1
                  if rank == '1':
                      first_rank += 1
                  elif rank == '2':
                      second_rank += 1
                  elif rank == '3':
                      third_rank += 1
              else:
                  nofollowed += 1
      total = float(nofollowed + followed)
      print 'Total', total, round(total/total*100., 2), '%'
      print 'Non suivi', nofollowed, round(nofollowed/total*100., 2), '%'
      print 'Suivi', followed, round(followed/total*100., 2), '%'
      print 'Premier suivi', first_rank, round(first_rank/total*100., 2), '% soit', round(first_rank/float(followed)*100., 2), '% des liens suivis'
      print 'Deuxieme suivi', second_rank, round(second_rank/total*100., 2), '% soit', round(second_rank/float(followed)*100., 2), '% des liens suivis'
      print 'Troisieme suivi', third_rank, round(third_rank/total*100., 2), '% soit', round(third_rank/float(followed)*100., 2), '% des liens suivis'

      Résultats

      Chaque ligne correspond Ă  : Type, nombre, taux par rapport au total

      • Total 36389577.0 100.0 %
      • Non suivi 16946938 46.57 %
      • Suivi 19442639 53.43 %
      • Premier suivi 8220278 22.59 % soit 42.28 % des liens suivis
      • Deuxieme suivi 2316738 6.37 % soit 11.92 % des liens suivis
      • Troisieme suivi 1640751 4.51 % soit 8.44 % des liens suivis

      Interprétation

      Sur 36 millions de recherches, seules 54% sont considĂ©rĂ©es comme Ă©tant pertinentes par l'utilisateur. C'est Ă©normĂ©ment peu (il serait trĂšs intĂ©ressant d'avoir les donnĂ©es de Google pour comparer la recherche est faite par Google, encore plus Ă©tonnant !). Et ensuite sur ces 54%, il vaut en effet mieux ĂȘtre placĂ© en tĂȘte de peloton mais moins que ce que je pensais, il reste tout de mĂȘme 40% des liens suivis qui le sont par les rĂ©sultats infĂ©rieurs. Quoiqu'il en soit, la lutte pour la premiĂšre place est justifiĂ©e !

      Conclusion générale

      Les donnĂ©es sont celles des utilisateurs du moteur de recherchĐe d'AOL et je ne pense pas que les recherches effectuĂ©es sur Google par exemple soient de mĂȘme nature, surtout en ce qui concerne les recherches fructueuses. Ces rĂ©sultats sont bruts et il serait trĂšs intĂ©ressant de les affiner davantage en fonction d'un secteur d'activitĂ© donnĂ©. Est-ce que tel type d'utilisateur utilise plusieurs mots-clĂ©s ? Et suit-il le premier lien ? etc.

      Si vous ne donnez pas dans le p0rn, il peut-ĂȘtre intĂ©ressant de rĂ©fĂ©rencer un site de « new lyrics for free ». On comprend aussi pourquoi un moteur de recherche a toujours l'avantage sur ses concurrents en analysant ses recherches. Par exemple au sujet du nombre important de localitĂ©s recherchĂ©es, il est Ă©vident que Google a fait une Ă©tude poussĂ©e lĂ -dessus avant de s'investir dans GoogleMap et devant le nombre de recherches ils Ă©taient certains de la future popularitĂ© de leur service.

      Pour vĂ©ritablement arriver Ă  des conclusions solides, il faudrait les donnĂ©es de Ńplusieurs moteurs de recherche rĂ©parties sur plusieurs dates. C'est impossible Ă  avoir, il n'y a donc actuellement que les moteurs de recherche qui peuvent se prĂ©cipiter sur ces donnĂ©es pour identifier les diffĂ©rents profils d'utilisateurs ;-).

      Conclusion personnelle : je crois que l'aspect scientifique me manque un peu en ce moment... (sans compter le python).

      [edit du 15/08] : Suite de l'analyse des donnĂ©es sur ce site.

      Logo biologeek Les 100 premiers mots-clĂ©s recherchĂ©s par les utilisateurs d'AOL a Ă©tĂ© rĂ©digĂ© par David LÒarlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 09 AoĂ»t 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      Vous n'ĂȘtes pas sans savoir que des donnĂ©es reatives aux utilisateurs d'AOL ont Ă©tĂ© mises en ligne derniĂšrement (version anglaise, je pense que les serveurs sont plus rĂ©guliĂšrement mis Ă  jour si vous voulez rĂ©cupĂ©rer les donnĂ©es). Voici le script et les 100 premiers mots-clĂ©s de recherche rĂ©alisĂ©es par ces utilisateurs. Attention leÓs donnĂ©es n'ont pas Ă©tĂ© filtrĂ©es donc ce post peut contenir des mots heurtant la sensibilitĂ© des plus jeunes lecteurs.

      Les 100 premiers mots-clés

      Un site est déjà en ligne pour fouiller dans toutes ces données mais je voulais connaßtre les meilleurs mots-clés.

      Script Python

      freq = {}
      for i in range(1, 11):
          if i in range(1, 10): i = '0'+str(i)
          for line in open('user-ct-test-collection-'+str(i)+'.txt'):
              for word in line.split('\t')[1].split():
                  if len(word) >= 3:
                      try:
                          freq[word] += 1
                      except KeyError:
                          freq[word] = 1
      
      total = float(sum(freq.values()))
      items = freq.items()
      items.sort(lambda a, b: -cmp(a[1], b[1]))
      for word, count in items[:100]:
          print count, word, round(count/total*100., 2)

      Résultats

      Les résultats sont dans l'ordre décroissant, chaque ligne correspond à position. occurences, mot-clé, taux d'apparition

      1. 837298 the 1.03
      2. 698426 for 0.86
      3. 692358 and 0.85
      4. 449102 free 0.55
      5. 363020 google 0.45
      6. 270158 new 0.33
      7. 251125 http 0.31
      8. 236473 pictures 0.29
      9. 231574 county 0.28
      10. 217750 yahoo 0.27
      11. 208600 how 0.26
      12. 188800 lyrics 0.23
      13. 182564 school 0.22
      14. 176714 myspace 0.22
      15. 166225 sex 0.2
      16. 160174 ebay 0.2
      17. 159871 florida 0.2
      18. 155790 com 0.19
      19. 145346 sale 0.18
      20. 144472 with 0.18
      21. 144242 city 0.18
      22. 140896 home 0.17
      23. 138907 american 0.17
      24. 136993 state 0.17
      25. 127214 www 0.16
      26. 121237 .com 0.15
      27. 120478 what 0.15
      28. 119897 games 0.15
      29. 118366 texas 0.15
      30. 117860 music 0.14
      31. 115674 york 0.14
      32. 110711 yahoo.com 0.14
      33. 109857 bank 0.13
      34. 108839 black 0.13
      35. 108607 beach 0.13
      36. 108228 nudŐe 0.13
      37. 104911 high 0.13
      38. 102669 online 0.13
      39. 102016 aol 0.13
      40. 101424 news 0.12
      41. 101226 map 0.12
      42. 101138 pics 0.12
      43. 98942 girls 0.12
      44. 96254 college 0.12
      45. 96063 you 0.12
      46. 92866 2006 0.11
      47. 92701 car 0.11
      48. 91862 real 0.11
      49. 89954 mapquest 0.11
      50. 89768 from 0.11
      51. 88975 university 0.11
      52. 87936 jobs 0.11
      53. 87283 center 0.11
      54. 86572 google.com 0.11
      55. 86083 myspace.com 0.11
      56. 85265 homes 0.1
      57. 85156 porn 0.1
      58. 84175 ohio 0.1
      59. 82530 california 0.1
      60. 80015 women 0.1
      61. 79429 white 0.1
      62. 78212 photos 0.1
      63. 77077 san 0.09
      64. 74934 estate 0.09
      65. 74360 club 0.09
      66. 74161 day 0.09
      67. 73791 art 0.09
      68. 72760 park 0.09
      69. 72728 house 0.09
      70. 72437 world 0.09
      71. 71346 baby 0.09
      72. 70068 big 0.09
      73. 69716 parts 0.09
      74. 69413 hotel 0.09
      75. 68313 weather 0Ö.08
      76. 67802 furniture 0.08
      77. 67756 airlines 0.08
      78. 65458 blue 0.08
      79. 65332 credit 0.08
      80. 64648 movie 0.08
      81. 64619 south 0.08
      82. 64333 lottery 0.08
      83. 64138 internet 0.08
      84. 64137 island 0.08
      85. 64003 john 0.08
      86. 63017 your 0.08
      87. 62882 video 0.08
      88. 62866 north 0.08
      89. 62574 hot 0.08
      90. 62137 air 0.08
      91. 62059 wedding 0.08
      92. 61841 lake 0.08
      93. 61674 best 0.08
      94. 61363 used 0.08
      95. 61103 dog 0.08
      96. 60942 hotels 0.07
      97. 60749 america 0.07
      98. 60702 love 0.07
      99. 59443 department 0.07
      100. 59153 pages 0.07

      Interprétation

      Des commentaires sur ces résultats ce soir, faut que j'aille bosser là ;-). La pause déjeuner devrait suffire.

      On remarque dĂ©jĂ  que les 3 premiers (the, for et and) sont Ă  exclure... ou pas. Le and est probablement utilŚisĂ© en tant qu'opĂ©rateur logique mais le the par exemple est un bon indicateur de l'utilisation des articles dans les moteurs de recherche. Il faut donc peut-ĂȘtre se tourner vers une rĂ©fĂ©rencement avec article et non plus par suite de mots-clĂ©s (d'oĂč la pertinence d'avoir un contexte).

      Ensuite le champ lexical de la pornographie est trÚs présent mais beaucoup moins que ce que je pensais. HÎnnetement, je m'attendais à sex dans le top 5. C'est presque rassurant (bon je me suis pas risqué à faire le total pour rester optimiste).

      Ce qui est Ă©tonnant aussi c'est l'absence du mot mp3 des recherches. Je ne sais pas si c'est par peur de la RIAA, qui sait ? Les personnes utilisant le moteur de recherche d'AOL sont sĂ»rement trĂšs respectueuses des lois (ou alors ont compris qu'il existait d'autres outils pour ça).

      Les recherches sont un bon indicateuŰr des tendances avec myspace qui a le vent en poupe, par contre il n'y a aucune star qui arrive Ă  entrer dans le top 100 (bon Ă  part John...). On remarque aussi qu'il y a beaucoup de recherches effectuĂ©es en utilisant en mot-clĂ© le nom d'un autre moteur de recherche (j'avoue ne pas trop comprendre). De mĂȘme, les mots-clĂ©s http, www ou com montrent l'ignorance de leur signification par les chercheurs.

      Je trouve que l'on retrouve aussi beaucoup de localitĂ©s prĂ©sentes dans ces recherches, il faudrait pouvoir comparer Ă  des donnĂ©es datant de quelques annĂ©es mais c'est peut-ĂȘtre un nouvel aspect du web (ce qui m'Ă©tonne Ă  moitiĂ© sinon personne n'aurait lancĂ© la cartographie en ligne).

      Quels liens sont suivis ?

      On dit souvent que les 3 premiers liens d'un moteur de recherche sont les seuls suivis. Je voulais vĂ©rifier si cela Ă©tait vrai pour ces donnĂ©es, c'est pas tous les jours qu'on a cette dÙ'aubaine !

      Script python :

      nofollowed, followed, first_rank, second_rank, third_rank = 0, 0, 0, 0, 0
      for i in range(1, 11):
          if i in range(1, 10): i = '0'+str(i)
          for line in open('user-ct-test-collection-'+str(i)+'.txt'):
              #for line in open('user-ct-test-collection-01.txt'):
              rank = line.split('\t')[3]
              if rank:
                  followed += 1
                  if rank == '1':
                      first_rank += 1
                  elif rank == '2':
                      second_rank += 1
                  elif rank == '3':
                      third_rank += 1
              else:
                  nofollowed += 1
      total = float(nofollowed + followed)
      print 'Total', total, round(total/total*100., 2), '%'
      print 'Non suivi', nofollowed, round(nofollowed/total*100., 2), '%'
      print 'Suivi', followed, round(followed/total*100., 2), '%'
      print 'Premier suivi', first_rank, round(first_rank/total*100., 2), '% soit', round(first_rank/float(followed)*100., 2), '% des liens suivis'
      print 'Deuxieme suivi', second_rÚank, round(second_rank/total*100., 2), '% soit', round(second_rank/float(followed)*100., 2), '% des liens suivis'
      print 'Troisieme suivi', third_rank, round(third_rank/total*100., 2), '% soit', round(third_rank/float(followed)*100., 2), '% des liens suivis'

      Résultats

      Chaque ligne correspond Ă  : Type, nombre, taux par rapport au total

      • Total 36389577.0 100.0 %
      • Non suivi 16946938 46.57 %
      • Suivi 19442639 53.43 %
      • Premier suivi 8220278 22.59 % soit 42.28 % des liens suivis
      • Deuxieme suivi 2316738 6.37 % soit 11.92 % des liens suivis
      • Troisieme suivi 1640751 4.51 % soit 8.44 % des liens suivis

      Interprétation

      Sur 36 millions de recherches, seules 54% sont considĂ©rĂ©es comme Ă©tant pertinentes par l'utilisateur. C'est Ă©normĂ©ment peu (il serait trĂšs intĂ©ressant d'avoir les donnĂ©es de Google pour comparer la recherche est faite par Google, encore plus Ă©tonnant !). Et ensuÛite sur ces 54%, il vaut en effet mieux ĂȘtre placĂ© en tĂȘte de peloton mais moins que ce que je pensais, il reste tout de mĂȘme 40% des liens suivis qui le sont par les rĂ©sultats infĂ©rieurs. Quoiqu'il en soit, la lutte pour la premiĂšre place est justifiĂ©e !

      Conclusion générale

      Les donnĂ©es sont celles des utilisateurs du moteur de recherche d'AOL et je ne pense pas que les recherches effectuĂ©es sur Google par exemple soient de mĂȘme nature, surtout en ce qui concerne les recherches fructueuses. Ces rĂ©sultats sont bruts et il serait trĂšs intĂ©ressant de les affiner davantage en fonction d'un secteur d'activitĂ© donnĂ©. Est-ce que tel type d'utilisateur utilise plusieurs mots-clĂ©s ? Et suit-il le premier lien ? etc.

      Si vous ne donnez pas dans le p0rn, il peut-ĂȘtre intĂ©ressant de rĂ©fĂ©rencer un site de « new lyrics for free ». On comprend aussi pourquoi un moteur de recherche a toujours l'avantage sur ses concurrents en analysant seÜs recherches. Par exemple au sujet du nombre important de localitĂ©s recherchĂ©es, il est Ă©vident que Google a fait une Ă©tude poussĂ©e lĂ -dessus avant de s'investir dans GoogleMap et devant le nombre de recherches ils Ă©taient certains de la future popularitĂ© de leur service.

      Pour véritablement arriver à des conclusions solides, il faudrait les données de plusieurs moteurs de recherche réparties sur plusieurs dates. C'est impossible à avoir, il n'y a donc actuellement que les moteurs de recherche qui peuvent se précipiter sur ces données pour identifier les différents profils d'utilisateurs ;-).

      Conclusion personnelle : je crois que l'aspect scientifique me manque un peu en ce moment... (sans compter le python).

      [edit du 15/08] : Suite de l'analyse des donnĂ©es sur ce site.

      Logo biologeek Les 100 premiers mots-clĂ©s recherchĂ©s par les utilisateurs d'AOL a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 09 AoĂ»t 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      [Biologeek] Les 100 premiers mots-clĂ©s recherchĂ©s par les utilisateurs d'AOLLes 100 premiers mots-clĂ©s recherchĂ©s par les utilisateurs d'AOLȚnet. Je dois avouer que j'avais un peu peur, un peu comme un bon film duquel on en attend trop, et bien je n'ai pas Ă©tĂ© déçu, c'est le moins qu'on puisse dire !

      En ouvrant le livre je me suis dit : « Bon les 100, voire 200 premiĂšres pages je vais les lire en diagonale ça va encore ĂȘtre des rappels sur la syntaxe de Python... ». Heureusement, je me trompais...

      La premiĂšre partie, intitulĂ©e « DĂ©couverte de Python », doit ĂȘtre un peu difficile pour un dĂ©butant (bon aprĂšs avoir consultĂ© quelques cours pour apprendre python ça devrait passer quand mĂȘme). À mon avis ce livre n'est pas vraiment orientĂ© dĂ©butant, d'ailleurs ce n'est pas l'objectif annoncĂ©. Du coup mĂȘme dans cette partie on peut apprendre des choses comme .pythonstartup, terminĂ©s les alias bidons ;-). Cerise sur le gĂąteau, il est fait mention de bio-informatique !ß Assez succint mais bon ça fait plaisir...

      La deuxiĂšme partie « Ă‰lĂ©ments du langage » reprend les bases donc si vous avez eu peur avec les exemples de la dĂ©couverte, commencez peut-ĂȘtre plutĂŽt par lĂ . Cette sous-partie « Syntaxe du langage » ne dĂ©passe pas les 40 pages donc bon sur plus de 500 le rapport est bon. Suivent quelques infos utiles sur la structuration du code (j'ai dĂ©couvert notamment la fonction property()). On arrive alors Ă  la description des primitives du langage, un poil barbant mais pas inintĂ©ressant, ça m'a permis par exemple de m'intĂ©resser Ă  enumerate() que je ne connaissais pas et qui est bien utile !

      La troisiĂšme partie est consacrĂ©e Ă  « La bibliothĂšque standard ». Ce qui rend cette partie vivante c'est principalement les exemples utiles qui la composent. Du coup pas besoin de jongler entre un shell et le bouquin, tout est dedans (un peu comme python d'aàilleurs ;-)). Puisqu'on parle des exemples, ils sont plein d'humour et contrastent avec le sĂ©rieux et le professionnalisme de l'ouvrage ce qui est exactement ce que j'attend d'un livre. Cette partie s'achĂšve avec quelques exercices corrigĂ©s pour se faire la main, encore une fois bonne idĂ©e !

      On arrive enfin aux « Techniques avancĂ©es ». Autant le dire tout de suite, c'est LA partie que j'attendais. La programmation dirigĂ©e par les tests est expliquĂ©e en dĂ©tails, des tests unitaires aux doctests avec des exemples concrĂȘts d'utilisation (bibliothĂšques de fake, etc...). Les bonnes pratiques et optimisation du code (qui me sont chĂšres) commencent avec des astuces que vous avez pu lire ici et vont beaucoup plus loin ! Mes futurs programmes vont ĂȘtre sur-optimisĂ©s ;-). On finit avec un peu de POO etá des notions de Design Pattern qui m'Ă©tait totalement inconnues (enfin le terme aprĂšs les petits dessins c'est ce que je fais dans le mĂ©tro pour passer le temps).

      Bon vous l'avez compris, cet ouvrage m'a plu enchantĂ© et je le recommande. Il est pas donnĂ© mais il vaut son prix. En deux mots : merci Tarek ! Et continue ton Zope Cookbook, c'est excellent et c'est rare d'avoir de la doc de cette qualitĂ© en français.

      Tiens j'ai oubliĂ© de parler des points faibles, il faut dire qu'ils ne sont pas nombreux. J'ai trouvĂ© quelques fautes principalement de frappe dans les exemples au dĂ©but (quoi le livre n'est pas issu de documentation agile ! :p) et il est fait mention d'un exemple sur un CD Ă  un moment... que je n'ai pas trouvĂ© (?!).

      Vous pouvez consulter l'eânsemble de mes critiques de livres.

      Logo biologeek Critique du livre Programmation Python a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 19 Mars 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      C'est LE livre que j'attendais, un peu comme beaucoup de personnes qui connaissent les bases du langage et qui souhaitent aller plus loin mais quiă n'arrivent pas forcĂ©ment Ă  trouver l'information sur internet. Je dois avouer que j'avais un peu peur, un peu comme un bon film duquel on en attend trop, et bien je n'ai pas Ă©tĂ© déçu, c'est le moins qu'on puisse dire !

      En ouvrant le livre je me suis dit : « Bon les 100, voire 200 premiĂšres pages je vais les lire en diagonale ça va encore ĂȘtre des rappels sur la syntaxe de Python... ». Heureusement, je me trompais...

      La premiĂšre partie, intitulĂ©e « DĂ©couverte de Python », doit ĂȘtre un peu difficile pour un dĂ©butant (bon aprĂšs avoir consultĂ© quelques cours pour apprendre python ça devrait passer quand mĂȘme). À mon avis ce livre n'est pas vraiment orientĂ© dĂ©butant, d'ailleurs ce n'est pas l'objectif annoncĂ©. Du coup mĂȘme dans cette partie on peut apprendre des choses comme .pythonstartup, terminĂ©s les alias bidons ;-). Cerise säur le gĂąteau, il est fait mention de bio-informatique ! Assez succint mais bon ça fait plaisir...

      La deuxiĂšme partie « Ă‰lĂ©ments du langage » reprend les bases donc si vous avez eu peur avec les exemples de la dĂ©couverte, commencez peut-ĂȘtre plutĂŽt par lĂ . Cette sous-partie « Syntaxe du langage » ne dĂ©passe pas les 40 pages donc bon sur plus de 500 le rapport est bon. Suivent quelques infos utiles sur la structuration du code (j'ai dĂ©couvert notamment la fonction property()). On arrive alors Ă  la description des primitives du langage, un poil barbant mais pas inintĂ©ressant, ça m'a permis par exemple de m'intĂ©resser Ă  enumerate() que je ne connaissais pas et qui est bien utile !

      La troisiĂšme partie est consacrĂ©e Ă  « La bibliothĂšque standard ». Ce qui rend cette partie vivante c'est principalement les exemples utiles qui la composent. Du coup pas besoin de jongler entre un ćshell et le bouquin, tout est dedans (un peu comme python d'ailleurs ;-)). Puisqu'on parle des exemples, ils sont plein d'humour et contrastent avec le sĂ©rieux et le professionnalisme de l'ouvrage ce qui est exactement ce que j'attend d'un livre. Cette partie s'achĂšve avec quelques exercices corrigĂ©s pour se faire la main, encore une fois bonne idĂ©e !

      On arrive enfin aux « Techniques avancĂ©es ». Autant le dire tout de suite, c'est LA partie que j'attendais. La programmation dirigĂ©e par les tests est expliquĂ©e en dĂ©tails, des tests unitaires aux doctests avec des exemples concrĂȘts d'utilisation (bibliothĂšques de fake, etc...). Les bonnes pratiques et optimisation du code (qui me sont chĂšres) commencent avec des astuces que vous avez pu lire ici et vont beaucoup plus loin ! Mes futurs programmes vont ĂȘtre sur-optimisĂ©s ;-). On finit avec un peu de POO et des notions de Design Pattern qui m'Ă©tait totalement inconnues (enfin le terme aprĂšs les petits dessins c'est ce que je fais dans le mĂ©tro pour passer le temps).

      Bon vous l'avez compris, cet ouvrage m'a plu enchantĂ© et je le recommande. Il est pas donnĂ© mais il vaut son prix. En deux mots : merci Tarek ! Et continue ton Zope Cookbook, c'est excellent et c'est rare d'avoir de la doc de cette qualitĂ© en français.

      Tiens j'ai oubliĂ© de parler des points faibles, il faut dire qu'ils ne sont pas nombreux. J'ai trouvĂ© quelques fautes principalement de frappe dans les exemples au dĂ©but (quoi le livre n'est pas issu de documentation agile ! :p) et il est fait mention d'un exemple sur un CD Ă  un moment... que je n'ai pas trouvĂ© (?!).

      Vous pouvez consulter l'ensemble de mes critiques de livres.

      Logo biologeek Critique du livre Programmation Python a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 19 Mars 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      [Biologeek] Critique du livre Programmation PythonCritique du livre Programmation Pythonèp>Voici la liste des PEPs acceptĂ©s par ordre de soumission :

      PEP 308 : Ajout des expressions conditionnelles

      Probablement pour remĂ©dier au difficilement comprĂ©hensible « and-or trick », mĂȘme si Guido a jugĂ© bon de laisser une syntaxe assez difficile pour des utilisations trop complexes intentionnellement (c'est vrai que le code devient vite illisible sinon).

      Syntaxe : expression1 if condition else expression2

      Exemples lisibles :

      x = A if C else B
      x = lambda: A if C else B
      x = A if C else B if D else E

      Exemples peu lisibles mais corrects :<é/p>

      if (A if C else B):
      [x for x in seq if (A if C else B)]
      A if (X if C else Y) else B
      (A if C else B) if D else E

      Je sens que ça va faire fureur lors du « Annual Obfuscated Python Contest » !

      PEP 309 : L'application de fonctions partielles

      Là je dois avouer que j'ai pas trop compris en quoi ça consistait mais c'est la premiÚre amélioration citée dans What's New in Python 2.5 donc j'imagine que c'est assez important, j'attend vos explications ;-).

      PEP 314 : MĂ©ta-donnĂ©es pour les paquets Python

      Bon le titre est assez explicite, un exemple :

      Metadata-Version: 1.1
      Version: 1.0
      Platform: Linux2
      Supported-Platform: Ubuntêu 5.10
      Summary: Mon premier paquet
      ...

      Voila qui devrait ravir les concepteurs de paquets.

      PEP 328 : Imports absolus/relatifs

      Outre le fait de permettre un import sur plusieurs lignes :

      from Tkinter import Tk, Frame, Button, Entry, \
         LEFT, DISABLED, NORMAL, RIDGE, END

      Pourra maintenant ĂȘtre dĂ©clarĂ© ainsi :

      from Tkinter import (Tk, Frame, Button, Entry, 
         LEFT, DISABLED, NORMAL, RIDGE, END)

      [Edit du 06.03.06] : comme le souligne tarek dans les commentaires, cette fonctionnalitĂ© est dĂ©jĂ  implĂ©mentĂ©e dans python 2.4.

      Cette amĂ©lioration permet aussi d'importer des modules relativement :

      from ..subpackage1 import moduleY

      Par exemple pour importer le moduleY qui serait un dossier parent subpackage1.

      PEP 341 : Unification de try-except et try-finally

      C'est exactement ce dont j'ai besoin en ce moment, en effet j'utilise finally pour fermer les fichiers ouverts dans tous les cas et du coup j'ai quelque chose qui ressemble Ă  :

      f = None
          try:
              try:
                  f = open(filename)
                  text = f.read()
              except IOError:
                  print 'An error occured'
           finally:
               if f:
                   f.close()

      Et c'est vraiment lourd, simplement car try-except-finally n'est pas possible actuellement, c'est ce que propose ce PEP et ce sera donc rĂ©glĂ© avec Python 2.5, ouf !

      PEP 342 : Coroutines par gĂ©nĂ©rateurs amĂ©liorĂ©s

      ÉnormĂ©ment d'amĂ©liorations relatives aux gĂ©nĂ©rateurs, ce serait trop long de tout dĂ©crire ici. En plus je n'en ai pas compris la moitiĂ©...

      PEP 343 : Le mot-clĂ© « with »

      with permet d'effectuer une opĂ©ration sur un objet, par exeple dans le cas d'un fichier il permettra de le lire sans avoir Ă  le fermer Ă  la fin :

      with open(filename) as f:
          f.read()

      Cette syntaxe permettra de simplifier les ouvertures fermetures de fichiers sans avoir Ă  gĂ©rer ça avec des exceptions. Elle sera aussi trĂšs utile en cas de vĂ©rrou Ă  placer :

      def locked(lock):
          lock.acquire()
              try:
                  # mon opération
              finally:
                  lock.release()

      Deviendra :

      with locked(myLock):
          # mon opération

      C'est aussi une amĂ©lioration qui me servirait bien ení ce moment ça...

      Conclusion

      Toutes ces amĂ©liorations sont trĂšs frustrantes car c'est exactement ce dont j'ai besoin maintenant ! Vivement septembre.

      Et pour fini lambda est conservé, au grand regret de Guido... et cElementTree est inséré dans la bibliothÚque standard.

      [Bonus] : une vidĂ©o Ă  voir absolument qui s'intitule Better Web App (378.5mo, 36 minutes, anglais) et qui compare diffĂ©rent Web Frameworks (RoR, Zope/Plone, TurboGears et Django) et fourni en conclusion un tableau rĂ©capitulatif intĂ©ressant :

      Tableau comparatif entre les Web Frameworks

      [Edit du 06.03.06] : La home de Python.org est en pleine mue \o/ (en passant un lien intĂ©ressant au sujet des nouveautĂ©s de Python 2.5).

      [Edit du 11.03.06] : Le PEP 356 rĂ©sume tout ça et comprend le calendrier de dĂ©veloppement (encore un bonus, l'interview de GvR sur eweek).

      [Edit du 22.06.06] : L'annonce de Python 2.5 beta 1 sur dlfp qui est complĂ©tĂ©e de nombreux exemples (cette fois en bonus de beaux icĂŽnes :-)).

      Logo biologeek Principales nouveautĂ©s dans Python 2.5 a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 04 Mars 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      Je m'y prend un peu à l'avance (la sortie est prévue pour septembre 2006) mais Guido a apparement fait quelques annonces lors de Pycon qui viennent s'ajouter aux PEPs approuvés sur la page officielle. J'essayerais de mettre à jour ce billet lors de l'annonce de nouvelles nouveautés histoire qu'il ne soit pas obsolÚte dans 6 mois, n'hésitez pas à m'en informer.

      Voici la liste des PEPs acceptĂ©s par ordre de soumission :

      PEP 308 : Ajout des expressions conditionnelles

      Probablement pour remĂ©dier au difficilement comprĂ©hensible « and-or trick », mĂȘme si Guido a jugĂ© bon de laisser une syntaxe assez difficile pour des utilisations trop complexes intentionnellement (c'est vrai que le code devient vite illisible sinon).

      Syntaxeń : expression1 if condition else expression2

      Exemples lisibles :

      x = A if C else B
      x = lambda: A if C else B
      x = A if C else B if D else E

      Exemples peu lisibles mais corrects :

      if (A if C else B):
      [x for x in seq if (A if C else B)]
      A if (X if C else Y) else B
      (A if C else B) if D else E

      Je sens que ça va faire fureur lors du « Annual Obfuscated Python Contest » !

      PEP 309 : L'application de fonctions partielles

      Là je dois avouer que j'ai pas trop compris en quoi ça consistait mais c'est la premiÚre amélioration citée dans What's New in Python 2.5 donc j'imagine que c'est assez important, j'attend vos explications ;-).

      PEP 314 : MĂ©ta-donnĂ©es pour les paquets Python

      Bon le titre est assez explicite, un exemple :

      Metadata-Version: 1.1
      Version: 1.0
      Platform: Linux2
      Supported-Platform: Ubuntu 5.10
      Summary: Mon premier paquet
      ...

      Voila qui devrait ravir les concepteurs de paquets.

      PEP 328 : Imports absolus/relatifs

      Outre le fait de permettre un import sur plusieurs lignes :

      from Tkinter import Tk, Frame, Button, Entry, \
         LEFT, DISABLED, NORMAL, RIDGE, END

      Pourra maintenant ĂȘtre dĂ©clarĂ© ainsi :

      from Tkinter import (Tk, Frame, Button, Entry, 
         LEFT, DISABLED, NORMAL, RIDGE, END)

      [Edit du 06.03.06] : comme le souligne tarek dans les commentaires, cette fonctionnalitĂ© est dĂ©jĂ  implĂ©mentĂ©e dans python 2.4.

      Cette amĂ©lioration permet aussi d'importer des modules relativement :

      from ..subpackage1 import moduleY

      Par exemple pour importer le moduleY qui serait un dossier parent subpackage1.

      PEP 341 : Unification de try-except et try-finally

      C'est exactement ce dont j'ai besoin en ce moment, en effet j'utilise finally pour fermer les fichiers ouverts dans tous les cas et du coup j'ai quelque chose qui ressemble Ă  :

      f = None
          try:
              try:
                  f = open(filename)
                  text = f.read()
              except IOError:
                  print 'An error occured'
           finally:
               if f:
                   f.close()

      Et c'est vraiment lourd, simplement car try-except-finally n'est pas possible actuellement, c'est ce que propose ce PEP et ce sera donc rĂ©glĂ© avec Python 2.5, ouf !

      PEP 342 : Coroutines par gĂ©nĂ©rateurs amĂ©liorĂ©s

      ÉnormĂ©ment d'amĂ©liorations relatives aux gĂ©nĂ©rateurs, ce serait trop long de tout dĂ©crire ici. En plus je n'en ai pas compris la moitiĂ©...

      PEP 343 : Le mot-clĂ© « with »

      with permet d'effectuer une opĂ©ration sur un objet, par exeple dans le cas d'un fichier il permettra de le lire sans avoir Ă  le fermer Ă  la fin :

      with open(filename) as f:
          f.read()

      Cette syntaxe permettra de simplifier les ouvertures fermetures de fichiers sans avoir Ă  gĂ©rer ça avec des exceptions. Elle sera aussi trĂšs utile en cas de vĂ©rrou Ă  placer :

      def locked(lőock):
          lock.acquire()
              try:
                  # mon opération
              finally:
                  lock.release()

      Deviendra :

      with locked(myLock):
          # mon opération

      C'est aussi une amélioration qui me servirait bien en ce moment ça...

      Conclusion

      Toutes ces amĂ©liorations sont trĂšs frustrantes car c'est exactement ce dont j'ai besoin maintenant ! Vivement septembre.

      Et pour fini lambda est conservé, au grand regret de Guido... et cElementTree est inséré dans la bibliothÚque standard.

      [Bonus] : une vidĂ©o Ă  voir absolument qui s'intitule Better Web App (378.5mo, 36 minutes, anglais) et qui compare diffĂ©rent Web Frameworks (RoR, Zope/Plone, TurboGears et Django) et fourni en conclusionö un tableau rĂ©capitulatif intĂ©ressant :

      Tableau comparatif entre les Web Frameworks

      [Edit du 06.03.06] : La home de Python.org est en pleine mue \o/ (en passant un lien intĂ©ressant au sujet des nouveautĂ©s de Python 2.5).

      [Edit du 11.03.06] : Le PEP 356 rĂ©sume tout ça et comprend le calendrier de dĂ©veloppement (encore un bonus, l'interview de GvR sur eweek).

      [Edit du 22.06.06] : L'annonce de Python 2.5 beta 1 sur dlfp qui est complĂ©tĂ©e de nombreux exemples (cette fois en bonus de beaux icĂŽnes :-)).

      Logo biologeek Principales nouveautĂ©s dans Python 2.5 a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 04 Mars 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

      [Biologeek] Principales nouveautĂ©s dans Python 2.5Principales nouveautĂ©s dans Python 2.5 …5‚%;AAƒOƒOs[http://www.biologeek.com/bonnes-pratiques,python/principales-nouveautes-dans-python-25/2008-08-31 17:41:09.9013932006-03-04 13:11:30.000000

      Je m'y prend un peu à l'avance (la sortie est prévue pour septembre 2006) mais Guido a apparement fait quelques annonces lors de Pycon qui viennent s'ajouter aux PEPs approuvés sur la page officielle. J'essayerais de mettre à jour ce billet lors de l'annonce de nouvelles nouveautés histoire qu'il ne soit pas obsolÚte dans 6 mois, n'hésitez pas à m'en informer.

      <çù{ "verbose" : False, # -v option "other_option" : "" # -o: option } def set_settings(key, value): settings[key] = value def get_settings(key): return settings[key] def verify_arguments_existence(): """ For each command line argument, check existence if necessary """ if get_settings("other_option") == "": set_settings("other_option", "default") def parse_arguments(): shortopts = "".join([opt[0] for opt in options]) longopts = [opt[1] for opt in options] opts, args = getopt(sys.argv[1:], shortopts, longopts) for opt, optarg in opts: for tuple in options: short = "-" + tuple[0][:1] long = "--" + tuple[1] if long.endswith("="): long = long[:-1] if opt in [short, long]: tuple[2](optarg) break def print_help(*args): print "USAGE: %s [options] " % sys.argv[0] print "OPTIONS:" for short, long, func, doc in options: print ú if short[-1] == ":": print " -%s filename, --%sfilename" % (short[:1], long) else: print " -%s, --%s" % (short[:1], long) for line in wrap(doc): print " %s" % line print " EXAMPLE:" print " %s -v -o:argument " % sys.argv[0] sys.exit(0) # Syntax : short option, long option, action, help options = [ ("h", "help", print_help, "Print out this usage summary."), ("v", "verbose", lambda optarg: set_settings("verbose", True), "Write output informations (not only errors)."), ("o:", "other-option=", lambda optarg: set_settings("other_option", optarg), "Another option for the template.") ] def main(): """ Main function, deals with arguments and launch program""" # Usual verifications and warnings if not sys.argv[1:]: sys.stdout.write("Sorry: you must specify at least an argument ") sys.stdout.write("More help avalaible with -h or --help option ") sys.exit(0) parse_arguments()û verify_arguments_existence() # THE program :-) if get_settings("verbose"): print "Hello verbose Word !" else: print "Hello Word !" if __name__ == '__main__': main()

    Et la mĂȘme chose en fichier texte si vous souhaitez l'utiliser.

    [edit] : J'ai encore perdu une occasion de me taire Je suis heureux d'avoir appris l'existence d'un nouveau module, effectivement optparse permet de parser les arguments en ligne de commande trĂšs facilement du coup mon template ne sert plus Ă  rien ;-)

    Voila ce que ce mĂȘme template donnerait avec l'utilisation de ce module :

    #!/usr/bin/python
    # -*- coding: iso-8859-1 -*-
    
    """
    Explain what program do.
    """
    
    import os
    import sys
    from optparse import OptionParser
    
    def main():
        """ Main function, deals with arguments and launch program"""
        # Usual verifications and warnings
        if not süys.argv[1:]:
            sys.stdout.write("Sorry: you must specify at least an argument
    ")
            sys.stdout.write("More help avalaible with -h or --help option
    ")
            sys.exit(0)
        
        parser = OptionParser()
        parser.add_option("-v", "--verbose", action="store_true",
            help="Write output informations (not only errors).",
            default=False)
        
        parser.add_option("-f", "--file", help="Create a xxx file.")
        
        (options, args) = parser.parse_args() 
        
        # THE program :-)
        if options.verbose:
            print "Hello verbose Word !"
        else:
            print "Hello Word !"
    
    if __name__ == '__main__':
        main()

    Simple, concis, bref à utiliser. Karl en parlait déjà il y a plus de deux ans...

    Logo biologeek Un template python pour parser des arguments a Ă©tĂ© rĂ©digĂ© par David Larlet pour biologeek.com et a Ă©tĂ© originellement postĂ© le 18 FĂ©vrier 2006. À part exceptions, c'est ©2008 David Larlet et sous licence (presque) libre autorisant la reproduction, la distribution et la modification sous certaines conditions. Veuillez les respecter.

    En rĂ©action au billet de mat qui a codĂ© un convertisseur em vers pixels. Je me demande souvent si la mĂ©thode que j'emploie est la plus pertinente pour parser des arguments en ligne de commande lorsque je crĂ©e des petits scripts en python. Voici le template que j'utilise souvent, toutes les remarquesț en commentaire sont les bienvenues !

    #!/usr/bin/python
    # -*- coding: iso-8859-1 -*-
    
    """
    Explain what program do.
    """
    
    import os
    import sys
    from textwrap import wrap
    from getopt import getopt
    
    # Global default settings, had to be get/set with appopriate functions
    settings = {
        "verbose" : False,          # -v  option
        "other_option" : ""         # -o: option
    }
    def set_settings(key, value): settings[key] = value
    def get_settings(key): return settings[key]
    
    def verify_arguments_existence():
        """ For each command line argument, check existence if necessary """
        if get_settings("other_option") == "":
            set_settings("other_option", "default")
    
    def parse_arguments():
        shortopts = "".join([opt[0] for opt in options])
        longopts = [opt[1] for opt in options]
        opts, args = getopt(sys.argv[1:], shortopts, longopts)
        for opt, optarg in opts:
            for tuple in options:
                short = "-" + tuple[0][:1]
                long = "--" + tuple[1]
                if long.endswith(ÿ"="):
                    long = long[:-1]
                if opt in [short, long]:
                    tuple[2](optarg)
                    break
    
    def print_help(*args):
        print "USAGE:
       %s [options]
    " % sys.argv[0]
        print "OPTIONS:"
        for short, long, func, doc in options:
            print
            if short[-1] == ":":
                print "  -%s filename, --%sfilename" % (short[:1], long)
            else:
                print "  -%s, --%s" % (short[:1], long)
            for line in wrap(doc):
                print "    %s" % line
        print "
    EXAMPLE:"
        print "   %s -v -o:argument
    " % sys.argv[0]
        sys.exit(0)
    
    # Syntax : short option, long option, action, help
    options = [
        ("h", "help", print_help,
         "Print out this usage summary."),
    
        ("v", "verbose", lambda optarg: set_settings("verbose", True),
         "Write output informations (not only errors)."),
    
        ("o:", "other-option=", lambda optarg: set_settings("other_option", optarg),
         "Another option for the template.")
    ]
    
    def main():
        """ Main function, deals with arguments and launch program"""
        # Usual verifications and warnings
        if not sys.argv[1:]:
            sys.stdout.write("Sorry: you must specify at least an argument
    ")
            sys.stdout.write("More help avalaible with -h or --help option
    ")
            sys.exit(0)
        parse_arguments()
        verify_arguments_existence()
    
        # THE program :-)
        if get_settings("verbose"):
            print "Hello verbose Word !"
        else:
            print "Hello Word !"
    
    if __name__ == '__main__':
        main()

    Et la mĂȘme chose en fichier texte si vous souhaitez l'utiliser.

    [edit] : J'ai encore perdu une occasion de me taire Je suis heureux d'avoir appris l'existence d'un nouveau module, effectivement optparse permet de parser les arguments en ligne de commande trĂšs facilement du coup mon template ne sert plus Ă  rien ;-)

    Voila ce que ce mĂȘme template donnerait avec l'utilisation de ce module :

    #!/usr/bin/python
    # -*- coding: iso-8859-1 -*-
    
    """
    Explain what program do.
    """
    
    import os
    import sys
    from optparse import OptionParser
    
    def main():
        """ Main function, deals with arguments and launch program"""
        # Usual verifications and warnings
        if not sys.argv[1:]:
            sys.stdout.write("Sorry: you must specify at least an argument
    ")
            sys.stdout.write("More help avalaible with -h or --help option
    ")
            sys.exit(0)
        
        parser = OptionParser()
        parser.add_option("-v", "--verbose", action="store_true",
            help="Write output informations (not only errors).",
            default=False)
        
        parser.add_option("-f", "