Fantomas' side - Articles pour le tag pythonhttps://blog.fantomas.site/blog/tags/python/Les derniers articles taggés sous pythonfrCopyright (c) 2005-2018, Julien FacheTue, 02 Jan 2018 14:45:39 +0000Veliberator is alive https://blog.fantomas.site/blog/2015/03/18/veliberator-alive/ <img src="/media/cache/81/d8/81d82d0abd1cd34e9ef24554f4f07cb7.jpg" alt="Veliberator is alive" /> <p>Il y a quelques jours, j'ai décidé de mettre à jour le code de <a href="https://github.com/Fantomas42/veliberator">veliberator</a>, l'API qui me sert à récupérer en direct les informations du réseau Vélib'. Je vous en avais déjà parlé lors d'un <a href="http://fantomas.willbreak.it/blog/2009/09/24/le-temps-des-releases-veliberator/">article précèdent</a> en 2009.</p><p>Donc après avoir fini la mise à jour de 2015, je me suis demandé à quel point il était compliqué d'en faire un robot pour <a href="http://fr.wikipedia.org/wiki/Internet_Relay_Chat">IRC</a>, une vieille idée qui me trottait en tête depuis longtemps.</p><p>Or après quelques recherches il est assez simple de faire un bot IRC, grâce à la <a href="https://pypi.python.org/pypi/irc">librairie irc pour Python</a>. Un module étant même fourni spécifiquement pour écrire ce genre de robot.</p><p>Malgré une documentation éparse, j'ai pu en quelques heures mettre sur pied une version IRC de veliberator me permettant de trouver les stations libres les plus proches.</p><p>Pour rencontrer veliberator le robot, connectez-vous sur <a href="irc://irc.freenode.net/#velib">irc.freenode.net/#velib</a> et écrivez une des choses suivantes:</p><blockquote><p>veliberator, status 42001<br />veliberator, address tour eiffel<br />veliberator, help</p></blockquote><p>Quand c'est facile et utile, le développement devient plus qu'un plaisir.</p> fantomas42@gmail.com (fantomas)Wed, 18 Mar 2015 19:11:41 +0000https://blog.fantomas.site/blog/2015/03/18/veliberator-alive/DéveloppementLa face cachée du Sudoku https://blog.fantomas.site/blog/2011/10/11/la-face-cachee-du-sudoku/ <img src="/media/cache/6f/85/6f85967bc7fc45ed3dc82e56fa667bd7.jpg" alt="La face cachée du Sudoku" /> <h1>Introduction</h1><p>Tout commence un soir entre amis, où une envie démente de coder un petit projet nous surprend entre 2 bières. :D</p><p>Lui vient du monde Java, moi du Python, mais ayant subi la même formation, le moment fût propice pour comparer nos progrès et évolutions et aussi lancer un troll ou deux.</p><p>Ensuite nous vient l'idée de programmer un résolveur universel de <a title="Le Sudoku sur Wikipedia" href="http://fr.wikipedia.org/wiki/Sudoku">Sudoku</a>, ayant quelques connaissances de base à propos de ce jeu, j'imagine dans les grandes lignes un algorithme pour résoudre ce genre de puzzles...</p><p>L'idée générale du programme est d'appliquer de manière séquentielle les 2 ou 3 stratégies de résolutions que j'utilise moi même quand je fais un Sudoku tiré d'un magazine...</p><h1>Passage à l'acte</h1><p>Rapidement j'obtiens un résultat, mais se pose le problème de la difficulté. En effet, les grilles disponibles dans les magazines sont classées par difficulté croissante, or <a title="Classification des grilles de Sudoku" href="http://www.le-sudoku.fr/le-sudoku/classification">cette difficulté est toute relative</a>.</p><p>En effet seul le nombre de <a title="Les différentes techniques du Sudoku" href="http://www.mots-croises.ch/Manuels/Sudoku/technique.htm">techniques de résolutions</a> nécessaires (en général 3 ou 4) à un puzzle conditionne le niveau de difficulté. A savoir qu'il existe de techniques très complexes pour résoudre certaines grilles de Sudoku, mais il ne sera jamais nécessaire même à un niveau dit "<em>Diabolique</em>" de les maîtriser. Seules les techniques élémentaires seront nécessaire pour 95% des grilles publiées.</p><p>Mais concernant les 5% restant, là cela devient beaucoup plus complexe, car après plusieurs heures de recherches et de compréhension de ces techniques, je décide d'en implémenter certaines dans le résolveur pour augmenter ses chances de résolution. </p><p>Mais le problème reste entier, même si j'augmente le nombre d'algorithmes de résolution, si je tombe sur un cas que je n'ai pas prévu, je ne peux pas résoudre complètement la grille. En effet, le programme n'est pas capable d'improviser une solution ou d'échafauder une hypothèse qui lui permettrait de se sortir de ce cas imprévu.</p><p>A la suite de cette série d'échecs, je décide d'implémenter un algorithme de résolution basé sur le <a title="BackTracking sur Wikipedia" href="http://fr.wikipedia.org/wiki/Retour_sur_trace">backtracking</a>, solution qui me convient beaucoup mieux car le taux de résolution des puzzles est de 100%, mais insatisfaisante car elle ne permet pas d'expliquer la solution et le temps de résolution d'un puzzle est peu prédicable et très fluctuant.</p><h1>Réflexions</h1><p>En guise de conclusion à cette immersion dans le monde du Sudoku qui s'est révélée au final bien plus riche qu'il ne le semblait aux premiers abords, j'ai appris une belle leçon en matière de programmation et surtout d'algorithmique. </p><p>En effet mimer la façon de penser d'un homme pour résoudre certains problèmes de programmation peut parfois se révéler intéressant et source de solutions, mais il ne faut pas oublier que l'on traite avec une machine. <br />Une machine n'a pas la capacité d'innovation ou d'évolution face à un problème non identifié, par contre elle est capable de retenir des millions d'informations et de les traiter beaucoup plus rapidement que n'importe quel humain et ça, c'est un avantage indéniable.</p><p>Même si un humain peut utiliser la technique du <em>Backtracking</em> (appelé aussi <a title="Nishio et Sudoku" href="http://www.mots-croises.ch/Manuels/Sudoku/Nishio.htm">Nishio</a>) pour résoudre sa grille, il mettra un temps phénoménal mais il n'y arrivera que s'il est très rigoureux et ce n'est pas du tout ludique.</p><p>Par contre pour une machine, la donne s'inverse, la machine est rigoureusement rigoureuse et peut faire tous ces calculs très rapidement.</p><p>Pour conclure, même si un humain et une machine peuvent plus ou moins faire la même chose, il ne faut jamais oublier de prendre en compte les points forts et points faibles de l'un et de l'autre dans la conception d'un algorithme.</p><h1>Résultats</h1><p>Le résultat de toute ces expériences est disponible sur PyPI sous le nom de <a title="Mon solveur de sudoku sur PyPI" href="http://pypi.python.org/pypi/sudoku-solver">sudoku-solver</a>.</p><pre>$ easy_install sudoku-solver $ sudoku_solver votre_grille.txt</pre><p>Vous pouvez éventuellement contribuer sur la page Github du projet à l'adresse suivante : <a title="Sudoku Solver sur Github" href="https://github.com/Fantomas42/sudoku-solver">https://github.com/Fantomas42/sudoku-solver</a></p><p>Et pour terminer, je n'ai pas pu m'empêcher de réaliser une démo web de ma librairie sous le framework Django. Donc si vous voulez résoudre ou vérifier vos grilles de Sudoku, allez à cette adresse : <a title="Résolvez vos puzzles de Sudoku en ligne" href="http://sudoku.willbreak.it/">http://sudoku.willbreak.it/</a></p><p>Bon puzzles !</p> fantomas42@gmail.com (fantomas)Tue, 11 Oct 2011 16:49:56 +0000https://blog.fantomas.site/blog/2011/10/11/la-face-cachee-du-sudoku/DécouvertesDéveloppementExpériencesLe temps des releases : easy_extract https://blog.fantomas.site/blog/2010/01/19/le-temps-des-releases-easy-extract/ <img src="/media/cache/9a/c2/9ac2da5d13ce19a88cda6c86704d1127.jpg" alt="Le temps des releases : easy_extract" /> <p>Imaginons que j'ai sur un serveur de donnée une grosse quantité d'archives sous différents formats, tel que RAR, ZIP, XTM... </p><p>Si je souhaite extraire toutes ces archives, je devrais aller trouver chaque archives dans son répertoire, taper la bonne commande pour pouvoir les extraire, les réparer au besoin et ainsi de suite... Plutôt fastidieux non ? :(</p><p>Sur ce constat m'est venu l'idée de <strong>easy_extract</strong>, un script écrit en Python qui va analyser récursivement les répertoires à la recherche d'archives ou de collections d'archives pour les extraire et les réparer automatiquement si elles sont corrompues.</p><p>Pour cela, il suffit de lancer le script de la manière suivante par exemple :</p><pre>$ easy_extract -r mes_archives/</pre><p>Pratique et le gain de temps est évident, car une fois le script lancé, vous n'avez plus à vérifier que l'extraction s'est bien déroulée pour ensuite passer à la suivante, donc a scotcher devant votre terminal. Victoire une tâche fastidieuse de plus automatisée. :D</p><p>Pour l'installation, il est nécessaire d'installer les paquets suivant avant :</p><ul><li>par2</li><li>unrar-free</li><li>7zip-full</li></ul><p>Ensuite l'installation du script se fait grâce à easy_install :</p><pre>$ easy_install easy_extract</pre><p>Bien sûr le code est open-source, donc si vous voulez contribuer, forker ou juste critiquer, le code se trouve à l'adresse suivante : <a title="Source de easy_extract" href="http://github.com/Fantomas42/easy-extract">http://github.com/Fantomas42/easy-extract</a></p><p>Bonne décompression et bon leech.</p> fantomas42@gmail.com (fantomas)Tue, 19 Jan 2010 10:47:56 +0000https://blog.fantomas.site/blog/2010/01/19/le-temps-des-releases-easy-extract/DéveloppementLe temps des releases : Vélib'erator https://blog.fantomas.site/blog/2009/09/24/le-temps-des-releases-veliberator/ <img src="/media/cache/62/ea/62ea6a9ad14f0fac4c578fa52f8b552b.jpg" alt="Le temps des releases : Vélib&#39;erator" /> <p>Suite à mon abonnement à <a title="Vélib" href="http://velib.paris.fr/">Vélib'</a>, habitant près d'une station récemment construite, j'ai vite remarqué que de trouver un vélo en bon état ou une place de parking à proximité avant les 30 minutes fatidiques et payantes pouvait vite devenir un calvaire.</p><p>Sur ce, après quelques recherches,&#160; j'ai pu constater que les informations sur l'état des stations du réseau Vélib' étaient librement accessibles. D'où l'idée de créer un paquet python nommé <a title="Sources du paquet python Veliberator" href="http://pypi.python.org/pypi/veliberator/">Veliberator</a>, me permettant depuis mon shell de consulter l'état de mes stations favorites.</p><p>Pour les fans de la ligne de commande, essayez ceci :</p><pre>$ sudo easy_install veliberator $ sudo synchronize.py $ find_place.py 42008</pre><p>Partant de là, je me dis qu'il serait dommage de m'arrêter à ce stade du développement, d'autant plus que mon problème pour trouver une place libre rapidement ne se résous que depuis mon ordinateur, il faudrait donc que ce service soit accessible partout et pour tout le monde.</p><p>Un site web semble être la solution idéale, d'autant plus si on est capable d'optimiser l'affichage des pages au type de support, par exemple un mobile.</p><p>Equipé de mon module python et de Django, j'ai donc réalisé le site <a title="Vélib'erator la libération des stations Vélib'." href="http://veliberator.com">http://veliberator.com</a>.</p><p>Au programme du site :</p><ul><li>Consultation des <a title="Station Vélib' 42008" href="http://veliberator.com/42008">statuts des stations Vélib'</a>.</li><li>Affichage des stations aux alentours.</li><li>Affichage des <a title="Stations Vélib près de la Tour Eiffel." href="http://veliberator.com/lieux/monument/tour-eiffel/">lieux importants</a> près des stations.</li><li><a title="Flux RSS de la station 12002 et des alentours." href="http://veliberator.com/rss/around/12002">Flux RSS</a> pour monitorer le statut des stations.</li><li>Vues par <a title="Stations Vélib' de Saint Mandé" href="http://veliberator.com/ville/94160/">ville</a>, départements, statut, adresse.</li><li><a title="Statistiques du réseau Vélib'" href="http://veliberator.com/stats/">Statistiques</a> du réseau Vélib'.</li><li>Recherche par : adresse, métro, monument, code postal, coordonnées GPS.</li><li>Calcul des distances.</li><li>Traçage d'<a title="Itinéraire entre la station 42008 et 12001" href="http://veliberator.com/route/42008/12001">itinéraires</a> entre stations Vélib'.</li><li>Gestion de favoris.</li><li>Interfaces claires et unifiées.</li><li>Cartes détaillées et en <a title="Vue plein écran !" href="http://maps.veliberator.com/13053/">plein écran</a>.</li><li>Géo-localisation automatique.</li><li>Internationalisation </li><li>Support pour les téléphones <a title="Vélib'erator version iPhone et mobile." href="http://m.veliberator.com">mobiles et iPhone</a>.</li><li>Support pour les Télésites Freebox.</li></ul><p>En effet le site tourne sous plusieurs versions, chacune adaptées à son environnement d'affichage, et à tout moment je peux consulter ces informations.</p><p>Dans mon cas, quand je rentre du travail en Vélib' et qu'il n'y a plus de place en bas de chez moi, je sais directement où aller pour trouver une place libre, sur mon téléphone. Adieu les rondes au hasard à la recherche d'une place libre... Merci Vélib'erator ! :D</p><p>Si vous avez des suggestions, je suis ouvert à toutes propositions d'amélioration.</p><p><a title="Vélib'erator.com" href="http://veliberator.com">http://veliberator.com</a></p><p><a title="Vélib'erator version mobile" href="http://m.veliberator.com">http://m.veliberator.com</a></p><p><em><strong>Edit 30 septembre 2009</strong> : Suite à un email provenant de la société JCDecaux, je me vois dans l'obligation de ne plus utiliser leurs données sur les stations vélib selon les articles L. 112-3 al 2 et L.341-1 du code de la propriété intellectuelle. Données qui sont pourtant accessible publiquement... A priori, avec Vélib, il vaut mieux éviter les initiatives personnelles.</em></p> fantomas42@gmail.com (fantomas)Thu, 24 Sep 2009 14:16:23 +0000https://blog.fantomas.site/blog/2009/09/24/le-temps-des-releases-veliberator/DécouvertesDéveloppementPaye ta Fabric ! https://blog.fantomas.site/blog/2009/05/01/paye-ta-fabric/ <img src="/media/cache/19/68/19684b55d03204bbf3823f2bddca5621.jpg" alt="Paye ta Fabric !" /> <p>Le déploiement d'applications, c'est pas toujours facile et rébarbatif surtout quand on travaille sur un parc de machines.</p><p>Imaginons que j'utilise un serveur de version, du genre <em>Subversion</em> ou <em>Mercurial</em> et que j'utilise un ou deux serveurs (test, production 1, production 2, ...) pour héberger mon ou mes applications.</p><p>Le déroulement est le suivant :</p><ul><li>Développement en local. </li><li>Propagation des modifications.</li><li>Connection SSH sur les serveurs.</li><li>Rapatriement les dernières modifications</li><li>On redémarre le soft.</li></ul><p>Vous me direz que cela n'est pas forcément très long, mais quand vous devez le faire souvent et plusieurs fois par jour, on en a vite pleins le dos et cela est <strong>source d'erreur</strong>.</p><p>Heureusement l'informatique étant un sport où celui qui est le plus fainéant gagne, il existe un solution pour se simplifier ces tâches de déploiements à distance.</p><p>Son nom ? <strong>Fabric</strong></p><p>En quelques lignes de Python, définissant des règles, un peu à la manière d'un Makefile, il est possible d'automatiser ce genre d'opération.</p><p>Voici un exemple basique pour le déployement d'un projet Django avec Mercurial :</p><pre>"""Fabric Rules for MyProject"""<br /><br />config.production = ['server.domain.com']<br />config.app_dir = '/home/dev/djangos/myproject'<br /><br />def publish():<br />&#160;&nbsp;&nbsp; """Publish the content by pushing it"""<br />&nbsp;&nbsp;&nbsp; local('hg push')<br /><br />def apache_reload():<br />&nbsp;&nbsp;&nbsp; """Reload the apache process"""<br />&nbsp;&nbsp;&nbsp; sudo('/etc/init.d/apache2 reload')<br /><br />@roles('production')<br />def update():<br />&nbsp;&nbsp;&nbsp; """Update the code source"""<br />&nbsp;&nbsp;&nbsp; run('cd $(app_dir); hg pull; hg update')<br />&nbsp;&nbsp;&nbsp; run('cd $(app_dir); python manage.py syncdb')<br />&nbsp;&nbsp;&nbsp; run('cd $(app_dir); python manage.py loaddata my_dump.json')<br />&nbsp;&nbsp;&nbsp; apache_reload()<br /><br />@roles('production')<br />def debug_on():<br />&nbsp;&nbsp;&nbsp; """Turn debug mode on for the production server."""<br />&nbsp;&nbsp;&nbsp; run("cd $(app_dir); sed -i -e 's/DEBUG = .*/DEBUG = True/' settings.py")<br />&nbsp;&nbsp;&nbsp; apache_reload()<br /><br />@roles('production')<br />def debug_off():<br />&nbsp;&nbsp;&nbsp; """Turn debug mode off for the production server."""<br />&nbsp;&nbsp;&nbsp; run("cd $(app_dir); sed -i -e 's/DEBUG = .*/DEBUG = False/' settings.py")<br />&nbsp;&nbsp;&nbsp; apache_reload()<br /><br />@depends(publish, update)<br />def deploy():<br />&nbsp;&nbsp;&nbsp; """Deploy the website."""<br />&nbsp;&nbsp;&nbsp; pass</pre><p>Un des avantages principaux de <strong>Fabric</strong> est qu'il est possible de l'utiliser sur plusieurs serveurs en même temps, avec des règles spécifiques.</p><p>On lance Fabric, et on peut aller prendre un café. :D<br /> </p><p>Pour information Fabric est basé sur Capistrano, le même principe mais en Ruby.</p><p>Un must, à tester absolument. </p><p><em>Edit </em>: <a title="Fabric" href="http://www.nongnu.org/fab/">le site du projet Fabric</a></p> fantomas42@gmail.com (fantomas)Fri, 01 May 2009 14:53:09 +0000https://blog.fantomas.site/blog/2009/05/01/paye-ta-fabric/DécouvertesDéveloppementIntégrer Twitter dans Django https://blog.fantomas.site/blog/2009/01/06/integrer-twitter-dans-django/ <img src="/media/cache/b4/7d/b47dd9ae960e59e22a6f086587417dec.jpg" alt="Intégrer Twitter dans Django" /> <p>Twitter, c'est le nouveau média à la mode pour lancer le buzz.<br /> Créer en 2006, son but est simple, pouvoir résumer à tout instant, ce que l'on fait, ce que l'on pense, par des messages courts, que l'on envois par SMS. En effet les messages ne doivent pas dépasser 140 caractères. </p><p>De plus votre réseau peut suivre instantanément vos status, enfin bref voilà le <a href="http://fr.wikipedia.org/wiki/Microblog" title="Microblog sur Wikipedia">Micro-Blogging</a> d'inventé. </p><p>Twitter fournis une <a href="http://apiwiki.twitter.com/" title="API Twitter">API</a> pour pouvoir communiquer avec son service. Je me suis alors demandé ce que je pouvais en faire, et ait décidé d'interfacer celle ci avec Django. </p><p> A travers un exemple nous allons voir comment récupérer des informations de Twitter avec les <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#built-in-tag-reference" title="Built-in Templatetags Django">Templatetags</a> Django. </p><p>Première étape, installer l'excellente <a href="http://code.google.com/p/python-twitter/" title="API Python pour Twitter">API python pour Twitter disponible sur GoogleCode</a>. </p><p>Ensuite nous allons créer un module python disponible dans le PYTHON_PATH, que nous appellerons <strong>django-twitter</strong>, et y créer un templatetag qui récupèrera nos derniers status postés. </p><pre>$ mkdir -p django-twitter/templatetags $ cd django-twitter $ touch __init__.py $ cd templatetags $ touch __init__.py $ touch get_tweets.py </pre><p> Ceci va nous créer la structure pour y intégrer notre code. Nous allons maintenant éditer le fichier get_tweets.py et y insérer le code suivant : </p><pre>"""Templates tags for accessing to Twitter""" from django.conf import settings from django.core.cache import cache from django.template import Library, Node from twitter import Api register = Library() class TweetStatusNode(Node): def __init__(self, num, varname): self.num = int(num) self.varname = varname self.key = '%s-%s' % (self.num, self.varname) def render(self, context): tweets = cache.get(self.key) if not tweets: tweets = Api().GetUserTimeline(settings.TWITTER_USER, self.num) cache.set(self.key, tweets, settings.TWITTER_TIMEOUT) if self.num == 1: context[self.varname] = tweets[0] else: context[self.varname] = tweets return '' @register.tag def get_twitter_status(parser, token): """usage : {% get_twitter_status n as tweets %}""" bits = token.split_contents() if len(bits) != 4: raise TemplateSyntaxError, "get_twitter_status tag takes exactly three arguments" if bits[2] != 'as': raise TemplateSyntaxError, "second argument to get_twitter_status tag must be 'as'" return TweetStatusNode(bits[1], bits[3] ) </pre> <h1>Explications</h1><p> La fonction <strong>get_twitter_status</strong> sert de tag et va conditionner les paramètres passés à l'objet Node qui va effectuer la manipulation au sein du template et du context. Si ce code vous semble obscur, je vous conseille d'aller faire un tour sur la <a href="http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#writing-custom-template-tags">documentation Django pour les templatetags</a>. </p><p>Comme nous le voyons cette fonction retourne un objet hérité de <strong>Node</strong>, TweetStatusNode. C'est cette objet qui va contenir le code appelant l'API de Twitter. </p><p>De là j'assigne le résultat dans le context du template, et le tour est joué.</p><p> Désormais au sein de mes templates, je peux récupérer mes X derniers status sur Twitter, grâce à ces quelques lignes. </p><pre>{% load get_tweets %} {% get_twitter_status 5 as tweets %} </pre><p> Simple non ? <br /> Une dernière remarque, le système de cache de Django est utilisé, pour limiter les requêtes et le temps d'attente quand on interroge les serveurs de Twitter. </p><p>A partir de là, je pense qu'il est envisageable de faire une application Django complète, qui fournit les mêmes fonctionnalités que le site original, mais l'intérêt reste limité. </p> fantomas42@gmail.com (fantomas)Tue, 06 Jan 2009 16:19:05 +0000https://blog.fantomas.site/blog/2009/01/06/integrer-twitter-dans-django/DéveloppementExpériencesDistribuer une application Django en moins de 5 minutes https://blog.fantomas.site/blog/2008/12/29/distribuer-une-application-django-moins-de-5-min/ <img src="/media/cache/45/64/45644b57955c6841354eb879f1a5ef57.jpg" alt="Distribuer une application Django en moins de 5 minutes" /> <p>Vous venez de finir votre dernière application en Django, qui se veut réutilisable et distribuable. Félicitations :). </p><p>Désormais vous voulez automatiser l'installation et la distribution du paquet, et pourquoi pas le rendre installable facilement en 1 ligne de commande, sous la forme d'<a href="http://peak.telecommunity.com/DevCenter/PythonEggs" title="Eggs Python">eggs</a>. </p><p>Le plus simple est de réaliser un script d'installation basé sur <a href="http://docs.python.org/lib/module-distutils.html" title="Module Distutils">distutils</a> qui permettra de télécharger et d'installer le code en quelques secondes. L'idée est de paqueter le module à distribuer avec un script nommé <strong>setup.py</strong> se chargeant de l'installation.</p><p>Mais réaliser ce script est parfois assez contraignant et long, surtout ex nihilo... </p><p> Pour cela nous allons utiliser <strong>PasteScript</strong> et un jeu de templates pour Django pour nous créer automatiquement la structure du script. </p><p> <strong>Prérequis</strong> </p><ul><li><a href="https://pypi.python.org/pypi/PasteScript" title="Paste">PasteScript</a> : easy_install PasteScript </li><li><a href="http://github.com/danfairs/fez.djangoskel/tree/master" title="Projet fez.djangoskel">fez.djangoskel</a> : easy_install fez.djangoskel </li></ul><p>Désormais on va créer la structure du package avec cette commande : </p><pre>$ paster create -t django_app mon_application</pre><p> Plusieurs questions importantes vous seront posées pour créer la structure de votre distribution, répondez soigneusement. </p><p>Désormais dans ce dossier nous avons un fichier <em>setup.py</em> et un dossier <em>mon_application</em>. Le template utilisé crée automatiquement des fichiers pour réaliser une application Django. C'est là où il vous faut mettre votre code. </p><p>Maintenant éditez votre fichier <strong>setup.py</strong> pour le personnaliser un peu. </p><p>Grâce aux commandes intégrées vous pouvez distribuer votre application facilement. </p><p>Pour l'enregistrer sur <a href="http://pypi.python.org/pypi" title="Python Package Index">Pypi</a> et le rendre disponible via <strong>easy_install</strong> : </p><pre>$ python setup.py sdist bdist_egg register upload</pre><p> Pour installer votre application il suffit désormais de faire : </p><pre>$ easy_install mon_application</pre><p> Ou dans le cas où on a téléchargé les sources :</p><pre>$ python setup.py install</pre><p> Simple, rapide et efficace non ?</p> fantomas42@gmail.com (fantomas)Mon, 29 Dec 2008 15:21:43 +0000https://blog.fantomas.site/blog/2008/12/29/distribuer-une-application-django-moins-de-5-min/DéveloppementExpériencesDjango unique et timed sessions https://blog.fantomas.site/blog/2008/12/24/django-unique-et-timed-sessions/ <img src="/media/cache/7a/e7/7ae7794ebfb995588c172aa4c7bec0af.jpg" alt="Django unique et timed sessions" /> <h1>Comment rendre unique les comptes utilisateurs connectés sur un site en Django ? </h1><p>Ce genre de problématique se retrouve souvent sur les sites internet proposant des abonnements à un service en ligne, voulant empêcher le partage d'abonnement. </p><p>Pour les besoins d'un projet spécifique en Django au sein de la <a href="http://www.emencia.fr" title="Emencia">société Emencia</a> là où je travaille, j'ai du développer un moyen d'empêcher 2 utilisateurs de se connecter sur un compte utilisateur en même temps. </p><p>Mais le problème ne s'arrête pas là, comment empêcher la connection et la déconnection successive entre 2 utilisateurs ? L'idée est de donner un temps minimum de connection à chaque session ouverte pour empêcher la déconnection, par exemple 5 minutes. </p><p>Pour cela j'ai écrit un <strong>Middleware </strong>pour Django qui va se charger de rendre unique chaque sessions utilisateurs sur le site. Utiliser un middleware donne l'avantage d'être réutilisable et facile à installer. </p><pre>MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'utsessions.middleware.UTSessionMiddleware', )</pre><p> Après plusieurs refactorings et tests, permettant de configurer le comportement du middleware, comme la déconnection automatique, j'ai publier le code source sur GoogleCode pour que tout le monde puisse en profiter.</p><p>Pour plus d'informations, ou pour télécharger le code, consulter le site web du projet : <a href="http://code.google.com/p/django-ut-sessions/">Django UT Sessions</a>. </p><p>Pour installer le module depuis Pypi : </p><pre>$ easy_install utsessions</pre> fantomas42@gmail.com (fantomas)Wed, 24 Dec 2008 10:12:22 +0000https://blog.fantomas.site/blog/2008/12/24/django-unique-et-timed-sessions/DéveloppementClustered Models https://blog.fantomas.site/blog/2008/12/22/clustered-models/ <p>Je vous parlais récemment de l'application Django <a href="/blog/2008/12/15/clustered-sitemap/" title="Clustered Sitemap">Clustered Sitemap</a>, servant à établir la correspondance entre 2 objets sur des projets Django. </p><p>Après une review globale du code et l'ajout de certaines fonctionnalités, j'ai changé le nom du projet en <strong>Clustered models</strong> car il ne correspondait plus vraiment à la philosophie du projet. </p><p>La première modification à été d'ajouter une nouvelle version du sitemap, mais cette fois ci en <a href="/cloud-sitemap/" title="Sitemap en nuage">nuage 2D</a>. </p><p>Le code et les vues ont été rendu génériques pour en faciliter l'intégration et l'extensibilité. <br />Une feature intéressante est qu'il est possible de réutiliser la configuration des vues générique pour effectuer des groupements. </p><p>Ensuite un <em>templatetag</em> à été ajouté pour pouvoir voir les models associés à un autre model. Le résultat est qu'il est désormais possible de voir les articles associés sur le blog. :)</p><p> Le tout étant très facile à installer, voici un exemple du code pour réaliser mes sitemaps mélant les flatpages et les articles, dans le fichier <em>urls.py</em> du projet. </p><pre>from clustered_models import VectorBuilder<br />from clustered_models.clusterers import DimensionalClusterer<br />from clustered_models.clusterers import HierarchicalClusterer from django.contrib.flatpages.models import FlatPage<br /><br />entry_conf = {'queryset': Entry.published.all(), 'fields': ['content', 'title', 'excerpt']}<br /> flatpage_conf = {'queryset': FlatPage.objects.all(),<br /> 'fields': ['title', 'content']}<br /><br />vector = VectorBuilder(entry_conf, flatpage_conf)<br /><br />urlpatterns += patterns(<br /> '',<br /> url(r'^sitemap/$', 'clustered_models.views.clustered_view',<br /> {'vector': vector, 'clusterer': HierarchicalClusterer}),<br /> url(r'^cloud-sitemap/$', 'clustered_models.views.clustered_view',<br /> {'vector': vector, 'clusterer': DimensionalClusterer})<br />) </pre><p> Je ne releaserais le module que si il y a un minimum d'intérêt pour ce projet, donc à vos commentaires :).</p> fantomas42@gmail.com (fantomas)Mon, 22 Dec 2008 11:44:45 +0000https://blog.fantomas.site/blog/2008/12/22/clustered-models/DéveloppementClustered Sitemap https://blog.fantomas.site/blog/2008/12/15/clustered-sitemap/ <p>Comme je vous en parlais dans mon précèdent article, je comptais faire <a href="http://fantomas.willbreak.it/blog/2008/dec/14/analyse-hierarchique-par-le-contenu/" title="Analyse hiérarchique par le contenu">quelque chose d'utile tiré de l'intelligence collective</a>. <br />J'ai donc intégré une partie du code de mon projet <strong>Feed Clusterer</strong> pour en faire un module Django.</p><p> L'idée est de reprendre la configuration des vues génériques, et de spécifier les champs à inspecter pour effectuer une correspondance. Cette correspondance servira à l'établissement d'une cartographie des différentes vues d'un site en Django. </p><p> En modélisant ces données sous la forme d'un dendogramme on peut avoir un <a href="/sitemap/" title="Sitemap intelligent">sitemap assez surprenant</a>, que l'on peut retrouver sur la rubrique <a href="/sitemap/" title="Sitemap ou carte du site">Carte</a> en haut du site. Les regroupements se font à la fois sur les thèmes abordés, comme la <em>programmation</em>, ou les <em>restaurants</em>, tout en mélangeant les styles d'écritures et les catégories utilisées.</p><p> Cela permet de pouvoir orienter le visiteur vers les articles connexes du site, sans avoir à établir de relations aux préalables :). Regardez la section ou je parle d'<strong>Ogame</strong> cela suit ma logique de développement et regroupe à chaque fois l'article le plus proche. <br />Saisissant non ? </p><p>Concernant l'effet d'arbre dépliables, je tiens à en <a href="http://bassistance.de/jquery-plugins/jquery-plugin-treeview/">remercier l'auteur du site bassistance.de</a>, qui a fait un travail excellent en se basant sur JQuery, un must ! </p><p> Si le projet vous intéresse, je peux le releaser, il me reste que peu de travail pour le rendre générique. </p> fantomas42@gmail.com (fantomas)Mon, 15 Dec 2008 21:25:48 +0000https://blog.fantomas.site/blog/2008/12/15/clustered-sitemap/DéveloppementExpériencesAnalyse hiérarchique par le contenu https://blog.fantomas.site/blog/2008/12/14/analyse-hierarchique-par-le-contenu/ <img src="/media/cache/8b/34/8b34dc4ae060294c4321957d71309f39.jpg" alt="Analyse hiérarchique par le contenu" /> <p>Je suis actuellement en train de lire un livre sur les différents types d'intelligences dîtes collectives. C'est à dire l'analyse de données représentant les choix, ou les comportement de plusieurs personnes, et comment en extraire des vérités globales. </p><p>Une des première applications à laquelle je me suis attaqué à été de construire un <strong>Feed Clusterer</strong> en Python, servant à effectuer des regroupements par pertinences entre différents sites web. </p><h1>Comment ca marche ?</h1><p>Tout site web qui se respect propose un service de Flux RSS ou Atom, résumant les dernières actualités publiées sur le site. L'idée est d'en récupérer le contenu et d'en extraire une liste de mot pertinents. </p><p>En calculant le <a href="http://en.wikipedia.org/wiki/Pearson%27s_correlation_coefficient" title="Coefficiant de Pearson sur Wikipedia">coefficient de Pearson</a> en me basant sur les fréquences de mots comme vecteur, je peux en constituer des groupes et les classer de façon hiérarchique. </p><p>Pour visualiser cela, il suffit ensuite de tracer un <strong>dendogramme</strong>. Un dendogramme va représenter les groupes et la distance entre chaque groupes sur un ensemble de branches. Comme le montre l'image de l'article. </p><p>Ceci reste une expérience à petite échelle, mais imaginons maintenant toutes les données que récoltent les gros site web, en particulier ceux à vocations sociales, comme FaceBook, Twitter, MySpace, et n'oublions pas certains moteurs de recherches qui avec leurs dizaines de services sont capables de tracer toutes nos habitudes. </p><p>Je ne rentrerais pas dans le détails de toutes les applications inimaginables avec ces données pour tracer les gens, mais de plus avec l'internet mobile, on fournit une nouvelle donnée, c'est à dire le lieu et donc les conditions dans lesquelles on est quand on décide d'acheter un livre sur Amazon. </p><p>Marketing ciblé, ou Big Brother ? Où est la différence ? <br />A titre personnel, je pense que la différence se fera quand on mettra à profit les intelligences collectives au services de l'intelligence humaine, et non à son asservissement, commercial ou autre. </p><p> Donc pour finir j'ai décidé de programmer une application Django mettant à l'ouvrage cette étude, qui servira à proposer une navigation différente sur le site. Bientôt la release. :)</p> fantomas42@gmail.com (fantomas)Sun, 14 Dec 2008 00:33:28 +0000https://blog.fantomas.site/blog/2008/12/14/analyse-hierarchique-par-le-contenu/DéveloppementExpériencesPython 3.0 : compatibilités et évolutions https://blog.fantomas.site/blog/2008/12/11/python-30-compatibilite-evolutions/ <img src="/media/cache/4d/d1/4dd177ac01eca69c63e2165b7c4f315e.jpg" alt="Python 3.0 : compatibilités et évolutions" /> <p>C'est le 3 décembre dernier que la <a href="http://www.python.org/download/releases/3.0/">version 3.0 de Python</a> est sortie. Une version attendue par une grande partie de la communauté Python. </p><p>Au programme, un bon coup de nettoyage de la librairie standard, des nouveautés comme le passage en tout Unicode, et une nouvelle syntaxe. Même si cette dernière reste proche des moutures 2.x, elle est clairement incompatibles avec les versions précédentes. Un fait assumé par les créateurs. </p><p>Pour effectuer la transition en douceur, les versions 2.6 et 2.7 ont amorcées le travail en intégrant une partie des nouveaux concepts présent dans Python 3.0, comme la <em>Curryfication</em>, ou l'implémentation de pseudo opérateurs ternaires. </p><p>De plus le script <a href="http://svn.python.org/view/sandbox/trunk/2to3/">2to3</a> est là pour finaliser cette transition en convertissant le code écrit en 2.x vers la version 3. Il serait dommage que les anciens projets basé sur la version 2.x meurent du fait d'une trop grande difficulté de migration. </p><p>Craignant une fuite de la communauté Python, c'est sur ces sujets que nous avons été consultés par le site <strong>LeMagIT.fr</strong>, mon collègue et moi, pour expliquer notre point de vue sur cette nouvelle version dîtes mature. </p><p>L'article se situe à l'adresse suivante : <a href="http://www.lemagit.fr/article/web-developpement-communaute/1939/1/avec-version-python-mue-pour-harmoniser/">Harmonisation au sein de Python 3.0</a>.</p><p> <strong>Mise à jour</strong> : <a href="http://www.toonux.com/news/python-3k-a-lhonneur-dans-le-mag-it-les-developpeurs-demencia-nous-expliquent-les-tenants-et-les-aboutissants-de-cette-migration-necessaire" title="Toonux.com">Toonux.com relaye l'info.</a></p> fantomas42@gmail.com (fantomas)Thu, 11 Dec 2008 01:59:10 +0000https://blog.fantomas.site/blog/2008/12/11/python-30-compatibilite-evolutions/DéveloppementComment passer de Wordpress à Django https://blog.fantomas.site/blog/2008/11/24/comment-passer-de-wordpress-django/ <p><strong>Wordpress</strong> c'est très bien, mais ca devient peu devenir vite une machine à gaz. Mon hébergement gratuit et mutualisé chez 1and1 étant finis, je dois migrer sur un nouveau serveur, et PHP, pour moi c'est révolu, autant passer à Django, et décrire la marche à suivre.</p> <p><a href="http://fantomas.willbreak.it/migration-wordpress-django" title="Migration de Wordpress vers Django">Consulter le tutorial</a></p> fantomas42@gmail.com (fantomas)Mon, 24 Nov 2008 21:01:44 +0000https://blog.fantomas.site/blog/2008/11/24/comment-passer-de-wordpress-django/DéveloppementOgame Statistics https://blog.fantomas.site/blog/2008/03/02/ogame-statistics/ <img src="/media/cache/7a/36/7a3635d3277fc35ef96d0597c303e101.jpg" alt="Ogame Statistics" /> <p>Lors de mon dernier article, je vous ai parlé de Open Flash Chart, en vous spécifiant que cela avait un rapport avec un prochain article, cet article le voilà. </p><p><a href="http://ostat.upasika.org" title="Ogame Statistics">Ogame Statisitics</a> est un nouveau site que je viens d'ouvrir permettant de consulter les statistiques de tous les joueurs et alliances présents sur un univers de jeu de <a href="http://ogame.fr" title="Ogame.fr">Ogame</a>. </p><p>Le site réalisé grâce au framework <a href="http://www.djangoproject.com" title="Django Project">Django</a>, permet de créer une interface visuel des statistiques collectées par un module de mon robot pour Ogame, <a href="http://fantomas.willbreak.it/2008/jan/22/ogame-attack-watcher-la-suite/" title="Ogame Attack Watcher, la suite !">Obot</a> dont j'ai déjà parler précèdement sur le blog. </p><p>En effet j'ai développé un nouveau module pour mon robot permettant de récolter toute les statistiques à un moment donné sur un serveur de jeu.</p><p> Des initiatives ont déjà été prises pour effectuer des visualisations de statistiques, utiles pour les alliances, mais le gros inconvénient de ces systèmes est qu'il est nécessaire de rentrer les données manuellement et assez fréquemment pour obtenir un suivi, ce qui est une tache longue et répétitive donc idiote :) </p><p> Là où se démarque Ogame Statistics, est que la mise à jours des données est automatique et régulière, car elle est prise en charge par Obot :) </p><p> Au menu du site, on trouvera un moteur de recherche, pour permettre de retrouver son profil ou son alliance, ses dernières statistiques, ainsi que celle de son alliance, et des graphiques d'évolutions réalisés avec Open Flash Chart. Une petite touche d'Ajax avec <a href="http://www.jquery.com" title="jQuery.com">jQuery</a> pour le trie des données et le résultat n'en est que mieux. </p><p>La version 1.0 vient de sortir, mais va venir s'agrémenter de nouvelles fonctionnalités orientés sur la comparaison des différents univers de jeux, et la gestion des alliances inter-univers. </p><p>Le site : <a href="http://ostat.upasika.org" title="Ogame Statistics">Ogame Statistics </a></p> fantomas42@gmail.com (fantomas)Sun, 02 Mar 2008 19:59:32 +0000https://blog.fantomas.site/blog/2008/03/02/ogame-statistics/DéveloppementOpen Flash Chart avec le Python's style ! https://blog.fantomas.site/blog/2008/02/28/open-flash-chart-python/ <img src="/media/cache/de/06/de06759e66c72b2c17b9d268d351f8a1.jpg" alt="Open Flash Chart avec le Python&#39;s style !" /> <p>Récemment, pour les besoins d'un projet dont je parlerais bientôt lors d'un prochain article, je me suis mis à rechercher une librairie Python me permettant de réaliser rapidement de jolis graphiques statistiques. </p><p>Passé les <a href="http://home.gna.org/pychart/" title="Le site de PyChart">PyChart</a> et autre ChartDirector. Mon choix s'est porté sur <a href="http://teethgrinder.co.uk/open-flash-chart/" title="Le site d'Open Flash Chart">Open Flash Chart</a>, une librairie permettant de réaliser des graphiques statistiques grâce à Flash. </p><p>Comme son nom le laisse supposer, la librairie est <em>open source</em>, un point primordial ;) Un site bien documenté avec des exemples complets, permettant une prise en main rapide et un résultat graphique abouti, m'auront convaincu assez rapidement.</p><p> L'avantage de cette librairie est qu'il est techniquement possible de l'interfacer avec tous les langages, car le fichier flash générant le graphique, se charge de récupérer un fichier au format texte, contenant les données du document. </p><p> Il suffit donc de générer un simple fichier texte, pour pouvoir afficher un graphique complexe, ce qui est un avantage notable pour la machine qui hébergera la représentation des graphiques. En effet on nous n'avons pas générer d'image, comme les autres librairies, et encore moins à les stocker. </p><p>La bonne nouvelle, est qu'il existe déjà des APIs pour différents langages, tel PHP, Perl, mais aussi Python. Génial ! :) </p><p>La moins bonne nouvelle vient du fait, que cette dite API Python ne fonctionne pas <em>ou plus</em>, et n'est clairement pas maintenue à jours. :( </p><p>L'autre bonne nouvelle, est que j'ai pris le soin de recoder l'API Python pour Open Flash Chart. :) </p><p> En me basant sur la documentation et sur le travail de la précédente API écrite par Guenther Harrasser, j'ai corrigé, nettoyé et mis à jour le code. Pour finalement le réécrire complétement... </p><p> J'en ai profité pour mailer l'auteur, et lui proposer mon correctif. En l'attente d'une réponse, je me propose pour vous faire partager mon travail. </p><p>Nous allons dans cette exemple générer un graphique simple composé d'une ligne et d'une série de barres, la ligne étant placé sur l'axe Y de droite. </p><pre>from openflashchart import Graph # Création du graph et titrage graph = Graph() graph.title('My Graph Title', '{font-size:20px}') # Insertion des barres, de la ligne, # et des données associées graph.bar_outline(50, '#005aff', '#666666', 'Bar Stats', 10) graph.set_data(range(10)) graph.line_hollow(2, 5, '#05a0FF', 'Line Stats', 10) graph.set_data(range(10, 20)) # Assignation de la ligne sur l'axe Y de droite, # des libelles en abscisse, et des légende en ordonnée. graph.attach_to_y_right_axis(2) graph.set_x_labels(['x_%i' % i for i in range(10)]) graph.set_y_legend('Legend Left', 15, '#ff4a00') graph.set_y_right_legend('Legend Right', 15, '#4aff00') # Génération du graphique stat = graph.render()</pre><p>Télécharger <a href="http://fantomas.willbreak.it/wp-content/uploads/2008/02/open-fc.zip" title="Open Flash Chart : API Python">Open Flash Chart : API Python</a> </p><p><strong>Edition du 30 mai 2007 :</strong> Une amélioration du code de rendu HTML a été faite, pour gagner en lisibilité et aussi pour facilité la manipulation du DOM.</p> fantomas42@gmail.com (fantomas)Thu, 28 Feb 2008 22:51:47 +0000https://blog.fantomas.site/blog/2008/02/28/open-flash-chart-python/Développement