(14:00:29) olivier.larcheveque: On reprends avec la présentation de Davin sur la programmation Python https://wiki.auf.org/wikiteki/Projet/SemaineTech/Ateliers/ProgrammationPython (14:00:32) semainetech@reunion.auf.org: willy a changé le sujet en : ☞ Le salon de la Semaine Tech ☜ Atelier "Programmation python" https://wiki.auf.org/wikiteki/Projet/SemaineTech/Ateliers/ProgrammationPython (14:00:46) davin.baragiotta: ---------- DÉBUT : Atelier : Programmation Python ---------------- (14:00:51) davin.baragiotta: INTRODUCTION (14:00:55) davin.baragiotta: Bonjour à tous! (14:01:00) davin.baragiotta: La documentation complète de Python se trouve ici : http://www.python.org/doc/ (14:01:07) davin.baragiotta: Vous y trouverez notamment un tutoriel (que j'aurais aimé suivre mais c'est trop long) : http://docs.python.org/tutorial/ (14:01:16) davin.baragiotta: ... et aussi la documentation de la librarie (bibliothèque) standard venant avec le langage (on y reviendra) : http://docs.python.org/library/ (14:01:20) davin.baragiotta: Aujourd'hui, on va programmer en Python. (14:01:21) davin.baragiotta: :D (14:01:27) davin.baragiotta: Dans cet atelier : * on va coder dans l'interpréteur et explorer les bases du langages * on va écrire un script qu'on fera exécuter par l'interpréteur * on va explorer du vrai code et modifier celui-ci pour créer un bot jabber!!!! (14:01:39) davin.baragiotta: ENVIRONNEMENT (14:01:50) davin.baragiotta: Vous devriez avoir un éditer texte sous la main, configuré comme demandé dans la page wiki. (14:01:57) davin.baragiotta: Vous devriez avoir installé l'interpréteur ipython. (14:02:05) davin.baragiotta: Vous devriez avoir téléchargé l'archive code.tar.gz : https://wiki.auf.org/wikiteki/Projet/SemaineTech/Ateliers/ProgrammationPython?action=AttachFile&do=view&target=code.tar.gz (14:02:13) davin.baragiotta: Ouvrez un terminal et déplacez vous dans le répertoire où vous avez extrait l'archive : cd code/ (14:02:21) davin.baragiotta: C'est parti! (14:02:36) davin.baragiotta: INTERPRÉTEUR (14:03:00) davin.baragiotta: L'interpréteur python par défaut se lance avec la commande: python (14:03:06) davin.baragiotta: il vient avec le langage.... (14:03:14) davin.baragiotta: mais nous on va travailler avec ipython qui se lance avec la commande.... : ipython (14:03:21) davin.baragiotta: ipython permet une introspection plus aisée (on y reviendra) (14:03:28) davin.baragiotta: lancez dans votre terminal ipython : ipython (14:03:50) davin.baragiotta: Quand on code en Python, on utilise l'interpréteur pour explorer interactivement le Python. (14:03:57) davin.baragiotta: Mais l'édition directement dans l'interpréteur peut être pénible. (14:04:04) davin.baragiotta: C'est pourquoi nous mettons le "code qui marche" et et éditons le code plus complexe dans un script. (14:04:14) davin.baragiotta: C'est ce que nous ferons après. Explorons d'abord dans l'interpréteur. (14:04:19) davin.baragiotta: PYTHON : QUELQUES BASES (14:04:28) davin.baragiotta: Toute programmation repose sur des conventions syntaxiques... En Python, on a de la chance, la syntaxe est très simple et intuitive. (14:04:37) davin.baragiotta: Les commentaires se font avec # : # ceci est un commentaire (14:04:44) davin.baragiotta: Les variables se déclarent sans $ devant ou autre fioriture. (14:04:52) davin.baragiotta: Les instructions ne se terminent pas avec des ; (14:05:00) davin.baragiotta: Les blocs de code ne sont pas structurés avec des { } mais par l'indentation. (14:05:09) davin.baragiotta: Les conventions pour le style de code en Python sont définies dans la PEP 8 (genre de norme) : http://www.python.org/dev/peps/pep-0008/ (14:05:24) davin.baragiotta: PYTHON : QUELQUES BASES : LES TYPES (14:05:34) davin.baragiotta: Voici les principaux types de bases fournis avec le langage : n = None # NoneType : type spécial voulant dire... rien b = True # bool : booléen... True ou False n'oubliez pas les majuscules i = 15 # int : entier f = 15.5 # float : décimal s = "chaine" # str : chaine de caractère, instancié avec "" ou '' u = u"chaîne" # unicode : chaîne de caractère unicode, instancié avec u"" ou u'' l = [] # list : liste d'objets t = () # tuple : liste immuable d'objets d = {} # dict : dictionnaire de données (14:06:10) davin.baragiotta: PYTHON : QUELQUES BASES : OBJETS ET NAMESPACES (14:06:20) davin.baragiotta: En Python, tout est un "objet". Concrètement, ça veut dire que chaque "chose" qu'on manipule a: * un nom * des attributs (variables) accessibles "derrière" * des méthodes (fonctions) accessibles "derrière" (14:06:34) davin.baragiotta: Les attributs et méthodes ont des noms aussi. (14:06:41) davin.baragiotta: Mais ils se trouvent dans l' "espace de nom" de l'objet. (14:06:48) davin.baragiotta: Ils sont accessibles en utilisant un point pour séparer les noms : objet.attribut objet.methode() (14:06:58) davin.baragiotta: On peut chaîner les noms avec les points : objet.attribut.methode_attribut() (14:07:07) davin.baragiotta: Assez la théorie. Codons. (14:07:08) davin.baragiotta: :D (14:07:15) davin.baragiotta: INTROSPECTION (14:07:22) davin.baragiotta: Dans votre interpréteur déclarez une chaîne de caractères unicode : prenom = u"Davin" (14:07:42) davin.baragiotta: L'idée de l'introspection est de : voir en interrogeant l'objet ce qu'on peut faire avec (14:07:51) davin.baragiotta: ipython nous offre une façon simple de regarder ça (14:07:58) davin.baragiotta: après le nom de votre variable... tapez '.' puis 'tab' prenom. [+ tab] (14:08:10) davin.baragiotta: vous voyez tous les noms (attributs et méthodes) accessibles sur cet objet unicode (14:08:17) davin.baragiotta: (enter pour voir plus, 'q' pour sortir de la liste) (14:08:29) davin.baragiotta: tous les noms qui commencent avec __* sont des noms systèmes. (14:08:38) davin.baragiotta: Le nom seul est parfois pas suffisant pour savoir quoi faire avec... (14:08:46) davin.baragiotta: on va interroger l'interpréteur pour qu'il nous donne de l'info sur le nom (14:08:59) davin.baragiotta: derrière n'importe quel nom, on peut mettre '?' et taper enter prenom.upper? (14:09:12) davin.baragiotta: ooooouuah! la partie docstring est carrément la documentation de la méthode! (14:09:14) davin.baragiotta: :D (14:09:52) davin.baragiotta: si c'est la méthode qu'on veut (14:09:52) davin.baragiotta: on l'exécute : prenom.upper() (14:10:10) davin.baragiotta: note : l'objet prenom en est pas modifié... (14:10:14) davin.baragiotta: tapez : prenom (14:10:31) davin.baragiotta: Les fonctions built-in Python suivantes servent aussi à l'introspection : type(objet) # retourne le type de l'objet dir(objet) # retourne les noms derrière l'objet help(objet) # retourne l'aide callable(objet) # dit si un objet est appelable, exécutable... isinstance(objet, Type) # teste le classe (ou type) d'un objet ... (14:10:46) davin.baragiotta: exemple : type(prenom) (14:11:19) davin.baragiotta: l'objet prenom est bien de type unicode car on l'a instancié avec u"" (un u devant) (14:11:23) davin.baragiotta: Des questions? (14:11:47) olivier.larcheveque: non pas de questions (14:12:01) davin.baragiotta: ok cool (14:12:30) davin.baragiotta: on peut jouer un peu dans l'interpréteur avant de regarder un script (14:12:49) davin.baragiotta: nom = u"Baragiotta" (14:12:53) davin.baragiotta: l = [] (14:12:59) davin.baragiotta: l. + tab (14:13:15) davin.baragiotta: on utiliserait qu'on puor ajouter notre nom et prenom à la liste vide? (14:13:37) davin.baragiotta: l.append? (14:13:45) davin.baragiotta: l.append(prenom) (14:13:50) davin.baragiotta: l.append(nom) (14:13:55) davin.baragiotta: tapez : l (14:14:18) davin.baragiotta: si vous voulez itérer : for (14:14:33) davin.baragiotta: for item in liste : print item.upper() (14:14:37) davin.baragiotta: ach (14:14:42) davin.baragiotta: for item in liste : print item.upper() (14:15:11) davin.baragiotta: Questions? (14:15:14) olivier.larcheveque: REMARQUE de JC sur l'encodage : attention au piège de la saisie Unicode dans iPython : prenom = u"Céline" ne marchera pas, ça vous donnera la chaîne Unicode u'C\xc3\xa9line', qui est incorrecte (c'est de l'UTF-8), au lieu de u'C\xe9line', qui est ce qu'on attendait ; pour obtenir le résultat correct en direct dans iPython il faut taper ceci : prenom = unicode("Céline", 'utf-8') (14:15:44) olivier.larcheveque: autrement pas de questions (14:16:04) davin.baragiotta: oui, pour les questions d'encodage, python est mieux... mais en codant ce qu'on a fait dans un script et en l'exécutant... on devrait pas avoir à passer par unicode() (14:16:06) davin.baragiotta: okay (14:16:17) davin.baragiotta: SCRIPTS (14:16:19) olivier.larcheveque: les apprenants te font remarquer une erreur ;) (14:16:23) davin.baragiotta: ah? (14:16:36) olivier.larcheveque: c'est correct! ;) (14:16:37) davin.baragiotta: mais vous mentez, c'est mal... (14:16:40) davin.baragiotta: l = [] (14:16:41) davin.baragiotta: ;) (14:16:48) davin.baragiotta: (09:12:53) davin.baragiotta: l = [] (14:16:50) davin.baragiotta: :D (14:17:24) davin.baragiotta: SCRIPTS (14:17:28) davin.baragiotta: Comme on le disait, c'est pas top coder dans l'interpréteur. Alors on va faire un script. (14:17:33) davin.baragiotta: il s'agit d'inclure du code dans un fichier et demander à l'interpréteur d'exécuter le code (14:17:41) davin.baragiotta: ouvrez dans un éditeur le fichier script.py : code/script.py (14:17:49) davin.baragiotta: la première ligne s'appelle shebang (14:17:55) davin.baragiotta: c'est pour dire au système que ce qui suit est du python (14:18:03) davin.baragiotta: ligne 2 : dit que c'est encodé en UTF-8 : ça nous permet d'écrire avec caractères accentués (notamment texte et commentaires) (14:18:13) davin.baragiotta: ligne 7 : un peu obscure, cette ligne se lit comme ça : si le nom de ce script est __main__ (ce qui est son nom par défaut quand lancé dans un interpréteur) alors exécute ce qui suit (14:18:25) davin.baragiotta: c'est là qu'on met les instructions du script pour les cas où on le lance avec un interpréteur (14:18:47) davin.baragiotta: lançons le script avec ipython : run script ou run script.py (14:18:58) davin.baragiotta: (avec l'interpréteur normal ce serait juste : python script.py ) (14:19:33) davin.baragiotta: Voilà pour la partie théorique... il resterait beaucoup à dire (14:19:39) davin.baragiotta: mais je vous laisse explorer par vous même (14:19:45) davin.baragiotta: les if... par exemple... (14:20:03) davin.baragiotta: on peut regarder rapidement la syntaxe de la fonction (14:20:10) davin.baragiotta: ligne 4 de script.py (14:20:33) davin.baragiotta: en fait ce qui est remarquable ici = pas d'accolades, pas de ; (14:20:44) davin.baragiotta: une indentation de 4 esapces (pas de tabs dans vos scripts svp ;) ) (14:21:07) davin.baragiotta: on peut faire plein de trucs avec les types de bases... mais c'est facile à explorer (14:21:18) davin.baragiotta: C'est la semaine tech, jouons maintenant! ;) (14:21:25) davin.baragiotta: Regardons du code plus intense (14:21:26) davin.baragiotta: ;) (14:21:33) davin.baragiotta: MODULES : BOT JABBER (14:21:44) davin.baragiotta: l'idée générale = créer un robot qui puisse être dans un salon jabber et interagir avec les users connectés (14:21:56) davin.baragiotta: ah, des questions? (14:23:09) davin.baragiotta: ouvrez et éditez le fichier bot/conf.py.edit et sauvegardez le dans : bot/conf.py (14:23:10) davin.baragiotta: assurez-vous que : CHATROOM = "test@reunion.auf.org" (14:23:10) davin.baragiotta: si vous n'avez pas de username et de password pour votre bot : (14:23:10) davin.baragiotta: https://register.jabber.org/ (14:24:10) davin.baragiotta: tout le monde a créé un conf.py dans le répertoire bot? (14:24:50) davin.baragiotta: vous pouvez vous rendre dans le salon test (14:25:32) olivier.larcheveque: QUESTION: quel est l'intérêt de mettre un if __name__=='__main__' et de mettre son code au lieu de l'inclure une fois sans mettre cette ligne ? REPONSE : on peut utiliser le fichier comme un module dans avoir à lancer le script (14:25:40) olivier.larcheveque: ça permet d'importer des parties du script sans obligatoirement en exécuter le contenu (14:26:25) davin.baragiotta: ok je vais lancer mon bot (14:26:51) olivier.larcheveque: REMARQUE : davin.baragiotta n'a pas explicité comment on se rend dans le salon après avoir modifié la config (14:27:04) davin.baragiotta: ok mon bot s'appelle barabotta et est présent dans le salon test (14:27:09) davin.baragiotta: pour lancer votre bot : (14:27:16) davin.baragiotta: run bot/bot.py (14:28:04) davin.baragiotta: donc maintenant, vous (comme user) devriez être dans le salon test (de la même façon que vous avez fait pour vous rendre ici) ;) (14:28:07) davin.baragiotta: et votre bot aussi (14:28:29) davin.baragiotta: cool, y'a plein de bot (14:29:00) davin.baragiotta: ok je vais montrer des commandes du bot et on regardera le code qui l'exécute avant que vous le modifiez (14:29:01) davin.baragiotta: :D (14:31:29) davin.baragiotta: on a regardé quelques commandes du bot (14:31:33) davin.baragiotta: regardons les sources (14:31:50) davin.baragiotta: ouvrez dans un éditeur le fichier bot/bot.py (14:32:38) davin.baragiotta: en haut du fichier, on connait maintenant : shebang et encoding (14:32:39) davin.baragiotta: cool (14:32:45) davin.baragiotta: lignes 4 à 8 (14:32:50) davin.baragiotta: mesdames et messieurs... (14:32:57) davin.baragiotta: c'est toute la puissance de Python devant vous (14:33:07) davin.baragiotta: les import !!!! (14:33:17) davin.baragiotta: le but du jeu, quand on code... c'est de ne pas réinventer la roue (14:33:34) davin.baragiotta: pour ce faire, on importe le code qui règle déjà nos problèmes... (14:33:41) davin.baragiotta: ligne 4 (14:33:51) davin.baragiotta: from datetime import datetime (14:34:19) davin.baragiotta: ça veut dire que : du module (standard) datetime on veut importer le nom datetime (14:34:40) davin.baragiotta: en gros : datetime.datetime (14:34:56) davin.baragiotta: vous voulez en savoir plus sur ce module? (14:35:07) davin.baragiotta: voir la doc officielle : http://docs.python.org/library/ (14:35:16) davin.baragiotta: cherchez datetime (14:35:21) davin.baragiotta: http://docs.python.org/library/datetime.html (14:35:23) davin.baragiotta: lisez ;) (14:35:44) davin.baragiotta: sinon, importez le module dans interpréteur et introspectez!!! : import datetime (14:35:51) davin.baragiotta: continuons (14:36:08) davin.baragiotta: import re = import du module d'expressions régulière (14:36:24) davin.baragiotta: en fait... tous les messages échangés nous arrivent comme des lignes de texte.... (14:36:47) davin.baragiotta: on veut pouvoir chercher des mots dans les lignes pour trouver les commandes données au bot! (14:36:59) davin.baragiotta: re = regex = regular expression (14:37:09) davin.baragiotta: http://docs.python.org/library/re.html (14:37:17) davin.baragiotta: un petit monde en soit au niveau de la syntaxe (14:37:20) davin.baragiotta: on continue (14:37:39) davin.baragiotta: après mes imports de la librairie standard (14:37:59) davin.baragiotta: j'importe les modules particuliers installés dans mon système... (14:38:22) davin.baragiotta: jabberbot est accessible car vous l'avez installé via un paquet Debian avant l'atelier (14:38:33) davin.baragiotta: il est accessible par son nom de module python (14:39:03) davin.baragiotta: y'a 2 façons d'importer : from... import (14:39:25) davin.baragiotta: import re , par exemple, charge tout le module re (14:39:53) davin.baragiotta: ils sont accessible dans le code en préfixant les objets du module par le nom du module (14:39:58) davin.baragiotta: ex.: ligne 38 (14:40:08) davin.baragiotta: j'utilise compile de re en faisant re.compile (14:40:13) davin.baragiotta: from : (14:40:32) davin.baragiotta: charge seulement des noms spécifiques... accessibles directement (14:40:52) davin.baragiotta: ex.: MUCJabberBot ligne 10 (14:40:55) davin.baragiotta: chargé à la ligne 8 (14:41:09) davin.baragiotta: ligne 8 : muc vient d'où? (14:41:16) davin.baragiotta: il vient de *mon* module bot (14:41:28) davin.baragiotta: le répertoire bot est lui même un module (14:41:53) davin.baragiotta: on l'a pas installé sur notre système... mais il est accessible dans le contexte (14:42:08) davin.baragiotta: pour importer des éléments d'un autre script (14:42:16) davin.baragiotta: créez un module (14:42:18) davin.baragiotta: comment ? (14:42:31) davin.baragiotta: en mettant un fichier __init__.py dans un répertoire (14:42:43) davin.baragiotta: grace à bot/__init__.py (14:43:01) davin.baragiotta: on peut importer du contenu de ce répertoire (14:43:06) davin.baragiotta: preuve (14:43:20) davin.baragiotta: ligne 8 importe du fichier bot/muc.py (14:43:25) davin.baragiotta: Des questions sur l'import? (14:43:32) davin.baragiotta: après on personnalise votre bot (14:43:50) davin.baragiotta: Questions? (14:44:15) olivier.larcheveque: Non pas de questions (14:44:40) olivier.larcheveque: (quelques petits soucis avec les versions de jabberbot) (14:45:23) davin.baragiotta: ok puor ceux qui ont un bot qui marche, ont va le personnaliser (14:45:58) davin.baragiotta: copiez la ligne 38 et collez dessous en ligne 39 (14:46:17) davin.baragiotta: modifiez le mot dans le "bière" dans le regex (14:46:43) davin.baragiotta: exemple : self.re_biere = re.compile(u'.*(?P<biere>bi[eè]re).*') self.re_biere = re.compile(u'.*(?P<hourra>hourra).*') (14:46:53) willy: QUESTION: que signifie exactement @botcmd ? (14:46:58) davin.baragiotta: avec ça, un surveille le mot hourra dans les chaine (14:47:07) davin.baragiotta: botcmd est un décorateur (14:47:15) davin.baragiotta: une fonction qui s'exécute avant une fonction (14:47:30) davin.baragiotta: mais globalement, ici, ça veut dire que la fonction qui suit (14:47:34) davin.baragiotta: est une "commande du bot" (14:47:48) davin.baragiotta: donc en tapant ce mot : la fonction codée s'exécute (14:48:00) davin.baragiotta: il y a 2 approches pour l'interaction du bot : (14:48:17) davin.baragiotta: une commande ou il cherche un mot par regex (14:48:29) davin.baragiotta: ici on va personnaliser en mettant un mot dans regex (14:48:47) davin.baragiotta: je continue mon exemple perso avec hourra (mettez ce que vous voulez pour vous) (14:49:00) davin.baragiotta: donc on a ligne 39 cloné et modifié la ligne 38 (14:49:31) davin.baragiotta: ligne 50 et 51 : copier et coller dessous (14:50:05) davin.baragiotta: ah zut... il faut modifier le nom d'attribut en ligne 39 aussi : (14:50:14) davin.baragiotta: 38 et 39 : self.re_biere = re.compile(u'.*(?P<biere>bi[eè]re).*') self.re_hourra = re.compile(u'.*(?P<hourra>hourra).*') (14:50:31) davin.baragiotta: 50 et 51 : if self.re_biere.match(message): self.biere(mess) if self.re_hourra.match(message): self.hourra(mess) (14:50:57) davin.baragiotta: avec ça on vient de dire si le message match le pattern (regex) écrit dans self.re_hourra (14:51:14) davin.baragiotta: alors on exécute la méthode (fonction) hourra... (14:51:15) davin.baragiotta: mais elle n'existe pas encore : créons là (14:51:35) davin.baragiotta: copipez-collez def biere au grand complet, jusqu'au return (14:51:48) davin.baragiotta: et modifier tout pour personnaliser (14:52:21) davin.baragiotta: en fait, faut juste modifier le nom de la méthode (derrière le def) et éditer la réponse (14:52:22) davin.baragiotta: ex.: (14:52:38) davin.baragiotta: def biere(self, mess): """Aux messages relatifs à la bière, choisit une de ses réponses prédéfinies""" username = self.get_sender_username(mess) if username != self.username and username != self.nickname: response = 'St-Ambroise!' self.send_simple_reply(mess, response) def hourra(self, mess): """Aux messages relatifs à la bière, choisit une de ses réponses prédéfinies""" username = self.get_sender_username(mess) if username != self.username and username != self.nickname: response = 'Non... pas hourra.' self.send_simple_reply(mess, response) (14:52:57) davin.baragiotta: pour tester le nouveau comportement du bot : (14:53:11) davin.baragiotta: fermer dans votre terminal le bot en core : Ctrl + C (14:53:13) davin.baragiotta: *en cours (14:53:27) davin.baragiotta: et attendre qu'il sorte du salon test (peut être un peu long) (14:53:42) davin.baragiotta: puis après relancer le bot : run bot/bot.py (14:55:29) davin.baragiotta: bon j'attends toujours la déconnexion de mon bot barabotta... :( (14:56:34) olivier.larcheveque: (Il reste 5min si les gens ont des questions) (14:56:36) progfou: reviens avec une autre "resource" pour ne pas perdre de temps... (14:56:38) davin.baragiotta: vous pouvez personnaliser, évidemment, en modifiant seulement les lignes de réponse pour les méthodes biere et sieste (14:58:43) davin.baragiotta: ok (14:58:50) davin.baragiotta: vous pouvez essayez mon hourra ;) (14:58:54) davin.baragiotta: questions? MR 20110829T13:57:54Z 000 <davin.baragiotta> fermez les bots MR 20110829T13:57:58Z 000 <davin.baragiotta> avec ctrl + c MR 20110829T13:58:03Z 000 <davin.baragiotta> si boucle sans fin MR 20110829T13:58:05Z 000 <davin.baragiotta> ;) MR 20110829T13:58:44Z 000 <olivier.larcheveque> -----------------------FIN : ATELIER : programmation Python ----------------------- MI 20110829T14:00:17Z 002 willy has set the topic to: ☞ Le salon de la Semaine Tech ☜ Atelier "Django" https://wiki.auf.org/wikiteki/Projet/SemaineTech/Ateliers/Django MR 20110829T14:03:21Z 000 <davin.baragiotta> petit interlude entre ateliers MR 20110829T14:03:34Z 000 <davin.baragiotta> on a eu dans test... là où vivent encore nos bots MR 20110829T14:03:37Z 000 <davin.baragiotta> un boucle sans fin MR 20110829T14:04:12Z 000 <davin.baragiotta> ça arrive quand un bot réagit à un mot... et retourne ce même MR 20110829T14:04:23Z 000 <davin.baragiotta> on peut éviter en vérifiant qu'on ne se répond pas à soit MR 20110829T14:04:24Z 000 <davin.baragiotta> mais MR 20110829T14:04:54Z 000 <davin.baragiotta> si un bot réagit à hourra et répondant hourra... et qu'un autre bot fait pareil : réagit à hourra en disant hourra MR 20110829T14:05:14Z 000 <davin.baragiotta> même si chaque bot s'ignore soit même... ben... MR 20110829T14:05:31Z 000 <davin.baragiotta> il répond à l'autre qui lui répond qui fait répodnre l'autre qui... MR 20110829T14:05:36Z 000 <davin.baragiotta> un boucle *entre* les bot MR 20110829T14:05:57Z 000 <davin.baragiotta> en gros... c'est en testant qu'on blinde son code ;) MR 20110829T14:06:01Z 000 <davin.baragiotta> fin de l'interlude MR 20110829T14:06:45Z 001 <davin.baragiotta> progfou faisant remarquer : (10:06:13) progfou: et en fait même, plus généralement, qu'un bot ne devrait pas traiter des messages sans préfixe déterminé (son nom, un '!', ...) MR 20110829T14:06:57Z 000 <davin.baragiotta> c'est une solution... mais ça enlève son côté humain ;) MR 20110829T14:07:13Z 000 <progfou> ouaip, ça en fait un bot ;-) MR 20110829T14:07:18Z 000 <davin.baragiotta> :D MR 20110829T14:08:17Z 000 <progfou> Olivier, si tu es prêt n'attendons pas, ce n'est pas bon de s'éloigner des horaires (certaines personnes peuvent avoir prévu autre chose après, à l'heure pile, et d'autres auront envie de dormir, suivez mon regard...) MR 20110829T14:08:54Z 000 <olivier.larcheveque> ok on y va