[PageD'Accueil] [IndexDesTitres] [IndexDesTermes

Divers

Extraire des adresses email

Comment extraire les adresses email de n'importe quel fichier en 2 lignes de code !
http://sebsauvage.net/python/email_extractor.py
Il s'utilise de la façon suivante: python email_extractor.py < monfichier.html

Recuperer une variable d'environnement

   1 import os
   2 
   3 os.environ['USER']

Connaitre le chemin du répertoire dans lequel se trouve le script en cours

Ceci peut s'avérer utile, par exemple pour importer d'autres modules se trouvant dans ledit répertoire...

   1 import os, os.path
   2 print os.path.dirname(os.path.realpath(__file__))

Attention: il semble que sous Windows XP, file contienne le chemin complet. Ce n'est pas le cas sous Linux !. La solution consistant à utiliser os.path.dirname(file) n'est donc pas portable.

Connaître le chemin du répertoire 'home' de l'utilisateur

Cette astuce fonctionne sous Linux, mais aussi sous MacOS X et Windows. Pratique pour sauvegarder un fichier de configuration (par exemple).

   1 import os.path
   2 print os.path.expanduser('~')

Une fonction qui renvoie plusieurs valeurs

En Python, il est très facile de faire une fonction qui renvoie plusieurs valeur en même temps.

>>> def mafonction(a):
        return (a+1,a*2,a*a)
>>> print mafonction(3)
(4, 6, 9)

(En effet, les tuple (4,6,9), listes et dictionnaires sont des types de base de Python : on peut donc les utiliser partout où vous auriez utilisé d'autres types de données (entiers, chaînes...)).

N'oubliez pas que vous avez la possibilité de faire de l'assignation multiple:

>>> (g,h,i) = mafonction(7)
>>> print g
8
>>> print h
14
>>> print i
49
>>>

Obtenir la date en francais

Par défaut, pour garder la compatibilité avec la norme Posix, Python ne prend pas en compte les variables LANG sur unix ( http://www.python.org/doc/current/lib/module-locale.html ). Ce qui fait que la fonction strftime travaille par défaut en anglais. Il suffit donc de positionner la valeur des locales à la valeur par défaut avec setlocale.

>>> import time
>>> time.strftime('%c')
'Sun Jun 27 21:50:11 2004'
>>> import locale
>>> locale.setlocale(locale.LC_ALL,'')
'fr_FR'
>>> time.strftime('%c')
'dim 27 jun 2004 21:50:32 CEST'

Passer des paramètres en nombre variables à une fonction sans se soucier de leur ordre

le prototype d'une fonction est en réalité: function(args, *args, **kwargs) ou args est une liste classique de paramètres séparés par des ',', args est une variable de type list contenant la liste des paramètres et le plus intéressant se trouve dans kwargs qui est un dictionnaire (type dict) dont les clefs sont les paramètres, et leurs valeurs, les valeurs des paramètres. Ce qui permet de nombreuses possibilités d'utilisation des fonctions dans un cadre disont plus dynamique.

Vérifier qu'une variable est bien d'un certain type

Il existe le mot clef type qui permet de le savoir mais son utilisation est obsolète de par l'existence de la fonction isinstance(object, class) qui permet de savoir si l'objet "object" est une instance de la classe "class" et retourne True dans ce cas, False sinon.

Attention toutefois à ne pas utiliser isinstance() sans raison: Python est un langage à typage dynamique, et le plus souvent le type exact d'un objet est sans importance du moment que l'objet implémente bien l'interface attendue. Par exemple, une fonction originellement destinée à écrire dans un fichier (en utlisant la méthode write() de la classe file) peut fonctionner aussi bien avec n'importe quel objet implémentant la méthode write() (in StringIO par exemple). Tester si l'objet passé est effectivement une instance de la classe file limiterait inutilement les utilisations possibles de cette fonction.

Disposer d'un dictionnaire ou d'une liste ne levant pas d'exception en cas d'absence d'indice ou de clef

Il suffit de créér une classe qui héritera de dict ou de list qui réécrit la méthode getitem pour vérifier que l'item demandé fait bien partie de l'objet. ex:

   1 class Ndict(dict):
   2     """ customized dict, don't raise KeyError exception, return None instead """
   3     def __getitem__(self, key):
   4         if self.has_key(key):
   5             return dict.__getitem__(self, key)
   6         else:
   7             return None

idem pour une liste:

   1 class Nlist(list):
   2     """ customized list, don't raise IndexError exception, return None instead """
   3     def __getitem__(self, index):
   4         if index < len(self):
   5             return list.__getitem__(self, index)
   6         else:
   7             return None

ensuite à l'utilisation il suffit d'instancier la classe désirée puis l'utiliser comme un dictionnaire ou une liste classique mis à part cette petite différence.

>>> l = Nlist()
>>> print l
[]
>>> print l[3]
>>> 
>>> d = Ndict()
>>> print d
{}
>>> print l['toto']
>>> 

PDF

Codes utilisants la librairie http://www.reportlab.com

BaseDocTemplate

Permet de générer des tableaux sur plusieurs pages avec gestion des entêtes...

Thread

Voici un exemple de thread avec dialogue par file de message

   1 import threading 
   2 import time
   3 import Queue
   4 
   5 bal = Queue.Queue (100)
   6 test = 10
   7 class myThread(threading.Thread):
   8     def __init__(self, name=None):
   9         threading.Thread.__init__(self, target=self.run, name=name, args=() )
  10         self.start()
  11 
  12     def run(self):
  13         for i in range(test):
  14             print self.getName(), i
  15             bal.put ("Msg %d from %s"%(i,self.getName()))
  16             time.sleep (0.2)
  17 
  18 
  19 def main ():
  20     t1 = myThread("Thread(1)")
  21     t2 = myThread("Thread(2)")
  22 
  23     for i in range (test*2):
  24         msg = bal.get ()
  25         print "Reception message :", msg
  26 
  27 if __name__=="__main__":
  28     main ()

Test unitaire

Exemple de test unitaire d'une fonction de division

   1 import unittest
   2 
   3 def divide (value1, value2):
   4     return value1 / value2
   5 
   6 class DivisionValue(unittest.TestCase):
   7     values = ( ( 1., 1., 1.),
   8                ( 3., 2., 1.5) )
   9     def testDivide (self):
  10         """ Test division correcte """
  11         for value1, value2, result in self.values:
  12             res = divide(value1, value2)
  13             self.assertEqual (res, result)
  14             
  15     def testTypeError (self):
  16         """ Test mauvais type """
  17         self.assertRaises (TypeError, divide, 1, "2")
  18         
  19     def testZeroDivisionError (self):  
  20         """ Test division par zéro """
  21         self.assertRaises (ZeroDivisionError, divide, 1., 0.)
  22         
  23             
  24 if __name__ == "__main__":
  25     unittest.main()   

Utilisation de la bibliothèque cmd

Le principe est simple: vous définissez des méthodes commançant par do_ comme do_hello_world. Dans l'interpréteur, vous pouvez appeler ces fonctions par le nom de la méthode mais sans le do_. Après le code se trouve un exemple de session.

   1 #!/usr/bin/env python
   2 import cmd
   3 import os
   4 
   5 class SimpleCmdInterpretor(cmd.Cmd):
   6 
   7     def __init__(self):
   8         self.prompt = ">?>"
   9         self.intro = """This is a very simple command line Interpreter.
  10                      Type ? for help.
  11                      Type ! for Python subshell."""
  12 
  13     def emptyline(self):
  14         print "Type 'exit' to terminate the session or type ? for help."
  15 
  16     def default(self, line):
  17         print "*** Unknown Syntax : %s (type help for a list of valid command"%line
  18 
  19     def do_shell(self, arg):
  20         """\nLaunches the Python Interpreter.\n"""
  21         os.system("python")
  22 
  23     def do_exit(self, arg):
  24         """\nTerminates the session.\n"""
  25         return -1
  26 
  27 ## vos méthodes personnelles:
  28 
  29     def do_hello_world(self, arg):
  30         """\nPrints Hello 'arg'"""
  31         print 'Hello %s' % arg
  32 
  33 def _test(): 
  34     my_cmd = SimpleCmdInterpretor()
  35     my_cmd.cmdloop()
  36 
  37 if __name__ == "__main__":
  38     _test()

Exemple de session:

[oli@argyro]~/dev/python/gui/cmd/basic -> python cmd_interpretor.py
This is a small command line Interpreter.
Type ? for help.
Type ! for Python subshell.
>?>help

Documented commands (type help <topic>):
========================================
exit            hello_world     shell

Undocumented commands:
======================
help

>?>help hello_world

Prints Hello 'arg'
>?>hello_world Toto
Hello Toto
>?>exit
[oli@argyro]~/dev/python/gui/cmd/basic ->

Filtre Bayesien

Les filtres Baysesiens permettent de classifier des données. Par exemple, ils sont de plus en plus utilisés pour filtrer le spam (emails publicitaires).

Reverend est un filtre baysien écrit en 100% Python et opensource.

Prenons un exemple: reconnaître la langue d'un texte.

Tout d'abord, entraînons notre filtre bayesien sur quelques phrases:

   1 from reverend.thomas import Bayes
   2 guesser = Bayes()
   3 guesser.train('french','La souris est rentrée dans son trou.')
   4 guesser.train('english','my tailor is rich.')
   5 guesser.train('french','Je ne sais pas si je viendrai demain.')
   6 guesser.train('english','I do not plan to update my website soon.')

Et maintenant, laissons-le deviner:

>>> print guesser.guess('Jumping out of cliffs it not a good idea.')
[('english', 0.99990000000000001), ('french', 9.9999999999988987e-005)]

Le filtre bayesien dit "C'est anglais avec une probabilité de 99,99%."

Faisons un autre essai:

>>> print guesser.guess('Demain il fera très probablement chaud.')
[('french', 0.99990000000000001), ('english', 9.9999999999988987e-005)]

ça dit: "C'est français avec une probabilité de 99,99%."
Pas mal, non ?

Vous pouvez même l'entraîner sur d'autres langues en même temps. Ou même l'entraîner à classifier n'importe quel type de texte selon vos critères.

Crypter du texte

Il est très facile de faire un algorithme de cryptage en python comme suit:

   1 def crypt(texte,motdepasse):
   2     index=0
   3     final=''
   4     for lettre in texte:
   5         lettre=ord(lettre)
   6         lettre+=ord(motdepasse[index])
   7         if lettre>255:lettre-=256
   8         lettre=chr(lettre)
   9         final+=lettre
  10         index+=1
  11         if index>=len(motdepasse):index=0
  12     return final

et pour décrypter:

   1 def decrypt(texte,motdepasse):
   2     index=0
   3     final=''
   4     for lettre in texte:
   5         lettre=ord(lettre)
   6         lettre-=ord(motdepasse[index])
   7         if lettre<0:lettre+=256
   8         lettre=chr(lettre)
   9         final+=lettre
  10         index+=1
  11         if index>=len(motdepasse):index=0
  12     return final

Hachage MD5 d'une chaine de caractères

Pour conserver un mot de passe, ou pour garder une trace d'un fichier, il peut être utile de générer une signature numérique en MD5.

   1 import md5
   2 chaine = raw_input("Entrez le texte à crypter en MD5:");
   3 hashage = md5.new(chaine);
   4 print(hashage.hexdigest());

Hachage SHA d'une chaine de caractères

De même que le hachage en MD5, l'algorithme SHA produit une signature plus longue et plus sécurisé. De plus ce code utilise une variable aléatoire stockée en clair qui permet d'obtenir des signatures différentes pour une même chaine.

   1 import sha
   2 import random
   3 chaine = raw_input("Entrez le texte à crypter en SHA1:");
   4 sel = str(random.random()) 
   5 hashage = sha.new(chaine+sel);
   6 print sel
   7 print(hashage.hexdigest());

Inclure de petits fichiers dans vos sources

Ils parfois utile d'embarquer de petits fichiers binaires à l'intérieur de ses sources.

Prenons un fichier (monimage.gif), et convertissons-là en base64 (et accessoirement, nous le compressons avec zlib):

   1 import base64,zlib
   2 data = open('monimage.gif','rb').read()
   3 print base64.encodestring(zlib.compress(data))

On récupère le texte créé par ce programme, et on peut l'inclure directement dans le source de votre programme:

   1 import base64,zlib
   2 monfichier = zlib.decompress(base64.decodestring("""
   3 eJxz93SzsExUZlBn2MzA8P///zNnzvz79+/IgUMTJ05cu2aNaBmDzhIGHj7u58+fO11ksLO3Kyou
   4 ikqIEvLkcYyxV/zJwsgABDogAmQGA8t/gROejlpLMuau+j+1QdQxk20xwzqhslmHH5/xC94Q58ST
   5 72nRllBw7cUDHZYbL8VtLOYbP/b6LhXB7tAcfPCpHA/fSvcJb1jZWB9c2/3XLmQ+03mZBBP+GOak
   6 /AAZGXPL1BJe39jqjoqEAhFr1fBi1dao9g4Ovjo+lh6GFDVWJqbisLKoCq5p1X5s/Jw9IenrFvUz
   7 +mRXTeviY+4p2sKUflA1cjkX37TKWYwFzRpFYeqTs2fOqEuwXsfgOeGCfmZ57MP4WSpaZ0vSJy97
   8 WPeY5ca8F1sYI5f5r2bjec+67nmaTcarm7+Z0hgY2Z7++fpCzHmBQCrPF94dAi/jj1oZt8R4qxsy
   9 6liJX/UVyLjwoHFxFK/VMWbN90rNrLKMGQ7iQSc7mXgTkpwPXVp0mlWz/JVC4NK0s0zcDWkcFxxF
  10 mrvdlBdOnBySvtNvq8SBFZo8rF2MvAIMoZoPmZrZPj2buEDr2isXi0V8egpelyUvbXNc7yVQkKgS
  11 sM7g0KOr7kq3WRIkitSuRj1VXbSk8v4zh8fljqtOhyobP91izvh0c2hwqKz3jPaHhvMMXVQspYq8
  12 aiV9ivkmHri5u2NH8fvPpVWuK65I3OMUX+f4Lee+3Hmfux96Vq5RVqxTN38YeK3wRbVz5v06FSYG
  13 awWFgMzkktKiVIXkotTEktQUhaRKheDUpMTikszUPIVgx9AwR3dXBZvi1KTixNKyxPRUhcQSBSRe
  14 Sn6JQl5qiZ2CrkJGSUmBlb4+QlIPKKGgAADBbgMp"""))
  15 
  16 print "J'ai un fichier de %d octets." % len(monfichier)

Par exemple, si vous utilisez PIL (Python Imaging Library), vous pouvez charger directement cette image pour l'utiliser:

   1 import Image,StringIO
   2 monimage = Image.open(StringIO.StringIO(monfichier))
   3 monimage.show()

La machine virtuelle Python

Python - tout comme Java ou Microsoft .Net (C#) - possède une machine virtuelle.

C'est à dire que les programmes Python sont transformé dans un langage machine (appelé bytecode) spécifique à Python. Mais il n'existe aucun microprocesseur physique capable de comprendre ce langage machine ! (Au contraire du langage machine Intel x86 (Pentium)).

Python, Java et .Net possèdent donc chacun un programme qui simule un microprocesseur capable de comprendre leur langage machine respectif: c'est la machine virtuelle.

Le bytecode Python est différent de celui de Java, qui est différent de celui de .Net.

Un exemple

Créons un petit programme simple: sauvegardez le texte suivant dans le fichier monprogramme.py:

   1 def mafonction(a):
   2     print "J'ai",a
   3     b = a * 3
   4     if b<50:
   5       b = b + 77
   6     return b

Cette fonction prend un nombre en entrée, l'affiche, puis le multiplie par 3. Si le résultat est inférieur à 50, elle ajoute 77. Puis elle renvoie le résultat.

On va ensuite "compiler" le programme et l'utiliser:

C:\>python
Python 2.3.4 (#53, May 25 2004, 21:17:02) [MSC v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import monprogramme
>>> print monprogramme.mafonction(5)
J'ai 5
92
>>>

Le fait de taper import monprogramme va compiler le programme et créer le fichier monprogramme.pyc.

On peut ensuite désassembler:

>>> import dis
>>> print dis.dis(monprogramme.mafonction)
  2           0 LOAD_CONST               1 ("J'ai")
              3 PRINT_ITEM
              4 LOAD_FAST                0 (a)
              7 PRINT_ITEM
              8 PRINT_NEWLINE

  3           9 LOAD_FAST                0 (a)
             12 LOAD_CONST               2 (3)
             15 BINARY_MULTIPLY
             16 STORE_FAST               1 (b)

  4          19 LOAD_FAST                1 (b)
             22 LOAD_CONST               3 (50)
             25 COMPARE_OP               0 (<)
             28 JUMP_IF_FALSE           14 (to 45)
             31 POP_TOP

  5          32 LOAD_FAST                1 (b)
             35 LOAD_CONST               4 (77)
             38 BINARY_ADD
             39 STORE_FAST               1 (b)
             42 JUMP_FORWARD             1 (to 46)
        >>   45 POP_TOP

  6     >>   46 LOAD_FAST                1 (b)
             49 RETURN_VALUE
             50 LOAD_CONST               0 (None)
             53 RETURN_VALUE
None
>>>

La colonne de gauche indique la ligne correspondante dans le code source (dans monprogramme.py).

Si on prend la ligne 3 du programme (b = a * 3), on peut retrouver l'opération:

Vous pourrez également y retrouver les autres opération (affichage avec PRINT_ITEM, le if réalisé avec COMPARE_OP et JUMP_IF_FALSE, etc.) La liste des opératiosn est disponibles dans la documentation de Python : http://www.python.org/doc/current/lib/bytecodes.html

Chaque fois que vous importez un module, Python va créer le .pyc (bytecode) correspondant pour ne pas avoir à re-lire le code source à chaque fois. Si vous supprimez le .pyc, Python le re-crééera automatiquement dès que vous importerez à nouveau le module. Si vous modifiez le code source .py correspondant, Python détectera automatiquement ce changement dès que vous ré-importerez le module, et re-créera le .pyc.

Un fichier .pyc peut être exécuté directement, même si vous n'avez pas le .py correspondant.

Ce mécanisme permet à Python de compiler uniquement à la demande, et de garder le code pre-compilé pour la fois suivante afin d'aller plus vite.


2016-06-05 21:42