Initiation à la programmation ENSAE 1A

support de cours, version longue

File: chap1_introduction.tex, line 185


>>> x = 3
>>> y = 6 
>>> z = x * y
>>> print z
18
>>>

File: chap1_introduction.tex, line 258


if PLAT_WIN
    command.go.*.py=python -u "$(FileNameExt)"
    command.go.subsystem.*.py=0
    command.go.*.pyw=pythonw -u "$(FileNameExt)"
    command.go.subsystem.*.pyw=1

File: chap1_introduction.tex, line 266


if PLAT_WIN
    command.go.*.py=c:\Python26\python -u "$(FileNameExt)"
    command.go.subsystem.*.py=0
    command.go.*.pyw=c:\Python26\pythonw -u "$(FileNameExt)"
    command.go.subsystem.*.pyw=1

File: chap1_introduction.tex, line 340


print "premier message"

File: chap1_introduction.tex, line 344


print 3.141592 * 5*5
print 3.141592 * 5**2

File: chap1_introduction.tex, line 349


from math import *  # permet d'utiliser les extensions mathématiques de Python
print pi * 5**2

File: chap1_introduction.tex, line 356


print (3.141592 * 5*5)

File: chap1_introduction.tex, line 366


print "accentué"

File: chap1_introduction.tex, line 372


  File "essai.py", line 1
SyntaxError: Non-ASCII character '\xe9' in file i.py on line 1, 
             but no encoding declared; 
             see http://www.python.org/peps/pep-0263.html for details

File: chap1_introduction.tex, line 381


# coding: latin-1
print "accentué"

File: chap1_introduction.tex, line 390


# coding: cp1252
print "accentué"

File: chap1_introduction.tex, line 399


# coding: utf-8
print "accentué"

File: chap1_introduction.tex, line 411


#!/usr/local/bin/python

File: chap1_introduction.tex, line 524


import psyco
psyco.full ()

File: chap1_introduction.tex, line 596


import matplotlib.pylab as pylab

File: chap1_introduction.tex, line 603


#!/usr/bin/env pythonw2.6
import matplotlib
matplotlib.use("WXAgg")
import matplotlib.pylab as pylab

File: chap1_introduction.tex, line 618


2004-08-07 21:08:15.153 Python[695] *** _NSAutoreleaseNoPool(): Object
0x30ead0 of class NSCFArray autoreleased with no pool in place - just
leaking

File: chap2_type.tex, line 22


somme = 0                   # initialisation : la somme est nulle 
for i in range(1,n) :       # pour tous les indices de 1 à n exclu
    somme = somme + i       # on ajoute le i ème élément à somme

File: chap2_type.tex, line 55


x   = 3.5      # création d'une variable nombre réel appelée x initialisée à 3.5
               # 3.5 est un réel, la variable est de type "float"
sc = "chaîne"  # création d'une variable chaîne de caractères appelée str 
               # initialisée à "chaîne", sc est de type "str"

File: chap2_type.tex, line 70


x = 3          # affectation de la valeur entière 3 à la variable x
y = 3.0        # affectation de la valeur réelle 3.0 à la variable y

File: chap2_type.tex, line 83


x = 
    5.5

File: chap2_type.tex, line 94


x =  \
    5.5

File: chap2_type.tex, line 128


s = None
print s    # affiche None

File: chap2_type.tex, line 146


x = 3
y = 3.0
print "x =", x, type(x)
print "y =", y, type(y)

File: chap2_type.tex, line 155




x = 3 <type 'int'>
y = 3.0 <type 'float'>

File: chap2_type.tex, line 196


x = int (3.5)
y = float (3)
z = int ("3")
print "x:", type(x), "   y:", type(y), "   z:", type(z)
# affiche   x: <type 'int'>    y: <type 'float'>    z: <type 'int'>

File: chap2_type.tex, line 207


i = int ("3.5")          # provoque une erreur
i = int (float ("3.5"))  # fonctionne

File: chap2_type.tex, line 221


x = 11
y = 2
z = x / y      # le résultat est 5 et non 5.5 car la division est entière

File: chap2_type.tex, line 229


x = float (11)
y = float (2)
z = x / y      # le résultat est 5.5 car c'est une division entre deux réels

File: chap2_type.tex, line 255


x = 4 < 5
print x         # affiche True
print not x     # affiche False

File: chap2_type.tex, line 287


x = True
y = False

File: chap2_type.tex, line 309


t = "string = texte"
print type (t), t
t = 'string = texte, initialisation avec apostrophes'
print type (t), t

t = "morceau 1" \
    "morceau 2"    # second morceau ajouté au premier par l'ajout du symbole \, 
                   # il ne doit rien y avoir après le symbole \, 
                   # pas d'espace ni de commentaire
print t

t = """première ligne		
seconde ligne"""   # chaîne de caractères qui s'étend sur deux lignes
print t

File: chap2_type.tex, line 330


<type 'str'> string = texte
<type 'str'> string = texte, initialisation avec apostrophes
morceau 1morceau 2
première ligne
seconde ligne

File: chap2_type.tex, line 374


s = "C:\\Users\\Dupre\\exemple.txt"
s = r"C:\Users\Dupre\exemple.txt"

File: chap2_type.tex, line 395


x = 5.567
s = str (x)
print type(s), s   # <type 'str'> 5.567
print len(s)       # affiche 5

File: chap2_type.tex, line 444



res = s.fonction (...)

File: chap2_type.tex, line 535


st = "langage python"
st = st.upper ()              # mise en lettres majuscules
i  = st.find ("PYTHON")       # on cherche "PYTHON" dans st
print i                       # affiche 8
print st.count ("PYTHON")     # affiche 1
print st.count ("PYTHON", 9)  # affiche 0

File: chap2_type.tex, line 549


s    = "un;deux;trois"
mots = s.split (";")        # mots est égal à ['un', 'deux', 'trois']
mots.reverse ()             # retourne la liste, mots devient égal à 
                            #                 ['trois', 'deux', 'un']
s2 = ";".join (mots)        # concaténation des éléments de mots séparés par ";"
print s2                    # affiche trois;deux;un

File: chap2_type.tex, line 569



".... %c1  ....  %c2 " % (v1,v2)

File: chap2_type.tex, line 579


x = 5.5
d = 7
s = "caractères"
res =   "un nombre réel %f et un entier %d, une chaîne de %s, \n" \
        "un réel d'abord converti en chaîne de caractères %s" % (x,d,s, str(x+4))
print res        
res =   "un nombre réel " + str (x) + " et un entier " + str (d) + \
        ", une chaîne de " + s + \
        ",\n un réel d'abord converti en chaîne de caractères " + str(x+4)
print res        

File: chap2_type.tex, line 595


un nombre réel 5.500000 et un entier 7, une chaîne de caractères, 
un réel d'abord converti en chaîne de caractères 9.5
un nombre réel 5.5 et un entier 7, une chaîne de caractères,
un réel d'abord converti en chaîne de caractères 9.5

File: chap2_type.tex, line 606



"%n.df" % x

File: chap2_type.tex, line 618


x = 0.123456789
print x             # affiche 0.123456789
print "%1.2f" % x   # affiche 0.12
print "%06.2f" % x  # affiche 000.12

File: chap2_type.tex, line 651


x = (4,5)               # création d'un T-uple composé de 2 entiers
x = ("un",1,"deux",2)   # création d'un T-uple composé de 2 chaînes de caractères
                        # et de 2 entiers, l'ordre d'écriture est important
x = (3,)                # création d'un T-uple d'un élément, sans la virgule, 
                        # le résultat est un entier

File: chap2_type.tex, line 713


a     = (4,5)
a [0] = 3      # déclenche une erreur d'exécution

File: chap2_type.tex, line 720


Traceback (most recent call last):
  File "<pyshell#78>", line 1, in -toplevel-
    a[0]=3
TypeError: object doesn't support item assignment

File: chap2_type.tex, line 729


a = (4,5)
a = (3,) + a[1:2]  # crée un T-uple d'un élément concaténé 
                   # avec la partie inchangée de a

File: chap2_type.tex, line 745


print complex (1,1)   # affiche (1+1j)

File: chap2_type.tex, line 786


x = [4,5]               # création d'une liste composée de deux entiers
x = ["un",1,"deux",2]   # création d'une liste composée de 
                        # deux chaînes de caractères
                        # et de deux entiers, l'ordre d'écriture est important
x = [3,]                # création d'une liste d'un élément, sans la virgule, 
                        # le résultat reste une liste
x = [ ]                 # crée une liste vide
x = list ()             # crée une liste vide
y = x [0]               # accède au premier élément
y = x [-1]              # accède au dernier élément

File: chap2_type.tex, line 958


[9, 0, 3, 5, 4, 7, 8]
[0, 3, 4, 5, 7, 8, 9]

File: chap2_type.tex, line 964


def compare (x,y):           # crée une fonction
    if   x >  y : return -1  # qui retourne -1 si x<y,
    elif x == y : return 0   # 0 si x == y
    else        : return 1   # 1 si x < y

x.sort (compare)             # trie la liste x à l'aide de la fonction compare
                             # cela revient à la trier par ordre décroissant
print x

File: chap2_type.tex, line 979


[9, 8, 7, 5, 4, 3, 0]

File: chap2_type.tex, line 987


x = [9,0,3,5,0]
print x.index (1) # cherche la position de l'élément 1

File: chap2_type.tex, line 996


Traceback (most recent call last):
  File "c:/temp/temp", line 2, in -toplevel-
    print x.index(1)
ValueError: list.index(x): x not in list

File: chap2_type.tex, line 1007


x = [9,0,3,5,0]
try:               print x.index(1)
except ValueError: print "1 n'est pas présent dans la liste x"
else:              print "trouvé"

File: chap2_type.tex, line 1018


1 n'est pas présent dans la liste x

File: chap2_type.tex, line 1030



range (debut, fin [,marche])

File: chap2_type.tex, line 1043


print range (0,10,2)       # affiche [0, 2, 4, 6, 8]

File: chap2_type.tex, line 1051


print xrange (0,10,2)      # affiche xrange(0,10,2)

File: chap2_type.tex, line 1062


s = 0
for n in range (1,20,2) :  # ce programme est équivalent à
    s += n                 # s = sum (range(1,20,2))

File: chap2_type.tex, line 1073


x = ["un", 1, "deux", 2, "trois", 3]
for n in range (0, len(x)) :
    print "x [%d] = %s" % (n, x [n])
    
# le résultat est présenté à droite    
    

File: chap2_type.tex, line 1084


x [0] = un
x [1] = 1
x [2] = deux
x [3] = 2
x [4] = trois
x [5] = 3

File: chap2_type.tex, line 1105


x = ["un", 1, "deux", 2]
for el in x :  
    print "la liste inclut : ", el

File: chap2_type.tex, line 1115


la liste inclut :  un
la liste inclut :  1
la liste inclut :  deux
la liste inclut :  2

File: chap2_type.tex, line 1126


y = list ()
for i in range(0,5) : y.append (i+1)
print y                                # affiche [1,2,3,4,5]        

File: chap2_type.tex, line 1137


y = [ i+1 for i in range (0,5)]
print y                                # affiche [1,2,3,4,5]        

File: chap2_type.tex, line 1147


y = [ i for i in range(0,5) if i % 2 == 0]   # sélection les éléments pairs
print y                                      # affiche [0,2,4]        
z = [ i+j for i in range(0,5) \
          for j in range(0,5)]      # construit tous les nombres i+j possibles
print z                             # affiche [0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 
                                    # 3, 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]

File: chap2_type.tex, line 1162


a = (1,0,7,0,0,0)
b = [2,2,3,5,5,5]
c = [ "un", "deux", "trois", "quatre" ]
d = zip (a,b,c)
print d           # affiche [(1, 2, 'un'),    (0, 2, 'deux'), 
                  #          (7, 3, 'trois'), (0, 5, 'quatre')]

File: chap2_type.tex, line 1177


s = ""
while <condition> : s += ...
    

File: chap2_type.tex, line 1185


s = []
while <condition> : s.append ( ... )
s = "".join (s)

File: chap2_type.tex, line 1201


l  = [4,5,6]
l2 = l
print l            # affiche [4,5,6]
print l2           # affiche [4,5,6]
l2 [1] = "modif"
print l            # affiche [4, 'modif', 6]
print l2           # affiche [4, 'modif', 6]

File: chap2_type.tex, line 1213


l      = [[0,1], [2,3]]
l1     = l [0]
l1 [0] = "modif" # ligne équivalente à : l [0][0] = "modif"

File: chap2_type.tex, line 1223


import copy
l  = [4,5,6]
l2 = copy.copy(l)
print l            # affiche [4,5,6]
print l2           # affiche [4,5,6]
l2 [1] = "modif"
print l            # affiche [4,5,6]
print l2           # affiche [4, 'modif', 6]

File: chap2_type.tex, line 1238


import copy
l  = [1,2,3]
l2 = copy.copy (l)
l3 = l

print l == l2  # affiche True
print l is l2  # affiche False
print l is l3  # affiche True 

File: chap2_type.tex, line 1253


import copy
l  = [[1,2,3],[4,5,6]]
l2 = copy.copy (l)
l3 = copy.deepcopy (l)
l [0][0] = 1111
print l                # affiche [[1111, 2, 3], [4, 5, 6]]
print l2               # affiche [[1111, 2, 3], [4, 5, 6]]
print l3               # affiche [[1, 2, 3], [4, 5, 6]]
print l is l2          # affiche False
print l [0] is l2 [0]  # affiche True
print l [0] is l3 [0]  # affiche False

File: chap2_type.tex, line 1270


l     = [1,"a"]
ll    = [l,3]   # ll contient l
l [0] = ll      # l contient ll
print l         # affiche [[[...], 3], 'a']
print ll        # affiche [[[...], 'a'], 3]

import copy
z = copy.deepcopy (l)
print z         # affiche [[[...], 3], 'a']

File: chap2_type.tex, line 1306


x = { "cle1":"valeur1", "cle2":"valeur2" }
y = { }         # crée un dictionnaire vide
z = dict ()     # crée aussi un dictionnaire vide

File: chap2_type.tex, line 1316


print x ["cle1"]

File: chap2_type.tex, line 1443


d = { "un":1, "zéro":0, "deux":2, "trois":3, "quatre":4, "cinq":5, \
       "six":6, "sept":1, "huit":8, "neuf":9, "dix":10 }
key = d.keys ()
key.sort ()
for k in key:
    print k,d [k]

File: chap2_type.tex, line 1456


d = { "un":1,   "zero":0, "deux":2, "trois":3, "quatre":4, "cinq":5, \
      "six":6,  "sept":1, "huit":8, "neuf":9,  "dix":10 }
       
dinv = { }                      # création d'un dictionnaire vide, on parcout
for key,value in d.items ()  :  # les éléments du dictionnaire comme si
                                # c'était une liste de 2-uple (clé,valeur)
    dinv [value] = key          # on retourne le dictionnaire

print dinv                      # affiche {0: 'zero', 1: 'un', 2: 'deux', 
                                # 3: 'trois', 4: 'quatre', 5: 'cinq', 6: 'six', 
                                # 8: 'huit', 9: 'neuf', 10: 'dix'}

File: chap2_type.tex, line 1474


d = { "un":1, "zero":0, "deux":2, "trois":3, "quatre":4, "cinq":5, \
       "six":6, "sept":1, "huit":8, "neuf":9, "dix":10 }
print d.items ()
print d.iteritems ()

File: chap2_type.tex, line 1483


[('trois', 3), ('sept', 1), ('neuf', 9), ('six', 6), ('zero', 0), 
 ('un', 1), ('dix', 10), ('deux', 2), ('huit', 8), ('quatre', 4), 
                                                      ('cinq', 5)]
 
<dictionary-itemiterator object at 0x0115DC40>

File: chap2_type.tex, line 1495


  File "essai.py", line 6, in <module>
    for k in d :
RuntimeError: dictionary changed size during iteration

File: chap2_type.tex, line 1508


d  = {4:4,5:5,6:6}
d2 = d
print d            # affiche {4: 4, 5: 5, 6: 6}
print d2           # affiche {4: 4, 5: 5, 6: 6}
d2 [5] = "modif"
print d            # affiche {4: 4, 5: 'modif', 6: 6}
print d2           # affiche {4: 4, 5: 'modif', 6: 6}

File: chap2_type.tex, line 1523


d  = {4:4,5:5,6:6}
import copy
d2 = copy.copy(l)
print d            # affiche {4: 4, 5: 5, 6: 6}
print d2           # affiche {4: 4, 5: 5, 6: 6}
d2 [5] = "modif"
print d            # affiche {4: 4, 5: 5, 6: 6}
print d2           # affiche {4: 4, 5: 'modif', 6: 6}

File: chap2_type.tex, line 1544


k = { 1:1}
d = { }
d [k] = 0



File: chap2_type.tex, line 1554


Traceback (most recent call last):
  File "cledict.py", line 3, in <module>
    d [k] = 0
TypeError: dict objects are unhashable

File: chap2_type.tex, line 1567


k = { 1:1}
d = { }
d [id (k)] = 0

File: chap2_type.tex, line 1575


k = {1:1}
d = { }
d [id (k)] = 0
b = k
print d [id(b)]  # affiche bien zéro
c = {1:1}
print d [id(c)]  # provoque une erreur car même si k et c ont des contenus égaux,
                 # ils sont distincts, la clé id(c) n'existe pas dans d

File: chap2_type.tex, line 1590


class A : pass

k = A ()
d = { }
d [k] = 0
print d                   # affiche {<__main__.A object at 0x0120DB90>: 0}
print id (k), hex(id(k))  # affiche 18930576, 0x120db90
print d [id(k)]           # provoque une erreur

File: chap2_type.tex, line 1605


class A (dict):
    def __hash__(self):
        return id(self)
        
k = A ()
k ["t"]= 4
d = { }
d [k] = 0
print d         # affiche {{'t': 4}: 0}

File: chap2_type.tex, line 1635


x == eval (repr(x)) # est toujours vrai (True)
x == eval (str (x)) # n'est pas toujours vrai

File: chap2_type.tex, line 1648


x  = 32
y  = 9
op = "+ - * / % // & | and or << >>".split ()
for o in op :
    s = str (x) + " " + o + "  " + str (y)
    print s, " = ", eval (s)

File: chap2_type.tex, line 1661


32 +  9  =  41
32 -  9  =  23
32 *  9  =  288
32 /  9  =  3
32 %  9  =  5
32 //  9  =  3
32 &  9  =  0
32 |  9  =  41
32 and  9  =  9
32 or  9  =  32
32 <<  9  =  16384
32 >>  9  =  0

File: chap2_type.tex, line 1687


x = 3
print dir ()

File: chap2_type.tex, line 1694


['__builtins__', '__doc__', '__file__', '__name__', 'x']

File: chap2_type.tex, line 1733


x = 3
print x, type(x)     # affiche 3 <type 'int'>
x = 3.5
print x, type(x)     # affiche 3.5 <type 'float'>

File: chap2_type.tex, line 1754


x = 5       # affecte 5 à x
y = 6       # affecte 6 à y
x,y = 5,6   # affecte en une seule instruction 5 à x et 6 à y

File: chap2_type.tex, line 1767


x,y = divmod (17,5)
print x,y                          # affiche 3 2
print "17 / 5 = 5 * ", x, " + ",y  # affiche 17 / 5 = 5 *  3  +  2

File: chap2_type.tex, line 1778


x,y = point = 5,5

File: chap2_type.tex, line 1789


i = int(2**28)   
for k in range (0,4) :
    i *= int(2)
    print type(i),i

File: chap2_type.tex, line 1798


<type 'int'> 536870912
<type 'int'> 1073741824
<type 'long'> 2147483648
<type 'long'> 4294967296

File: chap2_type.tex, line 1815


print set ( (1,2,3) ) & set ( (2,3,5) )  
           # construit l'intersection qui est set([2, 3])

File: chap3_syntaxe.tex, line 44


initialisation de la variable moy à 0
faire pour i allant de 1 à N
      moy reçoit moy + ni
moy reçoit moy / N

File: chap3_syntaxe.tex, line 53


ligne 1 : initialisation de la variable moy à 0
ligne 2 : initialisation de la variable i à 1
ligne 3 : moy reçoit moy + ni
ligne 4 : i reçoit i + 1
ligne 5 : si i est inférieur ou égal à N alors aller à la ligne 3
ligne 6 : moy reçoit moy / N

File: chap3_syntaxe.tex, line 75


import keyword
print keyword.iskeyword("for")     # affiche True
print keyword.iskeyword("until")   # affiche False

File: chap3_syntaxe.tex, line 144



if condition1 :
   instruction1
   instruction2
   ...
else :
   instruction3
   instruction4
   ...

File: chap3_syntaxe.tex, line 158


if condition1 :
   instruction1
   instruction2
   ...

File: chap3_syntaxe.tex, line 168


if condition1 :
   instruction1
   instruction2
   ...
elif condition2 :
   instruction3
   instruction4
   ...
elif condition3 :
   instruction5
   instruction6
   ...
else :
   instruction7
   instruction8
   ...

File: chap3_syntaxe.tex, line 207


le nombre est positif
le nombre est négatif
signe = 1

File: chap3_syntaxe.tex, line 232


  File "test.py", line 7
    print "le nombre est négatif" 
                                 ^
IndentationError: unindent does not match any outer indentation level

File: chap3_syntaxe.tex, line 293


if condition :
    instruction1
else :
    instruction2

File: chap3_syntaxe.tex, line 306


if condition : instruction1
else : instruction2



File: chap3_syntaxe.tex, line 333


x = -5
if x < 0 :
   signe = -1
elif x == 0 :
   signe = 0
else :
   signe = 1

File: chap3_syntaxe.tex, line 349


x = -5
if x < 0 : signe = -1
elif x == 0 : signe = 0
else : signe = 1




File: chap3_syntaxe.tex, line 366


s = raw_input ("dites oui : ")    # voir remarque suivante
if s == "oui" or s [0:1] == "o" or s [0:1] == "O" or s == "1" :
       print "oui"
else : print "non"

version graphique de la fonction \codesindex{raw\_input

import Tkinter
def question (legende) :
    reponse = [""]
    root = Tkinter.Tk ()
    root.title ("pseudo raw_input")
    Tkinter.Label (text = legende).pack (side = Tkinter.LEFT)
    s = Tkinter.Entry (text= "def", width=80)
    s.pack (side = Tkinter.LEFT)
    def rget () :
        reponse [0] = s.get ()
        root.destroy ()
    Tkinter.Button (text = "ok", command = rget).pack (side = Tkinter.LEFT)
    root.mainloop ()
    return reponse [0]
    
print "reponse ", question ("texte de la question")  

File: chap3_syntaxe.tex, line 425


signe = 0
x = 0
if x < 0 : signe = -1
elif x == 0:
   pass          # signe est déjà égal à 0
else : signe = 1   

File: chap3_syntaxe.tex, line 437


File "nopass.py", line 6
    else :
    ^
IndentationError: expected an indented block

File: chap3_syntaxe.tex, line 471



while cond : 
    instruction 1
    ...
    instruction n

File: chap3_syntaxe.tex, line 488


n = 0
while n < 3:
   print "à l'intérieur ", n
   n += 1
print "à l'extérieur ", n   

File: chap3_syntaxe.tex, line 502


à l'intérieur  0
à l'intérieur  1
à l'intérieur  2
à l'extérieur  3


File: chap3_syntaxe.tex, line 519


n = 0
while n < 3 :
   print n
   n + 1        # n n'est jamais modifié, l'instruction correcte serait n += 1

File: chap3_syntaxe.tex, line 541



for x in set :
    instruction 1
    ...
    instruction n

File: chap3_syntaxe.tex, line 556


t = (1,2,3,4)
for x in t:       # affiche les nombres 1,2,3,4
    print x       # chacun sur une ligne différente

File: chap3_syntaxe.tex, line 565


d = { 1:2, 3:4, 5:6, 7:-1, 8:-2 }
print d                # affiche le dictionnaire {8: -2, 1: 2, 3: 4, 5: 6, 7: -1}
k = d.keys ()
print k                # affiche les clés [8, 1, 3, 5, 7]
k.sort ()
print k                # affiche les clés triées [1, 3, 5, 7, 8]
for x in k:            # affiche les éléments du dictionnaire 
    print x,":",d [x]  # triés par clés croissantes

File: chap3_syntaxe.tex, line 578


d = { 1:2, 3:4, 5:6, 7:-1, 8:-2 }
for x in sorted(d):    # pour les clés dans l'ordre croissant
    print x,":",d [x]

File: chap3_syntaxe.tex, line 589


sum = 0
N   = 10
for n in range(0,N):     # ou for n in xrange(0,N):  (plus rapide)
   sum += n              # additionne tous les entiers compris entre 0 et N-1

File: chap3_syntaxe.tex, line 598


l   = [ 4, 5, 3, -6, 7, 9]
sum = 0
for n in range(0,len (l)):  # ou for n in xrange(0,len (l)) :  (plus rapide)
   sum += l [n]             # additionne tous les éléments de l

File: chap3_syntaxe.tex, line 613



[ expression for x in ensemble ]

File: chap3_syntaxe.tex, line 623


y = list ()
for i in range(0,5) : 
   y.append (i+1)
print y             # affiche [1,2,3,4,5]        

File: chap3_syntaxe.tex, line 632


y = [ i+1 for i in range(0,5)] # résume trois lignes du programme précédent
print y                        # affiche [1,2,3,4,5]        

File: chap3_syntaxe.tex, line 647


d = ["un", "deux", "trois"]
for x in d: 
   print x          # affichage de tous les éléments de d

File: chap3_syntaxe.tex, line 660


d = ["un", "deux", "trois"]
it = iter (d)                     # obtient un itérateur sur d
while True:
    try: x = it.next ()           # obtient l'élément suivant, s'il n'existe pas
    except StopIteration: break   # déclenche une exception
    print x                       # affichage de tous les éléments de d

File: chap3_syntaxe.tex, line 674


d = [ (1,0,0), (0,1,0), (0,0,1) ]
for v in d: print v

File: chap3_syntaxe.tex, line 683


d = [ (1,0,0), (0,1,0), (0,0,1) ]
for x,y,z in d: print x,y,z

File: chap3_syntaxe.tex, line 691


d = [ (1,0,0), (0,1,0,6), (0,0,1) ]  # un élément de taille quatre
for x,y,z in d: print x,y,z

File: chap3_syntaxe.tex, line 699


Traceback (most recent call last):
  File "c:\temp\delete.py", line 2, in -toplevel-
    for x,y,z in d: print x,y,z
ValueError: unpack tuple of wrong size

File: chap3_syntaxe.tex, line 713


a = range(0,5)
b = [x**2 for x in a]
for x,y in zip (a,b):
    print y, " est le carré de ", x
    # affichage à droite

File: chap3_syntaxe.tex, line 723


0  est le carré de  0
1  est le carré de  1
4  est le carré de  2
9  est le carré de  3
16  est le carré de  4

File: chap3_syntaxe.tex, line 743


d = ["un", "deux", "trois"]
for x in d: print x          # une seule instruction

File: chap3_syntaxe.tex, line 750


d = ["un", "deux", "trois"]
i = 0
while d [i] != "trois" : i += 1
print "trois a pour position ", i

File: chap3_syntaxe.tex, line 769


d = dict ()
for i in range(1,100):            # d [i] est vrai si i est un nombre premier
    d [i] = True                  # au début, comme on ne sait pas, on suppose
                                  # que tous les nombres sont premiers
for i in range(2,100):
                                  # si d [i] est faux, 
   if not d [i]: continue         # les multiples de i ont déjà été cochés
                                  # et peut passer à l'entier suivant
   for j in range (2,100):        
       if i*j < 100: 
           d [i*j] = False        # d [i*j] est faux pour tous les multiples de i
                                  # inférieurs à 100
print "liste des nombres premiers"       
for i in d:
    if d [i]: print i

File: chap3_syntaxe.tex, line 789


d = dict ()
for i in range(1,100): d [i] = True

for i in range(2,100):
   if d [i]:                       
       for j in range (2,100):     
           if i*j < 100 : 
               d [i*j] = False

print "liste des nombres premiers"       
for i in d:
    if d [i]: print i

File: chap3_syntaxe.tex, line 813


l = [6,7,5,4,3]
n = 0
c = 5
for x in l:
   if x == c: break   # l'élément a été trouvé, on sort de la boucle
   n += 1             # si l'élément a été trouvé, cette instruction 
                      # n'est pas exécutée
print "l'élément ",c, " est en position ",
print n               # affiche l'élément 5 est en position 2

File: chap3_syntaxe.tex, line 829


set = range (1,21)
n = 53
for x in set:
    for y in set:
        c = x*x + y*y
        if c == n: break
    if c == n: break   # cette seconde instruction break est nécessaire 
                       # pour sortir de la seconde boucle 
                       # lorsque la solution a été trouvée
if c == n:
    # le symbole \ permet de passer à la ligne sans changer d'instruction
    print n, " est la somme des carrés de deux entiers :", \  
          x, "*", x, "+", y, "*", y, "=", n
else:
    print n, " n'est pas la somme des carrés de deux entiers"

File: chap3_syntaxe.tex, line 849


53  est la somme des carrés de deux entiers : 2 * 2 + 7 * 7 = 53

File: chap3_syntaxe.tex, line 863


L = [6,7,5,4,3]
n = 0
c = 1
for x in L :
   if x == c :
       print "l'élément ", c, " est en position ", n
       break  
   n += 1      
else:
   print "aucun élément ", c, " trouvé"  # affiche aucun élément  1  trouvé

File: chap3_syntaxe.tex, line 886


li = range (0,10)
print li                # affiche [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for i in range (0, len (li)):
    if i == 5 :
        del li [i:i+2]
    print li [i]        # affiche successivement 0, 1, 2, 3, 4, 7, 8, 9 et 
                        # produit une erreur
print li

File: chap3_syntaxe.tex, line 901


li = range (0,10)
print li                # affiche [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
i = 0
for t in li :
    if i == 5 : del li [i:i+2]
    i = i+1
    print t             # affiche successivement 0, 1, 2, 3, 4, 5, 8, 9
print li                # affiche [0, 1, 2, 3, 4, 7, 8, 9]

File: chap3_syntaxe.tex, line 916


li = range (0,10)
print li                # affiche [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for i in li :
    if i == 5 : del i
print li                # affiche [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

File: chap3_syntaxe.tex, line 956



def fonction_nom (par_1, ..., par_n) :
    instruction_1
    ...
    instruction_n
    return res_1, ..., res_n

File: chap3_syntaxe.tex, line 971



x_1, ..., x_n = fonction_nom (valeur_1, valeur_2, ..., valeur_n)

File: chap3_syntaxe.tex, line 978


fonction_nom (valeur_1, valeur_2, ..., valeur_n)

File: chap3_syntaxe.tex, line 992


import math
def coordonnees_polaires (x,y):
    rho     = math.sqrt(x*x+y*y)   # calcul la racine carrée de x*x+y*y
    theta   = math.atan2 (y,x)     # calcule l'arc tangente de y/x en tenant 
                                   # compte des signes de x et y
    return rho, theta

def affichage (x,y):
    r,t = coordonnees_polaires(x,y)
    print "cartésien (%f,%f) --> polaire (%f,%f degrés)" \
                  % (x,y,r,math.degrees(t))

affichage (1,1)
affichage (0.5,1)
affichage (-0.5,1)
affichage (-0.5,-1)
affichage (0.5,-1)

File: chap3_syntaxe.tex, line 1016


cartésien (1.000000,1.000000) --> polaire (1.414214,45.000000 degrés)
cartésien (0.500000,1.000000) --> polaire (1.118034,63.434949 degrés)
cartésien (-0.500000,1.000000) --> polaire (1.118034,116.565051 degrés)
cartésien (-0.500000,-1.000000) --> polaire (1.118034,-116.565051 degrés)
cartésien (0.500000,-1.000000) --> polaire (1.118034,-63.434949 degrés)

File: chap3_syntaxe.tex, line 1033



def fonction_nom (param_1, param_2 = valeur_2, ..., param_n = valeur_n):
    ...

File: chap3_syntaxe.tex, line 1046


def commander_carte_orange (nom, prenom, paiement = "carte", nombre = 1, zone = 2):
    print "nom : ", nom
    print "prénom : ", prenom
    print "paiement : ", paiement
    print "nombre : ", nombre
    print "zone :", zone
    
commander_carte_orange ("Dupré", "Xavier", "chèque")  
        # les autres paramètres nombre et zone auront pour valeur
        # leurs valeurs par défaut

File: chap3_syntaxe.tex, line 1063


def commander_carte_orange (nom, prenom, paiement = "carte", nombre = 1, zone):
    print "nom : ", nom
    # ...

File: chap3_syntaxe.tex, line 1069


  File "problem_zone.py", line 1
    def commander_carte_orange (nom, prenom, paiement = "carte", nombre = 1, zone):
SyntaxError: non-default argument follows default argument

File: chap3_syntaxe.tex, line 1082


def fonction (l = [0,0]) :
    l [0] += 1
    return l
    
print fonction ()         # affiche [1,0] : résultat attendu
print fonction ()         # affiche [2,0] : résultat surprenant
print fonction ( [0,0])   # affiche [1,0] : résultat attendu

File: chap3_syntaxe.tex, line 1096


import copy
def fonction (l = [0,0]) :
    l = copy.copy (l)
    l [0] += 1
    return l

File: chap3_syntaxe.tex, line 1114



x_1, ..., x_n = fonction_nom (param_1 = valeur_1, ..., param_n = valeur_n)

File: chap3_syntaxe.tex, line 1125


def identite (nom, prenom):
    print "nom : ", nom, " prénom : ", prenom

identite("Xavier", "Dupré")                 # nom :  Xavier prénom :  Dupré
identite(prenom = "Xavier", nom = "Dupré")  # nom :  Dupré  prénom :  Xavier

File: chap3_syntaxe.tex, line 1137


def commander_carte_orange (paiement = "carte", nombre = 1, zone = 2):
    print "paiement : ", paiement
    print "nombre : ", nombre
    print "zone :", zone
    
commander_carte_orange (zone = 5)  # seule la valeur par défaut 
                                   # du paramètre zone sera changée

File: chap3_syntaxe.tex, line 1157


def fonction (a,b):
    return a + b
    
def fonction (a,b,c):
    return a + b + c

print fonction (5,6)
print fonction (5,6,7)

File: chap3_syntaxe.tex, line 1172


Traceback (most recent call last):
  File "cours4.py", line 7, in ?
    print fonction (5,6)
TypeError: fonction() takes exactly 3 arguments (2 given)

File: chap3_syntaxe.tex, line 1191


>>> help (round)

File: chap3_syntaxe.tex, line 1197


Help on built-in function round:

round(...)
    round(number[, ndigits]) -> floating point number
    
    Round a number to a given precision in decimal digits (default 0 digits).
    This always returns a floating point number.  Precision may be negative.

File: chap3_syntaxe.tex, line 1211


>>> help (coordonnees_polaires)

File: chap3_syntaxe.tex, line 1216


Help on function coordonnees_polaires in module __main__:

coordonnees_polaires(x, y)

File: chap3_syntaxe.tex, line 1226


import math
def coordonnees_polaires (x,y):
    """convertit des coordonnées cartésiennes en coordonnées polaires
    (x,y) --> (pho,theta)"""
    rho     = math.sqrt(x*x+y*y)
    theta   = math.atan2 (y,x)
    return rho, theta
help (coordonnees_polaires)

File: chap3_syntaxe.tex, line 1241


Help on function coordonnees_polaires in module __main__:

coordonnees_polaires(x, y)
    convertit des coordonnées cartésiennes en coordonnées polaires
    (x,y) --> (pho,theta)

File: chap3_syntaxe.tex, line 1268


def somme_n_premier_terme(n,liste):
    """calcul la somme des n premiers termes d'une liste"""
    somme = 0
    for i in liste:
        somme += i
        n -= 1             # modification de n (type immuable)
        if n <= 0: break
    liste[0] = 0           # modification de liste (type modifiable)
    return somme

l = [1,2,3,4]
nb = 3
print "avant la fonction ",nb,l   # affiche   avant la fonction  3 [1, 2, 3, 4]
s = somme_n_premier_terme (nb,l)  
print "après la fonction ",nb,l   # affiche   après la fonction  3 [0, 2, 3, 4]
print "somme : ", s               # affiche   somme :  6

File: chap3_syntaxe.tex, line 1295


def fonction (liste):
    liste = []

liste = [0,1,2]
print liste       # affiche [0,1,2]
fonction (liste)
print liste       # affiche [0,1,2]

File: chap3_syntaxe.tex, line 1312


def fonction (liste):
    del liste

liste = [0,1,2]
print liste       # affiche [0,1,2]
fonction (liste)
print liste       # affiche [0,1,2]

File: chap3_syntaxe.tex, line 1326


def fonction (liste):
    del liste[0:len(liste)]  # on peut aussi écrire : liste[:] = []

liste = [0,1,2]
print liste       # affiche [0,1,2]
fonction (liste)
print liste       # affiche []

File: chap3_syntaxe.tex, line 1350


def factorielle(n):
    if n == 0 : return 1
    else : return n * factorielle(n-1)

File: chap3_syntaxe.tex, line 1360


Traceback (most recent call last):
  File "fact.py", line 5, in <module>
    factorielle(999)
  File "fact.py", line 3, in factorielle
    else : return n * factorielle(n-1)
  File "fact.py", line 3, in factorielle
    else : return n * factorielle(n-1)
  ...

File: chap3_syntaxe.tex, line 1375


def factorielle_non_recursive (n) :
    r = 1
    for i in range (2, n+1) :
        r *= i
    return r

File: chap3_syntaxe.tex, line 1393


print x   # déclenche une erreur

File: chap3_syntaxe.tex, line 1398


Traceback (most recent call last):
  File "pas_declaree.py", line 1, in <module>
    print x
NameError: name 'x' is not defined

File: chap3_syntaxe.tex, line 1409


def portee_variable(x):
    var = x
    print var
    
portee_variable(3)
print var           # déclenche une erreur car var est déclarée dans
                    # la fonction portee_variable

File: chap3_syntaxe.tex, line 1444


n = 1                   # déclaration d'une variable globale
def locale_globale():
    n = 2               # déclaration d'une variable locale
    print n             # affiche le contenu de la variable locale

print n                 # affiche 1
locale_globale()        # affiche 2
print n                 # affiche 1

File: chap3_syntaxe.tex, line 1460


n = 1                   # déclaration d'une variable globale
def locale_globale():
    global n            # cette ligne indique que n désigne la variable globale
    n = 2               # change le contenu de la variable globale
    print n             # affiche le contenu de la variable globale

print n                 # affiche 1
locale_globale()        # affiche 2
print n                 # affiche 2

File: chap3_syntaxe.tex, line 1488


print type(factorielle)  # affiche <type 'function'>

File: chap3_syntaxe.tex, line 1496


def affiche_pair():
    def fonction_locale(i):            # fonction locale ou imbriquée
        if i % 2 == 0 : return True
        else : return False
    for i in range(0,10):
        if fonction_locale(i):
            print i
    
affiche_pair()
fonction_locale(5)      # l'appel à cette fonction locale 
                        # déclenche une erreur d'exécution

File: chap3_syntaxe.tex, line 1525



def fonction (param_1, ..., param_n, *liste, **dictionnaire) : 

File: chap3_syntaxe.tex, line 1536



fonction (valeur_1, ..., valeur_n, \
          liste_valeur_1, ..., liste_valeur_p, \
          nom_1 = v_1, ..., nom_q = v_q)

File: chap3_syntaxe.tex, line 1550


def fonction(p,*l,**d):
    print "p = ",p
    print "liste (tuple) l :", l 
    print "dictionnaire d :", d
    
fonction (1,2,3,a=5,b=6) # 1 est associé au paramètre p
                         # 2 et 3 sont insérés dans la liste l
                         # a=5 et b=6 sont insérés dans le dictionnaire d

File: chap3_syntaxe.tex, line 1566


p =  1
liste l : (2, 3)
dictionnaire d : {'a': 5, 'b': 6}

File: chap3_syntaxe.tex, line 1578


def fonction(p,*l,**d):
    print "p = ",p
    print "liste l :", l 
    print "dictionnaire d :", d
    
def fonction2 (p, *l, **d) :
    l += (4,)              # on ajoute une valeur au tuple
    d ["c"] = 5            # on ajoute un couple (paramètre,valeur)
    fonction (p, *l, **d)  # ne pas oublier le symbole *
    
fonction2 (1,2,3,a=5,b=6)

File: chap3_syntaxe.tex, line 1596


p =  1
liste l : (2, 3, 4)
dictionnaire d : {'a': 5, 'c': 5, 'b': 6}

File: chap3_syntaxe.tex, line 1610



nom_fonction = lambda param_1, ..., param_n : expression

File: chap3_syntaxe.tex, line 1621


min = lambda x,y : (abs (x+y) - abs (x-y))/2

print min (1,2)      # affiche 1
print min (5,4)      # affiche 4

File: chap3_syntaxe.tex, line 1632


def min(x,y):
    return (abs (x+y) - abs (x-y))/2

print min (1,2)      # affiche 1
print min (5,4)      # affiche 4

File: chap3_syntaxe.tex, line 1644


fs = []
for a in range (0,10) :
    f = lambda x : x + a
    fs.append (f)
for f in fs :
    print (f(1))   # le programme affiche 10 fois 10 de suite
                   # car la variable a vaut dix à la fin de la boucle

File: chap3_syntaxe.tex, line 1657


fs = []
for a in range (0,10) :
    f = lambda x,y=a : x + y   # ligne changée
    fs.append (f)
for f in fs :
    print (f(1))

File: chap3_syntaxe.tex, line 1677


def fonction_yield(n):
    i = 0
    while i < n-1:
        print "yield 1" # affichage : pour voir ce que fait le programme
        yield i         # arrête la fonction qui reprendra
        i = i+1         # à la ligne suivante lors du prochain appel
    print "yield 2"     # affichage : pour voir ce que fait le programme
    yield i             # arrête la fonction qui ne reprendra pas
                        # lors du prochain appel car le code de la fonction
                        # prend fin ici
                        
for a in fonction_yield(2):
    print a                 # affiche tous les éléments que retourne la 
                            # fonction fonction_yield, elle simule la liste
                            # [0,1]
print "-----------------------------------------------"                            
for a in fonction_yield(3):
    print a                 # nouvel appel, l'exécution reprend 
                            # au début de la fonction,
                            # affiche tous les éléments que retourne la 
                            # fonction fonction_yield, elle simule la liste
                            # [0,1,2]

File: chap3_syntaxe.tex, line 1706


yield 1
0
yield 2
1
-----------------------------------------------
yield 1
0
yield 1
1
yield 2
2

File: chap3_syntaxe.tex, line 1733


x = 5
def y () :
    return None
print callable (x)  # affiche False car x est une variable
print callable (y)  # affiche True car y est une fonction

File: chap3_syntaxe.tex, line 1754


x = 3
y = 4
print eval ("x*x+y*y+2*x*y")  # affiche 49
print (x+y)**2                # affiche 49

File: chap3_syntaxe.tex, line 1763


x = 3
y = 4
print eval ("x*x+y*y+2*x*y+z")

File: chap3_syntaxe.tex, line 1771


Traceback (most recent call last):
  File "c:\temp\cours.py", line 3, in -toplevel-
    print eval ("x*x+y*y+2*x*y+z")
  File "<string>", line 0, in -toplevel-
NameError: name 'z' is not defined

File: chap3_syntaxe.tex, line 1790


import math
str = """def coordonnees_polaires (x,y):
    rho     = math.sqrt(x*x+y*y)
    theta   = math.atan2 (y,x)
    return rho, theta"""       # fonction définie par une chaîne de caractères

obj = compile(str,"","exec")   # fonction compilée
exec obj                       # fonction incorporée au programme
print coordonnees_polaires(1,1)# affiche (1.4142135623730951, 0.78539816339744828)

File: chap3_syntaxe.tex, line 1806


import math
str = """math.sqrt(x*x+y*y)"""  # expression définie par une chaîne de caractères

obj = compile(str,"","eval")    # expression compilée
x = 1
y = 2
print eval (obj)                # résultat de l'expression

File: chap3_syntaxe.tex, line 1826


sys:1: DeprecationWarning: Non-ASCII character '\xe9' 
SyntaxError: Non-ASCII character '\xe9' in file i.py on line 1, 
             but no encoding declared; 
             see http://www.python.org/peps/pep-0263.html for details

File: chap3_syntaxe.tex, line 1837


# coding: cp1252

File: chap3_syntaxe.tex, line 1841


# coding: latin-1

File: chap3_syntaxe.tex, line 1872


l = [0,3,4,4,5,6]
print [ est_pair (i) for i in l ]  # affiche [0, 1, 0, 0, 1, 0]
print map (est_pair, l)            # affiche [0, 1, 0, 0, 1, 0]

File: chap3_syntaxe.tex, line 1880


def addition (x,y) : return x + y
l = [0,3,4,4,5,6]
m = [1,3,4,5,6,8]
print [ addition (l [i], m [i]) for i in range (0, len (l)) ]
print map (addition, l, m)   # affiche [1, 6, 8, 9, 11, 14]

File: chap3_syntaxe.tex, line 1890


print map (None, l,m)  # affiche [(0, 1), (3, 3), (4, 4), (4, 5), (5, 6), (6, 8)]
print zip (l,m)        # affiche [(0, 1), (3, 3), (4, 4), (4, 5), (5, 6), (6, 8)]

File: chap3_syntaxe.tex, line 1903


l   = [ 4, 5, 3, -6, 7, 9]
l.sort ()
for n in l : 
    print n

File: chap3_syntaxe.tex, line 1912


l   = [ 4, 5, 3, -6, 7, 9]

for n in sorted (l) :
    print n    

File: chap3_syntaxe.tex, line 1927


l   = [ 4, 5, 3, -6, 7, 9]
for i in xrange (0, len (l)) :
    print i, l [i]

File: chap3_syntaxe.tex, line 1935


l   = [ 4, 5, 3, -6, 7, 9]
for i,v in enumerate (l) :
    print i, v

File: chap3_syntaxe.tex, line 1997


def recherche (li, c) :
    for i,v in enumerate (li) :
        if v == c : return i
    return -1
li = [ 45, 32, 43, 56 ]
print recherche (li, 43)    # affiche 2

File: chap3_syntaxe.tex, line 2008


print li.index (43)

File: chap3_syntaxe.tex, line 2014


def recherche (li, c,d) :
    for i,v in enumerate (li) :
        if v in [c,d] : return i
    return -1
li = [ 45, 32, 43, 56 ]
print recherche (li, 43, 32)    # affiche 1

File: chap3_syntaxe.tex, line 2030


li = [ 0, 434, 43, 6436, 5 ]
m  = li [0]             # initialisation
for l in li :           # boucle
    if m < l : m = l    # m est le maximum

File: chap3_syntaxe.tex, line 2044


li = [ 0, 434, 43, 6436, 5 ]
m  = 0
for i in xrange (0, len (li)) : 
    if li [m] < li [i] : m = i

File: chap3_syntaxe.tex, line 2057


k = [ (v,i) for i,v in enumerate (li) ]
m = max (k) [1]

File: chap3_syntaxe.tex, line 2065


li = [ (0,0), (434,0), (43,1), (6436,1), (5,0) ]
m  = -1 # -1 car le premier élément peut ne pas faire partie du sous-ensemble
for i in range (0, len (li)) : 
    if li [i][1] == 0 and (m == -1 or li [m][0] < li [i][0]) : m = i

recherche dichotomique

def recherche_dichotomique (li, c) :
    a,b = 0, len (li)-1
    while a <= b :
        m = (a+b)//2
        if   c == li [m] : return m
        elif c <  li [m] : b = m-1   # partie supérieure éliminée
        else             : a = m+1   # partie inférieure éliminée
    return -1  # élément non trouvé
    
li = range (0,100,2)
print (recherche_dichotomique (li, 48))  # affiche 24
print (recherche_dichotomique (li, 49))  # affiche -1

File: chap3_syntaxe.tex, line 2089


s       = "case11;case12;case13|case21;case22;case23"
# décomposition en matrice
ligne   = s.split ("|")                     # lignes
mat     = [ l.split (";") for l in ligne ]  # colonnes

File: chap3_syntaxe.tex, line 2096


ligne   = [ ";".join (l) for l in mat ]     # colonnes
s       = "|".join (ligne)                  # lignes

File: chap3_syntaxe.tex, line 2106


li = [ 0, 434, 43, 6456 ]
s  = 0                       # initialisation
for l in li :                # boucle
    s += l                   # addition

File: chap3_syntaxe.tex, line 2115


def fonction (x) : return x*x
s  = 0
for l in li : s += fonction (l)

File: chap3_syntaxe.tex, line 2128


s = sum ( [fonction (l) for l in li] )

s = sum ( map (fonction, li) )

File: chap3_syntaxe.tex, line 2146


for i in xrange (0, len (li)) :
    # recherche du minimum entre i et len (li) exclu
    pos = i
    for j in xrange (i+1, len (li)) :
        if li [j] < li [pos] : pos = j
    # échange
    ech      = li [pos]
    li [pos] = li [i]
    li [i]   = ech

tri avec positions initiales

tab = ["zéro", "un", "deux"]                        # tableau à trier
pos = [ (tab [i],i) for i in range (0, len (tab)) ] # tableau de couples
pos.sort ()                                         # tri    
print pos                # affiche [('deux', 2), ('un', 1), ('zéro', 0)]

File: chap3_syntaxe.tex, line 2173


ordre = range (0, len (pos))
for i in xrange (0, len (pos)) : ordre [pos [i][1]] = i

File: chap3_syntaxe.tex, line 2185


li = ["un", "deux", "un", "trois"]
d  = { }
for l in li :
    if l not in d : d [l] = 1
    else : d [l] += 1
print d   # affiche {'un': 2, 'trois': 1, 'deux': 1}

File: chap3_syntaxe.tex, line 2198


mat = [ [1,1,1], [2,2,2], [1,1,1]]
d  = { }
for l in mat :
    k = str (l)    # k = tuple (l) lorsque cela est possible
    if k not in d : d [k] = 1
    else : d [k] += 1
print d   # affiche {'[1, 1, 1]': 2, '[2, 2, 2]': 1}

File: chap3_syntaxe.tex, line 2212


li = ["un", "deux", "un", "trois"]
d  = { }
for i,v in enumerate (li) :
    if v not in d : d [v] = [ i ]
    else : d [v].append (i)
print d   # affiche {'un': [0, 2], 'trois': [3], 'deux': [1]}

File: chap3_syntaxe.tex, line 2228


mat = [[0,1,2],[3,4,5]]
lin = [ i * len (mat [i]) + j \
            for i in range (0, len (mat)) \
            for j in range (0, len (mat [i])) ]

File: chap3_syntaxe.tex, line 2237


nc = len (mat [0])
mat = [ [ lin [i * nc + j] for j in range (0, len (mat [i])) ] \
                           for i in range (0, len (mat)) ]

File: chap3_syntaxe.tex, line 2250


def fonction_carre(x) :  return x*x
def fonction_cube (x) :  return x*x*x

def calcul_n_valeur (l,f):
    res = [ f(i) for i in l ]
    return res

l = [0,1,2,3]
print l   # affiche [0, 1, 2, 3]

l1 = calcul_n_valeur (l, fonction_carre)
print l1  # affiche [0, 1, 4, 9]

l2 = calcul_n_valeur (l, fonction_cube)
print l2  # affiche [0, 1, 8, 27]

File: chap4_classe.tex, line 38


class nom_classe :
    # corps de la classe
    # ...

File: chap4_classe.tex, line 58



cl = nom_classe ()

File: chap4_classe.tex, line 79


class classe_vide:
    pass

File: chap4_classe.tex, line 88


class classe_vide:
    pass
cl = classe_vide ()

File: chap4_classe.tex, line 99


print type (cl)   # affiche <type 'instance'>

File: chap4_classe.tex, line 107


isinstance (cl,classe_vide)   # affiche True

File: chap4_classe.tex, line 126



class nom_classe :
    def nom_methode (self, param_1, ..., param_n) :
        # corps de la méthode...

File: chap4_classe.tex, line 140



cl = nom_classe ()    # variable de type nom_classe
t  = cl.nom_methode (valeur_1, ..., valeur_n)

File: chap4_classe.tex, line 152


rnd = 42

class exemple_classe:
    def methode1(self,n):
        """simule la génération d'un nombre aléatoire 
           compris entre 0 et n-1 inclus"""
        global rnd
        rnd = 397204094 * rnd % 2147483647
        return int (rnd % n)

nb  = exemple_classe ()
l   = [ nb.methode1(100) for i in range(0,10) ]
print l   # affiche [19, 46, 26, 88, 44, 56, 56, 26, 0, 8]

nb2 = exemple_classe ()
l2  = [ nb2.methode1(100) for i in range(0,10) ]
print l2   # affiche [46, 42, 89, 66, 48, 12, 61, 84, 71, 41]

File: chap4_classe.tex, line 195



class nom_classe :
    def nom_methode (self, param_1, ..., param_n) :
        self.nom_attribut = valeur

File: chap4_classe.tex, line 209


class exemple_classe:
    def methode1(self,n):
        """simule la génération d'un nombre aléatoire 
           compris entre 0 et n-1 inclus"""
        self.rnd = 397204094 * self.rnd % 2147483647
        return int (self.rnd % n)

nb = exemple_classe ()
l  = [ nb.methode1(100) for i in range(0,10) ]
print l

File: chap4_classe.tex, line 226


Traceback (most recent call last):
  File "cours.py", line 8, in -toplevel-
    l = [ nb.methode1(100) for i in range(0,10) ]
  File "cours.py", line 4, in methode1
    self.rnd = 397204094 * self.rnd % 2147483647
AttributeError: exemple_classe instance has no attribute 'rnd'

File: chap4_classe.tex, line 240


class exemple_classe:
    def methode1(self,n):
        """simule la génération d'un nombre aléatoire 
           compris entre 0 et n-1 inclus"""
        self.rnd = 42  # déclaration à l'intérieur de la méthode, 
                       # doit être précédé du mot-clé self
        self.rnd = 397204094 * self.rnd % 2147483647
        return int (self.rnd % n)

nb = exemple_classe ()
l  = [ nb.methode1(100) for i in range(0,10) ]
print l  # affiche [19, 19, 19, 19, 19, 19, 19, 19, 19, 19]

File: chap4_classe.tex, line 259


class exemple_classe:
    def methode1(self,n):
        """simule la génération d'un nombre aléatoire 
           compris entre 0 et n-1 inclus"""
        self.rnd = 397204094 * self.rnd % 2147483647
        return int (self.rnd % n)

nb     = exemple_classe ()
nb.rnd = 42              # déclaration à l'extérieur de la classe, 
                         # indispensable pour utiliser la méthode methode1
l = [ nb.methode1(100) for i in range(0,10) ]
print l  # affiche [19, 46, 26, 88, 44, 56, 56, 26, 0, 8]

File: chap4_classe.tex, line 283



class nom_classe :
    def __init__(self, param_1, ..., param_n):
        # code du constructeur

File: chap4_classe.tex, line 296



x = nom_classe (valeur_1,...,valeur_n)

File: chap4_classe.tex, line 307


class classe1:
    def __init__(self):
        # pas de paramètre supplémentaire
        print "constructeur de la classe classe1"
        self.n = 1 # ajout de l'attribut n

x = classe1 ()     # affiche constructeur de la classe classe1
print x.n          # affiche 1
        
class classe2:
    def __init__(self,a,b):
        # deux paramètres supplémentaires
        print "constructeur de la classe classe2"
        self.n = (a+b)/2  # ajout de l'attribut n

x = classe2 (5,9)  # affiche constructeur de la classe classe2
print x.n          # affiche 7

File: chap4_classe.tex, line 335


class exemple_classe:
    def __init__ (self) : # constructeur
        self.rnd = 42     # on crée l'attribut rnd, identique pour chaque instance
                          # --> les suites générées auront toutes le même début
    def methode1(self,n):
        self.rnd = 397204094 * self.rnd % 2147483647
        return int (self.rnd % n)

nb  = exemple_classe ()
l   = [ nb.methode1(100) for i in range(0,10) ]
print l   # affiche [19, 46, 26, 88, 44, 56, 56, 26, 0, 8]

nb2 = exemple_classe ()
l2  = [ nb2.methode1(100) for i in range(0,10) ]
print l2   # affiche [19, 46, 26, 88, 44, 56, 56, 26, 0, 8]

File: chap4_classe.tex, line 366


class exemple_classe:
    def __init__ (self) :
        self.rnd = 42
    def methode1(self,n):
        self.rnd = 397204094 * self.rnd % 2147483647
        return int (self.rnd % n)

nb = exemple_classe ()
print nb.__dict__        # affiche {'rnd': 42}

File: chap4_classe.tex, line 382


class exemple_classe:
    def methode1(self,n):
        if "rnd" not in self.__dict__ :  # l'attribut existe-t-il ? 
            self.rnd = 42                # création de l'attribut
            self.__dict__ ["rnd"] = 42   # autre écriture possible
        self.rnd = 397204094 * self.rnd % 2147483647
        return int (self.rnd % n)

nb = exemple_classe ()
l  = [ nb.methode1(100) for i in range(0,10) ]
print l  # affiche [19, 46, 26, 88, 44, 56, 56, 26, 0, 8]

File: chap4_classe.tex, line 455


class classe_vide:
    pass
cl = classe_vide ()
print cl.__module__             # affiche __main__
print cl.__class__              # affiche __main__.classe_vide ()
print cl.__dict__               # affiche {}
print cl.__doc__                # affiche None  (voir paragraphe suivant)
print cl.__class__.__doc__      # affiche None  
print cl.__class__.__dict__     # affiche {'__module__': '__main__', 
                                #          '__doc__': None}
print cl.__class__.__name__     # affiche classe_vide
print cl.__class__.__bases__    # affiche ()

File: chap4_classe.tex, line 486


class exemple_classe:
    """simule une suite de nombres aléatoires"""
    def __init__ (self) :
        """constructeur : initialisation de la première valeur"""
        self.rnd = 42
    def methode1(self,n):
        """simule la génération d'un nombre aléatoire 
        compris entre 0 et n-1 inclus"""
        self.rnd = 397204094 * self.rnd % 2147483647
        return int (self.rnd % n)
nb = exemple_classe ()
help (exemple_classe)     # appelle l'aide associée à la classe

File: chap4_classe.tex, line 502


class exemple_classe
 |  simule une suite de nombres aléatoires
 |  
 |  Methods defined here:
 |  
 |  __init__(self)
 |      constructeur : initialisation de la première valeur
 |  
 |  methode1(self, n)
 |      simule la génération d'un nombre aléatoire 
 |      compris entre 0 et n-1 inclus

File: chap4_classe.tex, line 520


print exemple_classe.__doc__  # affiche simule une suite de nombres aléatoires
print nb.__doc__              # affiche simule une suite de nombres aléatoires
print nb.__class__.__doc__    # affiche simule une suite de nombres aléatoires

File: chap4_classe.tex, line 533


class essai_class:
    def meth(self):
        x      = 6
        self.y = 7

a = essai_class()
print dir (a)             # affiche ['__doc__', '__module__', 'meth']
a.meth ()
print dir (a)             # affiche ['__doc__', '__module__', 'meth', 'y']
print dir (essai_class)   # affiche ['__doc__', '__module__', 'meth']

File: chap4_classe.tex, line 559


class ensemble_element :
    
    class element :
        def __init__ (self) :
            self.x, self.y, self.z = 0,0,0
    
    def __init__ (self) :
        self.all = [ ensemble_element.element () for i in xrange (0,3) ]
                     
    def barycentre (self) :
        b = ensemble_element.element ()
        for el in self.all :
            b.x += el.x
            b.y += el.y
            b.z += el.z
        b.x /= len (self.all)
        b.y /= len (self.all)
        b.z /= len (self.all)
        return b
    
f = ensemble_element ()
f.all [0].x, f.all [0].y, f.all [0].z = 4.5,1.5,1.5
b = f.barycentre ()
print b.x,b.y,b.z # affiche 1.5 0.5 0.5

File: chap4_classe.tex, line 598


class nouvelle_classe:
    pass
x = nouvelle_classe () + nouvelle_classe ()

File: chap4_classe.tex, line 613


class nombre_complexe:
    def __init__ (self, a = 0, b= 0) : self.a, self.b = a,b
    def get_module (self) :  return math.sqrt (self.a * self.a + self.b * self.b)

    def ajoute (self,c):
        return nombre_complexe (self.a + c.a, self.b + c.b)
    
c1 = nombre_complexe (0,1)    
c2 = nombre_complexe (1,0)    
c  = c1.ajoute (c2)         # c = c1 + c2
print c.a, c.b

File: chap4_classe.tex, line 633



class nom_class :
    def __add__ (self, autre) :
        # corps de l'opérateur
        return ...   # nom_classe

File: chap4_classe.tex, line 647


class nombre_complexe:
    def __init__ (self, a = 0, b= 0) : self.a, self.b = a,b
    def get_module (self) : return math.sqrt (self.a * self.a + self.b * self.b)
        
    def __add__(self, c):
        return nombre_complexe (self.a + c.a, self.b + c.b)
    
c1 = nombre_complexe (0,1)    
c2 = nombre_complexe (1,0)    
c  = c1 + c2          # cette expression est maintenant syntaxiquement correcte
c  = c1.__add__ (c2)  # même ligne que la précédente mais écrite explicitement
print c.a, c.b

File: chap4_classe.tex, line 667



class nom_class :
    def __iadd__ (self, autre) :
        # corps de l'opérateur
        return self

File: chap4_classe.tex, line 682


class nombre_complexe:
    def __init__ (self, a = 0, b= 0) : self.a, self.b = a,b
    def get_module (self) : return math.sqrt (self.a * self.a + self.b * self.b)
    def __add__(self, c)  : return nombre_complexe (self.a + c.a, self.b + c.b)
    
    def __iadd__(self, c) :
        self.a += c.a
        self.b += c.b
        return self
        
c1  = nombre_complexe (0,1)    
c2  = nombre_complexe (1,0)    
c1 += c2           # utilisation de l'opérateur +=
c1.__iadd__ (c2)   # c'est la transcription explicite de la ligne précédente
print c1.a, c1.b

File: chap4_classe.tex, line 706



class nom_class :
    def __str__ (self) :
        # corps de l'opérateur
        return...

File: chap4_classe.tex, line 721


class nombre_complexe:
    def __init__ (self, a = 0, b= 0) : self.a, self.b = a,b
    def __add__(self, c) : return nombre_complexe (self.a + c.a, self.b + c.b)
    
    def __str__ (self) :
        if   self.b == 0 : return "%f" % (self.a)
        elif self.b >  0 : return "%f + %f i" % (self.a, self.b) 
        else             : return "%f - %f i" % (self.a, -self.b) 

c1 = nombre_complexe (0,1)    
c2 = nombre_complexe (1,0)    
c3 = c1 + c2
print c3       # affiche 1.000000 + 1.000000 i

File: chap4_classe.tex, line 745


class point_espace:
    def __init__ (self, x,y,z): self._x, self._y, self._z = x,y,z

    def __getitem__(self,i):
        if i == 0 : return self._x
        if i == 1 : return self._y
        if i == 2 : return self._z
        # pour tous les autres cas --> erreur
        raise IndexError ("indice impossible, 0,1,2 autorisés")

    def __setitem__(self,i,x):
        if   i == 0 : self._x = x
        elif i == 1 : self._y = y
        elif i == 2 : self._z = z
        # pour tous les autres cas --> erreur
        raise IndexError ("indice impossible, 0,1,2 autorisés")
        
    def __str__(self):
        return "(%f,%f,%f)" % (self._x, self._y, self._z)
        
a = point_espace (1,-2,3)

print a                      # affiche (1.000000,-2.000000,3.000000)
a [1] = -3                   # (__setitem__) affecte -3 à a.y
print "abscisse : ", a [0]   # (__getitem__) affiche abscisse :  1  
print "ordonnée : ", a [1]   # (__getitem__) affiche ordonnée :  -3
print "altitude : ", a [2]   # (__getitem__) affiche altitude :  3

File: chap4_classe.tex, line 779


Traceback (most recent call last):
  File "point_espace.py", line 31, in ?
    print a [4]
  File "point_espace.py", line 13, in __getitem__
    raise IndexError, "indice impossible, 0,1,2 autorisés"
IndexError: indice impossible, 0,1,2 autorisés

File: chap4_classe.tex, line 923


a = point_espace (1,-2,3)
for x in a:   
    print x      # affiche successivement 1,-2,3

File: chap4_classe.tex, line 933


a = point_espace (1,-2,3)
it = iter (a)
while True:
    try : print it.next ()
    except StopIteration : break

File: chap4_classe.tex, line 944


class point_espace:
    def __init__ (self, x,y,z):
        self._x, self._y, self._z = x,y,z
    def __str__(self):
        return "(%f,%f,%f)" % (self._x, self._y, self._z)
    def __getitem__(self,i):
        if i == 0 : return self._x
        if i == 1 : return self._y
        if i == 2 : return self._z
        # pour tous les autres cas --> erreur
        raise IndexError ("indice impossible, 0,1,2 autorisés")
        
    class class_iter:
        """cette classe définit un itérateur pour point_espace"""
        def __init__ (self,ins):
            """initialisation, self._ins permet de savoir quelle 
               instance de point_espace on explore, 
               self._n mémorise l'indice de l'élément exploré"""
            self._n   = 0
            self._ins = ins
            
        def __iter__ (self) :   # le langage impose cette méthode 
           return self          # dans certaines configurations
           
        def next (self):
            """retourne l'élément d'indice self._n et passe à l'élément suivant"""
            if self._n <= 2:
                v = self._ins [self._n]
                self._n += 1
                return v
            else :
                # si cet élément n'existe pas, lève une exception
                raise StopIteration
    
    def __iter__(self):
        """opérateur de la classe point_espace, retourne un itérateur
           permettant de l'explorer"""
        return point_espace.class_iter (self)

a = point_espace (1,-2,3)
for x in a:   
    print x      # affiche successivement 1,-2,3

File: chap4_classe.tex, line 993


class point_espace:
    def __init__ (self, x,y,z):
        self._x, self._y, self._z = x,y,z
    def __str__(self):
        return "(%f,%f,%f)" % (self._x, self._y, self._z)
    def __getitem__(self,i):
        if i == 0 : return self._x
        if i == 1 : return self._y
        if i == 2 : return self._z
        # pour tous les autres cas --> erreur
        raise IndexError ("indice impossible, 0,1,2 autorisés")
        
    def __iter__(self):
        """itérateur avec yield (ou générateur)"""
        _n = 0
        while _n <= 2 : 
            yield self.__getitem__ (_n)
            _n += 1
            
a = point_espace (1,-2,3)
for x in a:   
    print x      # affiche successivement 1,-2,3

File: chap4_classe.tex, line 1040

			
class essai_class:
    def methode (self):
        print "méthode non statique"

x = essai_class ()
x.methode ()

File: chap4_classe.tex, line 1053



class nom_class :
    def nom_methode(params, ...) : 
        # corps de la méthode
        ...
    nom_methode = staticmethod (nom_methode)

File: chap4_classe.tex, line 1068


class essai_class:
    def methode ():
        print "méthode statique"
    methode = staticmethod(methode)

essai_class.methode ()

File: chap4_classe.tex, line 1080


def methode ():
    print "méthode statique"
    
class essai_class:
    pass

essai_class.methode = staticmethod(methode)
essai_class.methode ()

File: chap4_classe.tex, line 1094


class essai_class:
    print "création d'une instance de la classe essai_class"
    methode = staticmethod(methode)
cl = classe_vide () # affiche création d'une instance de la classe essai_class
ck = classe_vide () # n'affiche rien

File: chap4_classe.tex, line 1106


class Couleur :
    def __init__ (self, r, v, b) : self.r, self.v, self.b =  r, v, b
    def __str__ (self) : return str ( (self.r,self.v,self.b))
    def blanc () : return Couleur (255,255,255)
    def noir  () : return Couleur (0,0,0)
    blanc = staticmethod (blanc)
    noir  = staticmethod (noir)
    
c = Couleur.blanc ()
print c               # affiche (255, 255, 255)
c = Couleur.noir ()
print c               # affiche (0, 0, 0)

File: chap4_classe.tex, line 1135



class nom_class :
    attribut_statique = valeur
    def nom_methode (self,params, ...):
        nom_class.attribut_statique2 = valeur2 
    def nom_methode_st (params, ...) : 
        nom_class.attribut_statique3 = valeur3 
    nom_methode_st = staticmethod (nom_methode_st)

File: chap4_classe.tex, line 1153


class essai_class:
    x = 5
    def meth(self):
        print essai_class.x
        essai_class.x += 1

y = essai_class ()
z = essai_class ()
y.meth()    # affiche 5
z.meth()    # affiche 6

File: chap4_classe.tex, line 1172


class exemple_classe:
    rnd = 42
    def incremente_rnd (self):
        self.rnd += 1
        return self.rnd

cl = exemple_classe()

print cl.__dict__                    # affiche {}
print cl.__class__.__dict__ ["rnd"]  # affiche 42
cl.incremente_rnd ()
print cl.__dict__                    # affiche {'rnd': 43}
print cl.__class__.__dict__ ["rnd"]  # affiche 42

File: chap4_classe.tex, line 1202



def nom_methode (cls) :
    # code de la fonction}
    
class nom_classe :
    # code de la classe
    nom_methode = classmethod (nom_methode)        # syntaxe 1
    
nom_classe.nom_methode = classmethod (nom_methode) # syntaxe 2

File: chap4_classe.tex, line 1222


def meth3 (cls): print "ok meth3", cls.x
def meth4 (cls): print "ok meth4", cls.x
    
class essai_classe:
    x = 5
    def meth(self): print "ok meth", self.x
    def meth2(cls): print "ok meth2", cls.x

    meth3 = classmethod (meth3)

x = essai_classe ()
x.meth ()                                 # affiche ok meth 5
x.meth2 ()                                # affiche ok meth2 5
x.meth3 ()                                # affiche ok meth3 5

essai_classe.meth4 = classmethod (meth4)
x.meth4 ()                                # affiche ok meth4 5

File: chap4_classe.tex, line 1252



class nom_classe :
    # code de la classe
    nom_propriete = property (fget, fset, fdel, doc)

File: chap4_classe.tex, line 1268


import math

class nombre_complexe(object):           # voir remarque après l'exemple
    def __init__ (self, a = 0, b= 0):
        self.a = a
        self.b = b
        
    def __str__ (self) :
        if   self.b == 0 : return "%f" % (self.a)
        elif self.b >  0 : return "%f + %f i" % (self.a, self.b) 
        else             : return "%f - %f i" % (self.a, -self.b) 
        
    def get_module (self): 
        return math.sqrt (self.a * self.a + self.b * self.b)

    def set_module (self,m):
        r = self.get_module ()
        if r == 0:
            self.a = m
            self.b = 0
        else :
            d       = m / r
            self.a *= d
            self.b *= d
            
    def get_argument (self) : 
        r = self.get_module ()
        if r == 0 : return 0
        else      : return math.atan2 (self.b / r, self.a / r)
            
    def set_argument (self,arg) :
        m       = self.get_module ()
        self.a  = m * math.cos (arg)
        self.b  = m * math.sin (arg)
        
    def get_conjugue (self):
        return nombre_complexe (self.a,-self.b)
        
    module = property (fget = get_module,   fset = set_module,   doc = "module")
    arg    = property (fget = get_argument, fset = set_argument, doc = "argument")
    conj   = property (fget = get_conjugue,                      doc = "conjugué")
    
c = nombre_complexe (0.5,math.sqrt (3)/2)
print "c = ",         c          # affiche c =  0.500000 + 0.866025 i
print "module = ",    c.module   # affiche module =  1.0
print "argument = ",  c.arg      # affiche argument =  1.0471975512                    

c           = nombre_complexe ()
c.module    = 1
c.arg       = math.pi * 2 / 3
print "c = ",         c          # affiche c =  -0.500000 + 0.866025 i
print "module = ",    c.module   # affiche module =  1.0  
print "argument = ",  c.arg      # affiche argument =  2.09439510239
print "conjugué = ",  c.conj     # affiche conjugué =  -0.500000 - 0.866025 i

File: chap4_classe.tex, line 1329


Traceback (most recent call last):
  File "cour2.py", line 53, in ?
    c.conj = nombre_complexe (0,0)
AttributeError: can't set attribute

File: chap4_classe.tex, line 1356


class exemple_classe:
    def __init__ (self) : self.rnd = 42
    def methode1(self,n):
        self.rnd = 397204094 * self.rnd % 2147483647
        return int (self.rnd % n)

nb  = exemple_classe ()
nb2 = nb
print nb.rnd        # affiche 42
print nb2.rnd       # affiche 42

nb2.rnd = 0

print nb2.rnd       # affiche 0, comme prévu
print nb.rnd        # affiche 0, si nb et nb2 étaient des objets différents, 
                    # cette ligne devrait afficher 42

File: chap4_classe.tex, line 1379



import copy
nom_copy = copy.copy (nom_instance)

File: chap4_classe.tex, line 1392


class exemple_classe:
    def __init__ (self) : self.rnd = 42
    def methode1(self,n):
        self.rnd = 397204094 * self.rnd % 2147483647
        return int (self.rnd % n)

nb = exemple_classe ()

import copy           # pour utiliser le module copy
nb2 = copy.copy (nb)  # copie explicite

print nb.rnd    # affiche 42
print nb2.rnd   # affiche 42

nb2.rnd = 0

print nb2.rnd   # affiche 0
print nb.rnd    # affiche 42

File: chap4_classe.tex, line 1420


m  = [ 0, 1 ]
m2 = m
del m2   # supprime l'identificateur mais pas la liste
print m  # affiche [0, 1]

référencement d'objets

class CreationDestruction (object) :
    
    def __init__ (self) :
        print "constructeur"
        
    def __new__ (self) :
        print "__new__"
        return object.__new__ (self)
        
    def __del__ (self) :
        print "__del__"

print "a"
m = CreationDestruction ()
print "b"
m2 = m
print "c"
del m
print "d"
del m2
print "e"

File: chap4_classe.tex, line 1436


a
__new__
constructeur
b
c
d
__del__
e

File: chap4_classe.tex, line 1457


class classe_incluse:
    def __init__ (self) : self.attr = 3

class exemple_classe:
    def __init__ (self) : 
        self.inclus = classe_incluse ()
        self.rnd    = 42

nb = exemple_classe ()

import copy            # pour utiliser le module copy
nb2 = copy.copy (nb)   # copie explicite

print nb.inclus.attr   # affiche 3
print nb2.inclus.attr  # affiche 3

nb2.inclus.attr = 0

print nb.inclus.attr   # affiche 0 (on voudrait 3 ici)
print nb2.inclus.attr  # affiche 0

File: chap4_classe.tex, line 1485



class nom_classe :
    def __copy__ () :
        copie = nom_classe (...)
        # ...
        return copie

File: chap4_classe.tex, line 1503


import copy

class classe_incluse:
    def __init__ (self) : self.attr = 3

class exemple_classe:
    def __init__ (self) : 
        self.inclus  = classe_incluse ()
        self.rnd     = 42
    def __copy__ (self):
        copie        = exemple_classe ()
        copie.rnd    = self.rnd
        copie.inclus = copy.copy (self.inclus)
        return copie

nb  = exemple_classe ()

nb2 = copy.copy (nb)   # copie explicite,
                       # utilise l'opérateur __copy__,
                       # cette ligne est équivalente à
                       # nb2 = nb.__copy__()

print nb.rnd           # affiche 42
print nb2.rnd          # affiche 42
print nb.inclus.attr   # affiche 3
print nb2.inclus.attr  # affiche 3

nb.inclus.attr = 0
nb.rnd         = 1

print nb.rnd           # affiche 1
print nb2.rnd          # affiche 42
print nb.inclus.attr   # affiche 0
print nb2.inclus.attr  # affiche 3 (c'est le résultat souhaité)

File: chap4_classe.tex, line 1546


def fonction_liste ():
    return range (4,7) # retourne la liste [4,5,6]
l = fonction_liste ()  # la liste [4,5,6] n'est pas recopiée,
                       # l'identificateur l lui est affecté

File: chap4_classe.tex, line 1558


def fonction_liste ():
    return range (4,7)
fonction_liste () # la liste [4,5,6] n'est pas recopiée,
                  # elle n'est pas non plus attribuée à une variable,
                  # elle est alors détruite automatiquement par le langage Python

File: chap4_classe.tex, line 1575


l  = [4,5,6]
l2 = l
print l       # affiche [4, 5, 6]
print l2      # affiche [4, 5, 6]
l2 [1] = 10
print l       # affiche [4, 10, 6]
print l2      # affiche [4, 10, 6]

File: chap4_classe.tex, line 1589


l  = [4,5,6]
import copy
l2 = copy.copy (l)
print l       # affiche [4, 5, 6]
print l2      # affiche [4, 5, 6]
l2 [1] = 10
print l       # affiche [4, 5, 6]
print l2      # affiche [4, 10, 6]

File: chap4_classe.tex, line 1604


import copy
l  = [ [i] for i in range(0,3)]
ll = copy.copy (l)
print l, "  -  ", ll    # affiche [[0], [1], [2]]   -   [[0], [1], [2]]
ll [0][0] = 6
print l, "  -  ", ll    # affiche [[6], [1], [2]]   -   [[6], [1], [2]]

File: chap4_classe.tex, line 1619


import copy
l  = [ [i] for i in range(0,3)]
ll = copy.deepcopy (l)
print l, "  -  ", ll    # affiche [[0], [1], [2]]   -   [[0], [1], [2]]
ll [0][0] = 6
print l, "  -  ", ll    # affiche [[0], [1], [2]]   -   [[6], [1], [2]]

File: chap4_classe.tex, line 1635



import copy
memo = { } 
nom_copy = copy.deepcopy (nom_instance [,memo])

File: chap4_classe.tex, line 1648



class nom_classe :
    def __deepcopy__ (self,memo) :
        copie = copy.copy (self)
        # ...
        return copie

File: chap4_classe.tex, line 1665


import copy

class classe_incluse:
    def __init__ (self) : self.attr = 3

class exemple_classe:
    def __init__ (self) :
        self.inclus = classe_incluse ()
        self.rnd    = 42
    def __copy__ (self):
        copie       = exemple_classe ()
        copie.rnd   = self.rnd
        return copie
    def __deepcopy__ (self,memo):
        if self in memo : return memo [self]
        copie        = copy.copy (self)
        memo [self]  = copie    # mémorise la copie de self qui est copie
        copie.inclus = copy.deepcopy (self.inclus,memo)
        return copie

nb = exemple_classe ()

nb2 = copy.deepcopy (nb)   # copie explicite à tous niveaux,
                           # utilise l'opérateur __copy__,
                           # cette ligne est équivalente à
                           # nb2 = nb.__deepcopy__()

print nb.rnd           # affiche 42
print nb2.rnd          # affiche 42
print nb.inclus.attr   # affiche 3
print nb2.inclus.attr  # affiche 3

nb.inclus.attr = 0
nb.rnd = 1

print nb.rnd           # affiche 1
print nb2.rnd          # affiche 42
print nb.inclus.attr   # affiche 0
print nb2.inclus.attr  # affiche 3  # résultat souhaité

File: chap4_classe.tex, line 1711


import copy

class Objet1 :
    def __init__ (self, i) : self.i = i
    def __str__ (self) : 
        return "o1 " + str (self.i) + " : " + str (self.o2.i)

class Objet2 :
    def __init__ (self, i, o) :
        self.i  = i
        self.o1 = o
        o.o2    = self
    def __str__ (self) : 
        return "o2 " + str (self.i) + " : " + str (self.o1.i)
        
    def __deepcopy__ (self,memo) : return Objet2 (self.i, self.o1)
        
o1 = Objet1 (1)
o2 = Objet2 (2, o1)
print o1  # affiche o1 1 : 2
print o2  # affiche o2 2 : 1

o3   = copy.deepcopy (o2)
o3.i = 4
print o1  # affiche o1 1 : 4    --> on voudrait 2
print o2  # affiche o2 2 : 1
print o3  # affiche o2 4 : 1      

File: chap4_classe.tex, line 1745


import copy

class Objet1 :
    def __init__ (self, i) : self.i = i
    def __str__ (self) : 
        return "o1 " + str (self.i) + " : " + str (self.o2.i)
    def __deepcopy__ (self,memo={}) :
        if self in memo : return memo [self]
        r           = Objet1 (self.i)
        memo [self] = r
        r.o2        = copy.deepcopy (self.o2, memo)
        return r

class Objet2 :
    def __init__ (self, i, o) :
        self.i  = i
        self.o1 = o
        o.o2    = self
    def __str__ (self) : 
        return "o2 " + str (self.i) + " : " + str (self.o1.i)
        
    def __deepcopy__ (self,memo = {}) :
        if self in memo : return memo [self]
        r           = Objet2 (self.i, self.o1)
        memo [self] = r
        r.o1        = copy.deepcopy (self.o1, memo)
        return r
        
o1 = Objet1 (1)
o2 = Objet2 (2, o1)

print o1  # affiche o1 1 : 2
print o2  # affiche o2 2 : 1

o3   = copy.deepcopy (o2)
o3.i = 4
print o1  # affiche o1 1 : 2    --> on a 2 cette fois-ci
print o2  # affiche o2 2 : 1
print o3  # affiche o2 4 : 1      

File: chap4_classe.tex, line 1796



class nom_classe (object) :
    __slots__ = "attribut_1", ..., "attribut_n"

File: chap4_classe.tex, line 1807


class point_espace(object):
    __slots__ = "_x", "_y", "_z"
    
    def __init__ (self, x,y,z): self._x, self._y, self._z = x,y,z
    def __str__(self): return "(%f,%f,%f)" % (self._x, self._y, self._z)
        
a = point_espace (1,-2,3)
print a

File: chap4_classe.tex, line 1822


Traceback (most recent call last):
  File "cours4.py", line 15, in ?
    a.j = 6
AttributeError: 'point_espace' object has no attribute 'j'

File: chap4_classe.tex, line 1849


import random  # extension interne incluant des fonctions
               # simulant des nombres aléatoires,
               # random.randint (a,b) --> retourne un nombre entier entre a et b
               # cette ligne doit être ajoutée à tous les exemples suivant
               # même si elle n'y figure plus

def cent_tirages () :
    s = 0
    for i in range (0,100) : s += random.randint (0,1)
    return s
    
print cent_tirages ()

File: chap4_classe.tex, line 1869


def cent_tirages () :
    s = 0
    for i in range (0,100) :
        t = random.randint (0,10)
        if t >= 3 : s += 1
    return s
    
print cent_tirages ()

File: chap4_classe.tex, line 1884


def piece_normale () :
    return random.randint (0,1)
    
def piece_truquee () :
    t = random.randint (0,10)
    if t >= 3 : return 1
    else : return 0
    
def cent_tirages (piece) :
    s = 0
    for i in range (0,100) : s += piece ()
    return s
    
print cent_tirages (piece_normale)
print cent_tirages (piece_truquee)

File: chap4_classe.tex, line 1915


class piece_normale :
    def tirage (self) :
        return random.randint (0,1)
        
    def cent_tirages (self) :
        s = 0
        for i in range (0,100) : s += self.tirage ()
        return s

p = piece_normale ()
print p.cent_tirages ()

File: chap4_classe.tex, line 1933


class piece_normale :
    def tirage (self) :
        return random.randint (0,1)
        
    def cent_tirages (self) :
        s = 0
        for i in range (0,100) : s += self.tirage ()
        return s

class piece_truquee :
    def tirage (self) :
        t = random.randint (0,10)
        if t >= 3 : return 1
        else : return 0
        
    def cent_tirages (self) :
        s = 0
        for i in range (0,100) : s += self.tirage ()
        return s
        
p  = piece_normale ()
print p.cent_tirages ()
p2 = piece_truquee ()
print p2.cent_tirages ()

File: chap4_classe.tex, line 1967


class piece_normale :
    def tirage (self) :
        return random.randint (0,1)
        
    def cent_tirages (self) :
        s = 0
        for i in range (0,100) : s += self.tirage ()
        return s

class piece_truquee (piece_normale) :
    def tirage (self) :
        t = random.randint (0,10)
        if t >= 3 : return 1
        else : return 0
        
p  = piece_normale ()
print p.cent_tirages ()
p2 = piece_truquee ()
print p2.cent_tirages ()

File: chap4_classe.tex, line 1994


class piece_normale :
    def tirage (self) :
        return random.randint (0,1)
        
    def cent_tirages (self) :
        s = 0
        for i in range (0,100) : s += self.tirage ()
        return s

class piece_truquee (piece_normale) :
    def tirage (self) :
        t = random.randint (0,10)
        if t >= 3 : return 1
        else : return 0
        
class piece_tres_truquee (piece_truquee) :
    def __init__(self) :
        # création de l'attribut avant
        self.avant = 0 
        
    def tirage (self) :
        if self.avant == 0 :
            # appel de la méthode tirage de la classe piece_truquee
            self.avant = piece_truquee.tirage (self)
        else :
            # appel de la méthode tirage de la classe piece_normale
            self.avant = piece_normale.tirage (self)
        return self.avant
        
p = piece_normale ()
print "normale ", p.cent_tirages ()
p2 = piece_truquee ()
print "truquee ", p2.cent_tirages ()
p3 = piece_tres_truquee ()
print "tres truquee ", p3.cent_tirages ()

File: chap4_classe.tex, line 2063



class nom_classe (nom_ancetre) :
    # corps de la classe
    # ...

File: chap4_classe.tex, line 2078


help (piece_tres_truquee)

File: chap4_classe.tex, line 2086


Help on class piece_tres_truquee in module __main__:

class piece_tres_truquee(piece_truquee)
 |  Method resolution order:
 |      piece_tres_truquee
 |      piece_truquee
 |      piece_normale
 |  
 |  Methods defined here:
 |  
 |  __init__(self)
 |  
 |  tirage(self)
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from piece_normale:
 |  
 |  cent_tirages(self)

File: chap4_classe.tex, line 2116


for l in piece_tres_truquee.__bases__ : 
    print l   # affiche __main__.piece_truquee
print piece_normale in piece_tres_truquee.__bases__  # affiche False
print piece_truquee in piece_tres_truquee.__bases__  # affiche True

File: chap4_classe.tex, line 2126


print issubclass (piece_tres_truquee, piece_normale)  # affiche True
print issubclass (piece_truquee, piece_normale)       # affiche True

File: chap4_classe.tex, line 2140



class nom_classe (nom_ancetre) :
    def nom_autre_methode (self, ...) :
        # ...
    def nom_methode (self, ...) :
        nom_ancetre.nom_methode (self, ...)
            # appel de la méthode définie chez l'ancêtre
        nom_ancetre.nom_autre_methode (self, ...)
            # appel d'une autre méthode définie chez l'ancêtre
        self.nom_autre_methode (...)
            # appel d'une méthode surchargée

File: chap4_classe.tex, line 2159


class A :
    def __init__ (self) :
        self.x = 0
class B (A) :
    def __init__ (self) :
        A.__init__ (self)
        self.y = 0

File: chap4_classe.tex, line 2175


class ancetre :
    def __init__(self) :
        self.a = 5
    def __str__ (self) :
        return "a = " + str (self.a)

class fille (ancetre) :
    def __init__(self) :
        ancetre.__init__(self)     # cette ligne est importante
                                   # car sans elle, l'attribut a n'existe pas
        self.a += 1
    def __str__ (self) :
        s = "a = " + str (self.a)
        return s

x = ancetre ()  
print x         # affiche a = 5
y = fille ()
print y         # affiche a = 6

File: chap4_classe.tex, line 2209


class rectangle :
    def __init__(self,a,b) :
        self.a,self.b = a,b
    def __str__ (self) :
        return "rectangle " + str (self.a) +  " x " +  str (self.b)
        
class carre (rectangle) :
    def __init__( self, a) :
        rectangle.__init__ (self, a,a)
        
r = rectangle (3,4)
print r  # affiche rectangle 3 x 4
c = carre (5)
print c  # affiche rectangle 5 x 5

File: chap4_classe.tex, line 2230


class carre :
    def __init__( self, a) :
        self.a = a
    def __str__ (self) :
        return "carre " + str (self.a) 
        
class rectangle (carre):
    def __init__(self,a,b) :
        carre.__init__(self, a)
        self.b = b
    def __str__ (self) :
        return "rectangle " + str (self.a) +  " x " +  str (self.b)
        
r = rectangle (3,4)
print r  # affiche rectangle 3 x 4
c = carre (5)
print c  # affiche carre 5

File: chap4_classe.tex, line 2275


class A :
    def __init__ (self) : self.a = 5
    def carre (self) : return self.a ** 2

class B :
    def __init__ (self) : self.a = 6
    def cube (self) : return self.a ** 3

class C (A,B) :
    def __init__ (self):
        A.__init__ (self)

x = C ()
print x.carre ()    # affiche 25
print x.cube ()     # affiche 125

File: chap4_classe.tex, line 2297


class A :
    def __init__ (self) : self.a = 5
    def calcul (self) : return self.a ** 2

class B :
    def __init__ (self) : self.a = 6
    def calcul (self) : return self.a ** 3

class C (A,B) :
    def __init__ (self):
        A.__init__ (self)

x = C ()
print x.calcul ()  # affiche 25

File: chap4_classe.tex, line 2317


class C(A, B)
 |  Method resolution order:
 |      C
 |      A
 |      B
 |  
 |  Methods defined here:
 |  
 |  __init__(self)
 |  
 |  calcul(self)

File: chap4_classe.tex, line 2335


class A :
    def __init__ (self) : self.a = 5
    def calcul (self) : return self.a ** 2

class B :
    def __init__ (self) : self.a = 6
    def calcul (self) : return self.a ** 3

class C (A,B) :
    def __init__ (self):
        A.__init__ (self)
        
    def calcul (self) :
        return B.calcul (self)

x = C ()
print x.calcul ()  # affiche 125

File: chap4_classe.tex, line 2359


class C (A,B) :
    def __init__ (self):
        A.__init__ (self)
        B.__init__ (self)

File: chap4_classe.tex, line 2374



issubclass (B,A)

File: chap4_classe.tex, line 2385


class A (object) : pass
class B (A)      : pass
class C (B)      : pass
    
print issubclass (A, B)     # affiche False
print issubclass (B, A)     # affiche True
print issubclass (A, C)     # affiche False
print issubclass (C, A)     # affiche True

File: chap4_classe.tex, line 2398


a = A ()
b = B ()
print issubclass (a.__class__, B)     # affiche False
print issubclass (b.__class__, A)     # affiche True
print issubclass (a.__class__, A)     # affiche True

File: chap4_classe.tex, line 2409


a = A ()
b = B ()
print isinstance (a, B)     # affiche False
print isinstance (b, A)     # affiche True
print isinstance (a, A)     # affiche True

fonction \codesindex{isinstance

def fonction_somme_list (ens) :
    r = "list "
    for e in ens : r += e
    return r

def fonction_somme_dict (ens) :
    r = "dict "
    for k,v in ens.items () : r += v
    return r

def fonction_somme (ens) :
    if   isinstance (ens, dict) : return fonction_somme_dict (ens)
    elif isinstance (ens, list) : return fonction_somme_list (ens)
    else                        : return "erreur"
        
li = ["un", "deux", "trois"]
di = {1:"un", 2:"deux", 3:"trois"}
tu = ("un", "deux", "trois")
print fonction_somme (li)  # affiche list undeuxtrois
print fonction_somme (di)  # affiche dict undeuxtrois
print fonction_somme (tu)  # affiche erreur

File: chap4_classe.tex, line 2434


s = """class carre :
    def __init__( self, a) : self.a = a
    def __str__ (self)     : return "carre " + str (self.a) 
        
class rectangle (carre):
    def __init__(self,a,b) :
        carre.__init__(self, a)
        self.b = b
    def __str__ (self) :
        return "rectangle " + str (self.a) +  " x " +  str (self.b)"""

obj = compile(s,"","exec")       # code à compiler
exec (obj)                       # classes incorporées au programme
       
r = rectangle (3,4)
print r  # affiche rectangle 3 x 4
c = carre (5)
print c  # affiche carre 5

File: chap4_classe.tex, line 2459


# coding: latin-1
"""erreur de compilation incluses dans le code inséré dans la
chaîne de caractère s"""
s = """class carre :
    def __init__( self, a) :
        seilf.a = a   # erreur de compilation
    def __str__ (self) :
        return "carre " + str (self.a) """
        
obj = compile(s,"variable s","exec")   # code à compiler
exec (obj)                             # classes incorporées au programme
       
c = carre (5)
print c  # affiche carre 5

File: chap4_classe.tex, line 2480


Traceback (most recent call last):
  File "C:\temp\cours.py", line 14, in -toplevel-
    c = carre (5)
  File "variable s", line 3, in __init__
NameError: global name 'seilf' is not defined

exemple de classe

# coding: latin-1
# la première ligne autorise les accents
class fromage :
    
    def __init__ (self, p,c,o) :
        self.poids = p
        self.couleur = c
        self.odeur = o
        
    def decouper (self,nb) :
        l = []
        for i in range (0,nb) :
            f = fromage (self.poids/nb, \
                            self.couleur, self.odeur)
            l.append (f)
        return l

    def __str__ (self) :
        s = "poids : " + str (self.poids)
        s += " couleur : " + str (self.couleur)
        s += " odeur : " + str (self.odeur)
        return s

    def __add__ (self,f) :
        print "ajout fromage"
        poids = self.poids + f.poids
        couleur = [0,0,0]
        for i in range (0,3) :
            couleur [i] = (self.couleur [i] * self.poids \
                       + f.couleur [i] * f.poids) / poids
        odeur = (self.odeur * self.poids + \
                 f.odeur * f.poids) / poids
        couleur = ( couleur [0], couleur [1], couleur [2])
        return fromage (poids, couleur, odeur)

class gruyere (fromage) :
    def __init__ (self,p) :
        fromage.__init__ (self, p, c = (150,150,0), o = 0.1)

    def __str__ (self) :
        s = fromage.__str__(self)
        s = "gruyère, " + s
        return s

    def __add__ (self,f) :
        print "ajout gruyère"
        if not isinstance (f, gruyere) :
            return fromage.__add__ (self, f)
        else :
            r = gruyere (self.poids + f.poids)
            return r

#--------------------------------------------
fr = fromage (5.0, (255,0,0), 0.5)
fr2 = fromage (10.0, (0,255,0), 1)
fr3 = fr + fr2
print fr
print fr2
print fr3
print "----------------------"
g = gruyere (3.0)
g2 = gruyere (7.0)
g3 = g + g2
print g
print g2
print g3
print "----------------------"
print fr2 + g

héritage

class Fonction :
    def calcul (self, x) : pass
    def calcul_n_valeur (self, l) :
        res = [ self.calcul (i) for i in l ]
        return res
        
class Carre (Fonction) :
    def calcul (self, x) : return x*x
        
class Cube (Fonction) :
    def calcul (self, x) : return x*x*x

l = [0,1,2,3]
print l   # affiche [0, 1, 2, 3]

l1 = Carre ().calcul_n_valeur (l)  # l1 vaut [0, 1, 4, 9]
l2 = Cube () .calcul_n_valeur (l)  # l2 vaut [0, 1, 8, 27]

méthode paramètre d'une fonction

class Fonction :
    def calcul (self, x) : pass
class Carre (Fonction) :
    def calcul (self, x) : return x*x
class Cube (Fonction) :
    def calcul (self, x) : return x*x*x
        
def calcul_n_valeur (l,f):
    res = [ f(i) for i in l ]
    return res

l = [0,1,2,3]
l1 = calcul_n_valeur (l, Carre ().calcul) # l1 vaut [0, 1, 4, 9]
l2 = calcul_n_valeur (l, Cube ().calcul)  # l2 vaut [0, 1, 8, 27]

File: chap4_classe.tex, line 2523


class Matrice :
    def __init__ (self,lin,col,coef):
        self.lin, self.col = lin, col
        
    # interface d'échange
    def get_lin () : return self.lin
    def get_col () : return self.col
    def __getitem__(self,i,j): pass
    def __setitem__(self,i,j,v): pass
    def get_submat(self, i1,j1,i2,j2): pass
    def set_submat(self, i1,j1,mat): pass 
    # fin de l'interface d'échange
    
    def trace (self) :
        t = 0
        for i in xrange (0, self.lin):
            t += self (i,i)
        return t
        
class MatriceList (Matrice) :
    def __init__ (self,lin,col,coef):
        Matrice.__init__ (self, \
                      lin, col, coef)
        #...

    def __getitem__ (self, i,j) : #...
    def __setitem__ (self, i,j, v) : #...
    def get_submat(self, i1,j1,i2,j2): #...
    def set_submat(self, i1,j1,mat): #...
    
class MatriceDict (Matrice) :
    def __init__ (self,lin,col,coef):
        Matrice.__init__ (self, \
                       lin, col, coef)
        #...
        
    def __getitem__ (self, i,j) : #...
    def __setitem__ (self, i,j, v) : #...
    def get_submat(self, i1,j1,i2,j2): #...
    def set_submat(self, i1,j1,mat): #...

File: chap4_classe.tex, line 2568


class Produit :
    def calcul (self, mat1, mat2):
        pass

class ProduitClassique (Produit) :
    def calcul (self, mat1, mat2):
        #...
        return 
        
class ProduitStrassen (Produit) :
    def calcul (self, mat1,mat2):
        #...
        return 

File: chap5_exception.tex, line 19


x = 0
y = 1.0 / x

File: chap5_exception.tex, line 28


Traceback (most recent call last):
  File "cours.py", line 2, in ?
    y = 1.0 / x
ZeroDivisionError: float division

File: chap5_exception.tex, line 51


def inverse (x):
    y = 1.0 / x
    return y
    
a = inverse (2)
print a
b = inverse (0)
print b

File: chap5_exception.tex, line 66


Traceback (most recent call last):
  File "cours.py", line 8, in ?
    b = inverse (0)
  File "cours.py", line 3, in inverse
    y = 1.0 / x
ZeroDivisionError: float division

File: chap5_exception.tex, line 80


def inverse (x):
    y = 1.0 / x
    return y
    
try :
    a = inverse (2)
    print a
    b = inverse (0)  # déclenche une exception
    print b
except :
    print "le programme a déclenché une erreur"

File: chap5_exception.tex, line 98


0.5
le programme a déclenché une erreur

File: chap5_exception.tex, line 108


def inverse (x):
    y = 1.0 / x
    return y
    
try :
    print inverse (2)  # pas d'erreur
    print inverse (1)  # pas d'erreur non plus
except :
    print "le programme a déclenché une erreur"
else :
    print "tout s'est bien passé"

File: chap5_exception.tex, line 125


0.5
1.0
tout s'est bien passé

File: chap5_exception.tex, line 135


try : 
    # ... instructions à protéger
except :
    # ... que faire en cas d'erreur 
else : 
    # ... que faire lorsque aucune erreur n'est apparue

File: chap5_exception.tex, line 152


def inverse (x):
    y = 1.0 / x
    return y
    
try :
    print (-2.1) ** 3.1  # première erreur
    print inverse (2)
    print inverse (0)    # seconde erreur
except :
    print "le programme a déclenché une erreur"

File: chap5_exception.tex, line 174


def inverse (x):
    y = 1.0 / x
    return y
    
try :
    print inverse (2)
    print inverse (0)
except Exception, exc:
    print "exception de type ", exc.__class__  
         # affiche exception de type  exceptions.ZeroDivisionError
    print "message ", exc
         # affiche le message associé à l'exception

File: chap5_exception.tex, line 194


def inverse (x):
    y = 1.0 / x
    return y
    
try :
    print (-2.1) ** 3.1  # première erreur
    print inverse (2)
    print inverse (0)    # seconde erreur
except Exception, exc:
    if isinstance (exc, ZeroDivisionError) :
        print "division par zéro"
    else :
        print "erreur insoupçonnée : ", exc.__class__
        print "message ", exc

File: chap5_exception.tex, line 215


erreur insoupçonnée :  exceptions.ValueError

File: chap5_exception.tex, line 223


def inverse (x):
    y = 1.0 / x
    return y
    
try :
    print (-2.1) ** 3.1
    print inverse (2)
    print inverse (0)
except ZeroDivisionError:
    print "division par zéro"
except Exception, exc:
    print "erreur insoupçonnée : ", exc.__class__
    print "message ", exc

File: chap5_exception.tex, line 243



try :
    # ... instructions à protéger
except type_exception_1 :
    # ... que faire en cas d'erreur de type type_exception_1
except type_exception_i :
    # ... que faire en cas d'erreur de type type_exception_i
except type_exception_n :
    # ... que faire en cas d'erreur de type type_exception_n
except :
    # ... que faire en cas d'erreur d'un type différent de tous 
    #     les précédents types
else :
    # ... que faire lorsque une erreur aucune erreur n'est apparue

File: chap5_exception.tex, line 381


def inverse (x):
    if x == 0 :
        raise ValueError
    y = 1.0 / x
    return y
    
try :
    print inverse (0)  # erreur
except ValueError:
    print "erreur"

File: chap5_exception.tex, line 399


def inverse (x):
    if x == 0 :
        raise ValueError ("valeur nulle interdite, fonction inverse")
    y = 1.0 / x
    return y
    
try :
    print inverse (0)  # erreur
except ValueError, exc:
    print "erreur, message : ", exc

File: chap5_exception.tex, line 417



raise exception_type (message) :

File: chap5_exception.tex, line 437


class ZeroDivisionError(ArithmeticError)
 |  Second argument to a division or modulo operation was zero.
 |  
 |  Method resolution order:
 |      ZeroDivisionError
 |      ArithmeticError
 |      StandardError
 |      Exception

File: chap5_exception.tex, line 473


def inverse (x):
    y = 1.0 / x
    return y
    
try :
    try :    
        print inverses (0)  # fonction inexistante --> exception NameError
        print inverse (0)   # division par zéro --> ZeroDivisionError
    except NameError:
        print "appel à une fonction non définie"
except ZeroDivisionError, exc:
    print "erreur ", exc

File: chap5_exception.tex, line 492


def inverse (x):
    y = 1.0 / x
    return y
    
try :
    try :    
        print inverse (0)   # division par zéro --> ZeroDivisionError
        print inverses (0)  # fonction inexistante --> exception NameError
    except NameError:
        print "appel à une fonction non définie"
except ZeroDivisionError, exc:
    print "erreur ", exc

File: chap5_exception.tex, line 511


def inverse (x):
    try :
        y = 1.0 / x
    except ZeroDivisionError, exc:
        print "erreur ", exc
        if x > 0 : return 1000000000
        else : return -1000000000
    return y
    
try :    
    print inverse (0)   # division par zéro    --> la fonction inverse sait gérer
    print inverses (0)  # fonction inexistante --> exception NameError
except NameError:
    print "appel à une fonction non définie"

File: chap5_exception.tex, line 541


class AucunChiffre (Exception) :
    """chaîne de caractères contenant aussi autre chose que des chiffres"""

def conversion (s) :
    """conversion d'une chaîne de caractères en entier"""
    if not s.isdigit () :
        raise AucunChiffre (s)
    return int (s)

try :
    s = "123a"
    print s, " = ", conversion (s)
except AucunChiffre, exc :
    # on affiche ici le commentaire associé à la classe d'exception
    # et le message associé
    print AucunChiffre.__doc__, " : ", exc

File: chap5_exception.tex, line 564


class AucunChiffre (Exception) :
    """chaîne de caractères contenant aussi autre chose que des chiffres"""
    def __str__ (self) :
        return self.__doc__ + " " + Exception.__str__ (self)

File: chap5_exception.tex, line 585


class AucunChiffre (Exception) :
    """chaîne de caractères contenant aussi autre chose que des chiffres"""
    def __init__(self, s, f = "") :
        Exception.__init__(self, s)
        self.s = s
        self.f = f
    def __str__(self) :
        return """exception AucunChiffre, depuis la fonction """ + self.f + \
                  " avec le paramètre " + self.s

def conversion (s) :
    """conversion d'une chaîne de caractères en entier"""
    if not s.isdigit () :
        raise AucunChiffre (s, "conversion")
    return int (s)

try :
    s = "123a"
    i = conversion (s)
    print s, " = ", i
except AucunChiffre, exc :
    print exc
    print "fonction : ", exc.f

File: chap5_exception.tex, line 615


exception AucunChiffre, depuis la fonction conversion avec le paramètre 123a
fonction :  conversion

File: chap5_exception.tex, line 631


class point_espace:
    
    #...
            
    class class_iter:
        def __init__ (self,ins):
            self._n   = 0
            self._ins = ins
        def __iter__ (self) : 
            return self
        def next (self):
            if self._n <= 2:
                v = self._ins [self._n]
                self._n += 1
                return v
            else :
                raise StopIteration
    
    def __iter__(self):
        return point_espace.class_iter (self)

# ...

File: chap5_exception.tex, line 664


def racine_carree(x) :
    if x < 0 : return False, 0
    else : return True, x ** 0.5
print racine_carree (-1)  # (False, 0)
print racine_carree (1)   # (True, 1.0)

File: chap5_exception.tex, line 676


def racine_carree(x) :
    if x < 0 : raise ValueError ("valeur négative")
    return x ** 0.5
print racine_carree (-1)  # déclenche une exception
print racine_carree (1)

fichier ouvert et exception

# coding: latin-1
def ajoute_resultat_division (nom, x, y) :
    """ajoute le résultat de la division x/y au fichier nom"""
    f = open (nom, "a")
    f.write (str (x) + "/" + str (y) + "= ")
    f.write ( str ((float (x)/y)) + "\n" )     # exception si y == 0
    f.close ()
    
for i in range (0, 5) :
    try :
        print str (i-1) + "/" + str (i-2)
        ajoute_resultat_division ("essai.txt", i-1,i-2)
    except Exception, e : print "erreur avec i = ", i, ",", e

File: chap5_exception.tex, line 698


-1/-2
0/-1
1/0
erreur avec i =  2 , float division
2/1
3/2

File: chap5_exception.tex, line 709


-1/-2= 0.5
0/-1= 0.0
2/1= 2.0
3/2= 1.5
1/0= 


# coding: latin-1
"""exemple de module, aide associée"""

exemple_variable = 3

def exemple_fonction () :
    """exemple de fonction"""
    return 0
    
class exemple_classe :
    """exemple de classe"""
    def __str__ (self) :
        return "exemple_classe"

(1)

import module_exemple

c = module_exemple.exemple_classe ()
print c
print module_exemple.exemple_fonction()
help (module_exemple)








File: chap6_module.tex, line 58


import module_exemple
module_exemple.exemple_variable = 10
reload (module_exemple)
print module_exemple.exemple_variable   # affiche 3

(2)

import module_exemple as alias

c = alias.exemple_classe ()
print c
print alias.exemple_fonction ()
help (alias)

(3)

from module_exemple import *

c = exemple_classe ()
print c
print exemple_fonction ()

(4)

alias = __import__ ("module_exemple")

c = alias.exemple_classe ()
print c
print alias.exemple_fonction ()
help (alias)

File: chap6_module.tex, line 99


if __name__ == "__main__" :
    print "ce fichier est le programme principal"

File: chap6_module.tex, line 113


import sys
sys.path.append (sys.path [0] + "/../common")  
################ sys.path [0] = répertoire de ce programme
import nom_module

import dynamique de module

# coding: latin-1
def import_fichier (module) :
    import os.path
    import sys
    if os.path.exists (module) :           # on teste l'existence du fichier
        folder,name = os.path.split (module)  # on obtient le répertoire du module
        if folder not in sys.path :
            sys.path.append (folder)       # on ajoute le répertoire dans la liste
                                           # des répertoires autorisés
        name = name.replace (".py", "")    # on enlève l'extension
        module = __import__ (name)         # on importe le module
        return module
    else :
        # si le fichier n'existe pas --> on lève une exception
        raise ImportError ("impossible d'importer le module " + module)
        
# on importe un module    
mod = import_fichier (r"D:\Dupre\informatique\programme\corde.py")
# on affiche l'aide associée
help (mod)

File: chap6_module.tex, line 137


import sys
for m in sys.modules :
    print m, " " * (14 - len(str(m))), sys.modules [m]

File: chap6_module.tex, line 144


os              <module 'os' from 'c:\python26\lib\os.pyc'>
os.path         <module 'ntpath' from 'c:\python26\lib\ntpath.pyc'>
re              <module 're' from 'c:\python26\lib\re.pyc'>
site            <module 'site' from 'c:\python26\lib\site.pyc'>
sys             <module 'sys' (built-in)>
types           <module 'types' from 'c:\python26\lib\types.pyc'>
...

File: chap6_module.tex, line 158


module_exemple  <module 'module_exemple' from 'D:\python_cours\module_exemple.py'>

File: chap6_module.tex, line 167


if "module_exemple" in sys.modules :
    m = sys.modules ["module_exemple"]
    m.exemple_fonction ()

File: chap6_module.tex, line 191


import os
print os.__name__, os.__doc__
if __name__ == "__main__" : print "ce fichier est le point d'entrée"
else : print "ce fichier est importé"

File: chap6_module.tex, line 211


import mesmodules.extension
import mesmodules.part1.niveaudeux
import mesmodules.part2.niveaudeuxbis

estimation du nombre $\pi$

# coding: latin-1
import random
import math

somme = 0
nb    = 1000000
for i in range (0,nb) :
    x = random.random ()  # nombre aléatoire entre [0,1]
    y = random.random ()
    r = math.sqrt (x*x + y*y)  # racine carrée
    if r <= 1 : somme += 1
        
print "estimation ", 4 * float (somme) / nb
print "PI = ", math.pi

intégrale de Monte Carlo

import random  # import du module random : simulation du hasard
import math    # import du module math : fonctions mathématiques

def integrale_monte_carlo (a,b,f,n) :
    somme = 0.0
    for i in range (0,n) :
        x = random.random () * (b-a) + a
        y = f(x)
        somme += f(x)
    return somme / n
    
def racine (x) : return math.sqrt (x)
    
print integrale (0,1,racine,100000)

File: chap6_module.tex, line 284


def get_page_html (url):
    import urllib
    d = urllib.urlopen(url)
    res = d.read ()
    d.close ()
    return res

url = "http://www.lemonde.fr"
print get_page_html (url)

File: chap6_module.tex, line 304


c:\python26\python c:\python26\lib\pydoc.py -w nom_de_fichier

génération automatique de l'aide avec \codesindex{pydoc

# coding: latin-1
"""aide associée à ce module, exemple d'utiliation de pydoc"""
import os.path
import os

def pydoc_present () :
    """teste la présence du fichier pydoc.py"""
    p = "c:\\python26\\lib\\pydoc.py"""
    return os.path.exists (p)
    
def pydoc_generation (file) :
    """génère la documentation associée au fichier file"""
    if not pydoc_present () :
        raise Exception ("pydoc n'est pas installé")
    os.system ("c:\\python26\\python c:\\python26\\lib\\pydoc.py -w " + file)

class ExempleClass (object) :
    """exemple de classe avec de la documentation
    la classe contient comme attribut :
       - li : liste quelconque
    """
    def __init__ (self) :
        object.__init__ (self)
        self.li = ["un", "deux"]
    def __str__ (self) :
        """permet d'afficher la classe sous forme de chaînes de caractères"""
        return "li = " + str (self.li)
        
if __name__ == "__main__" :
    e = ExempleClass ()
    print e  # affiche li = ['un', 'deux']
    pydoc_generation ("exemple_pydoc")

File: chap6_module.tex, line 342


c:\python26\python setup.py install

File: chap6_module.tex, line 349


python setup.py install

un module en C++

#include <Python.h>
#include <stdio.h>

/** 
Une fois importe, le module definit deux fonctions :
    - exemple qui prend une chaine en argument et retourne 0
    - exemple2 qui leve une exception creee pour l'occasion 
*/



static PyObject* ExempleErreur;

static PyObject* exemple (PyObject* self, PyObject* args)
{
  const char* chaine;

  if (!PyArg_ParseTuple (args, "s", &chaine))
    return NULL;

  return Py_BuildValue("i", 2); 
}

static PyObject* exemple2(PyObject* self, PyObject* args)
{
  //const char* chaine ;

  PyErr_SetString (ExempleErreur, "Exemple de levée d'erreur") ;
  return NULL;
}

////////////////////////////////////////////////////
//////////// export des fonctions //////////////////
////////////////////////////////////////////////////

const char * module_name = "sample_module" ;
char buffer [100] ;

static PyMethodDef fonctions [] = {
  {"exemple",   exemple,    METH_VARARGS, "Un commentaire"},
  {"exemple2",  exemple2,   METH_VARARGS, "Une methode levant une exception"},
  {NULL, NULL, 0, NULL}
} ;

PyMODINIT_FUNC initsample_module(void)
{
  PyObject* m ;
  m = Py_InitModule (module_name, fonctions) ;
  
  
  sprintf (buffer, "%s.Exception", module_name) ;
  ExempleErreur = PyErr_NewException(buffer, NULL, NULL) ;
  Py_INCREF (ExempleErreur) ;
  PyModule_AddObject (m, "Exception", ExempleErreur) ;
}

importer un module en C++

# coding: latin-1
"""
import d'un module C (un fichier), inclut la recompilation 
si le module a évolué depuis sa dernière compilation
"""

import os, sys, re

def _find_compiled_file (path, name) :
    """cherche un fichier compilé"""
    ver         = sys.version_info
    st          = "%d.%d" % ver [:2]
    name        = os.path.splitext (name) [0]
    exp         = re.compile (name + "[.]o$")
    file, rep   = [], []
    for r, d, f in os.walk (path) :
        if st not in r : continue
        for a in f : 
            if exp.search (a) :
                return r,a
    return None,None

def import_c_module (name, mingw = r"c:\MinGW\bin", cpp = True, remove = False, path = None) :
    """
    @ingroup SQLAppModels    
    import d'un module C
    @param      name        nom du module C (nom du fichier sans extension, sans chemin non plus)
    @param      mingw       emplacement du compilateur mingw
    @param      cpp         c++ file?
    @param      remove      remove the file first before compiling
    @param      path        if the file is not found, try to look into this folder
    @return                 objet module
    
    @warning    remove = True must be used when the module is compiled for the first time. 
                Otherwise, the module is already loaded and impossible to remove until Python is closed.
    """
    if os.path.splitext (name) [1] == "" : 
        if cpp : 
            name += ".cpp"
            ext   = "cpp"
        else : 
            name += ".c"
            ext   = "c"
    else :
        ext = os.path.splitext (name) [1] [1:]
        
    mfile   = name
    mod     = os.path.splitext (mfile) [0]
    if path != None :
            mypath  = os.path.normpath (os.path.realpath (path))
            allpath = [mypath, "."]
    else :  allpath = ["."]
        
    for p in sys.path :
        if p not in allpath : allpath.append (p)
    
    for path in allpath :
        whole = os.path.join (path, name)
        if os.path.exists (whole) :
            break
    else :
        path_tried = u"\n".join (allpath)
        raise ImportError ("unable to find file %s in any import path:\n%s" \
                                % (name, path_tried))
        
    if sys.platform == "win32" : fsec = mod + ".pyd"
    else :                       fsec = mod + ".so"
        
    if path not in sys.path :
        sys.path.append (path)
        
    comp = os.path.join (path, fsec)
    if not os.path.exists (comp) :
        cond = True 
        resa = "not found"
    else :
        if remove :
            os.remove (comp)
            cond = True
            resa = "remove"
        else :
            r,f     = _find_compiled_file (path, mfile)
            if f != None :
                wholeo  = os.path.join (r,f)
                datec   = os.path.getmtime (whole)
                date    = os.path.getmtime (wholeo)
                cond    = datec > date
                resa    = "date"
            else :
                cond = True
                resa = "f == None"
                
    if cond :
        mfile = mod

        file =  ("""
                # coding: latin-1
                from distutils.core import setup
                from distutils.core import Extension

                setup(name          = '%s',
                      version       = '0.1',
                      ext_modules   = [Extension('%s', ['%s.%s']), ],
                      url           = '',
                      author        = '',
                      author_email  = '...',
                      )
                """ % (mfile,mfile,mfile,ext)).replace ("                ", "")
        wr   = os.path.join (path, "setup.py")
        f = open (wr, "w")
        f.write (file)
        f.close ()
        
        env = os.getenv ("PATH")
        if mingw not in env : 
            os.putenv ("PATH", env + ";" + mingw)
        
        cwd = os.getcwd ()
        os.chdir (path)
        
        py = sys.executable.replace ("pythonw.exe", "python.exe")
        if sys.platform == "win32" :    
                cmd  = "%s setup.py build_ext --inplace -c mingw32" % (py)
        else :  cmd  = "%s setup.py build_ext --inplace" % (py)
        child_stdin, stdout, child_stderr = os.popen3 (cmd)
        res = stdout.read ()
        err = child_stderr.read ()
        stdout.close ()
        
        os.chdir (cwd)
        
        if len (err) > 0 :
            message  = "\nOUTPUT:\n" + res + "\n\n"
            message += "ERR:\n" + err
            if "error" in err :
                message += "unable to compile %s (resa %s)\n%s" % (name, resa, message)
                print (message)
                raise ImportError (message)
            else :
                print (message)
            
        mod = __import__ (mfile)
        return mod
    
    else :
        mfile   = mod
        mod     = __import__ (mfile)
        return mod
    
if __name__ == "__main__" :
    sample_module = import_c_module ("sample_module", cpp = True)
    print sample_module

    print sample_module.exemple("e")
    print sample_module.exemple2() 

File: chap6_module.tex, line 467


BOOST_PYTHON_MODULE(PythonSample)
{ 
  // étapes d'initialisation
} ;

File: chap6_module.tex, line 479


int fonction (int r, const char * s, double x = 4) ;
BOOST_PYTHON_MODULE(PythonSample)
{ 
  boost::python::def ("fonction", fonction, 
                        (boost::python::arg ("r"), 
                         boost::python::arg ("s"), 
                         boost::python::arg ("x") = 4),
                         "aide associée à la fonction") ;
} ;

File: chap6_module.tex, line 504


import PythonSample
print PythonSample.fonction (4, "second")
print PythonSample.fonction (4, "second", 5)

File: chap6_module.tex, line 520


boost::python::class_<PythonClassSample> obj (
          "ClassSample", 
          "help on PythonClassSample") ) ;

File: chap6_module.tex, line 538

   
boost::python::class_<PythonClassSample> obj (
        "ClassSample", 
        "help on PythonClassSample",
        boost::python::init<int,const char*> (                     // ajout
             (boost::python::arg ("a"),                            // ajout
              boost::python::arg ("s") = "default value for s"),   // ajout
              "help on PythonClassSample constructor" )            // ajout
        ) ;

File: chap6_module.tex, line 551

   
boost::python::class_<PythonClassSample,  
                      boost::python::bases<ClassBase> > obj (
                           "ClassSample", 
                           "help on PythonClassSample") ;

File: chap6_module.tex, line 560


boost::python::class_<PythonClassSample, 
           boost::python::bases<ClassBase> > obj (
         // ...

File: chap6_module.tex, line 575

   
obj.def (   "Random",                      
            &PythonClassSample::Random, 
            (boost::python::arg ("pos")),  
            "help on the method") ;

File: chap6_module.tex, line 584

   
boost::python::class_<MyVector> obj ("Vector", "help on vector",
        boost::python::init<int> (
        (PY_ARG ("n")),
        "crée un vecteur de dimension n")) ;
// ajout d'un constructeur sans paramètre
obj.def (boost::python::init<MyVector> ()) ;

File: chap6_module.tex, line 595

   
v  = PythonSample.Vector ()
v2 = PythonSample.Vector (10)

File: chap6_module.tex, line 604

   
obj.def_readwrite ("a", &PythonClassSample::_a, "retourne un accès à a") ;

File: chap6_module.tex, line 643


#ifndef LIB_MAFONCTION_H
#define LIB_MAFONCTION_H

#include <vector>

void somme_vecteur (
  const std::vector<double> &v1,
  const std::vector<double> &v2,
  std::vector<double> &res) ;

#endif










File: chap6_module.tex, line 668


#include "mafonction.h"
void somme_vecteur (
  const std::vector<double> &v1,
  const std::vector<double> &v2,
  std::vector<double> &res)
{
  if (v1.size () != v2.size ())
    throw std::runtime_error (
         "dimensions différentes") ;
  res.resize (v1.size ()) ;
  std::vector<double>::
          const_iterator it1,it2 ;
  std::vector<double>::iterator it3 ;
  for (it1 = v1.begin (), 
       it2 = v2.begin (),
       it3 = res.begin () ; 
       it1 != v1.end () ;
       ++it1, ++it2, ++it3) 
       *it3 = *it1 + *it2 ;
}	

File: chap6_module.tex, line 695


#ifndef PYTHON_MAFONCTION_H
#define PYTHON_MAFONCTION_H

#include "python/definition.h"

boost::python::list
     python_somme_vecteur (
        boost::python::list v1,
        boost::python::list v2) ;
        
#endif        
        
        
        
        
        
        
        

File: chap6_module.tex, line 719


#include "python/definition.h"
#include "mafonction.h"
#include "../libsample/mafonction.h"
#include "python/conversion.h"
#include "python/conversion.hpp"
boost::python::list 
     python_somme_vecteur (
        boost::python::list v1,
        boost::python::list v2)
{
  std::vector<double> cv1,cv2,cres ;
  PythonConvert (v1, cv1) ;
  PythonConvert (v2, cv2) ;
  somme_vecteur (cv1, cv2, cres) ;
  boost::python::list res ;
  PythonConvert (cres, res) ;
  return res ;
}        

File: chap6_module.tex, line 744


// ...
#include "../mafonction.h"
BOOST_PYTHON_MODULE(PythonSample)
{
  // ...
  def ("somme_vecteur", 
        &python_somme_vecteur,
        (boost::python::arg ("v1"),
         boost::python::arg ("v2")),
 "retourne la somme de deux vecteurs");
  // ...
} ;

File: chap6_module.tex, line 762


import PythonSample as PS
v1 = [1.0, 2.0]
v2 = [6.5, 7.8]
v3 = PS.somme_vecteur (v1, v2) 









File: chap6_module.tex, line 799


class PythonClassSample 
{
    ...
    PythonClassSample & __iadd__ (const PythonClassSample &a) ;
    ...
} ;

File: chap6_module.tex, line 810


x.def ("__iadd__", 
       &PythonClassSample::__iadd__, 
       boost::python::return_internal_reference<>(), 
       "addition") ;

import d'une DLL

import sys
if "PythonSample" not in sys.modules :
    PythonSample = imp.load_dynamic ('PythonSample', PythonSample.dll) 
    sys.modules ["PythonSample"]  = PythonSample

File: chap6_module.tex, line 844


import PythonSampled as PythonSample
# au lieu de import PythonSample

File: chap6_module.tex, line 851


import sys
if "PythonSampled" in sys.modules : PythonSample = sys.modules ["PythonSampled"]
else : import PythonSample

File: chap6_module.tex, line 872


if (<condition>)
    throw std::runtime_error ("message d'erreur") ;

File: chap7_fichiers.tex, line 47


f = open ("nom-fichier", "w")    # ouverture

f.write ( s )    # écriture de la chaîne de caractères  s 
f.write ( s2 )   # écriture de la chaîne de caractères  s2
...

f.close ()  # fermeture

File: chap7_fichiers.tex, line 75


mat =  ... # matrice de type liste de listes
f = open ("mat.txt", "w")
for i in range (0,len (mat)) :                # la fonction join est aussi
    for j in range (0, len (mat [i])) :       # fréquemment utilisée
        f.write ( str (mat [i][j]) + "\t")    # pour assembler les chaînes
    f.write ("\n")                            # un une seule et réduire le
f.close ()                                    # nombre d'appels à f.write

File: chap7_fichiers.tex, line 94


mat = ... # matrice de type liste de listes
f = open ("mat.txt", "w")
for i in range (0,len (mat)) :
    for j in range (0, len (mat [i])) :
        print >> f, str (mat [i][j]), "\t",  # ligne changée
    print >> f                               # ligne changée
f.close ()

File: chap7_fichiers.tex, line 117


f = open ("nom-fichier", "a")    # ouverture en mode ajout, mode "a"
...

File: chap7_fichiers.tex, line 129


f = open ("essai.txt", "w")
f.write (" premiere fois ")
f.close ()
f = open ("essai.txt", "w")
f.write (" seconde fois ")
f.close ()

# essai.txt : seconde fois 

File: chap7_fichiers.tex, line 142


f = open ("essai.txt", "w")
f.write (" premiere fois ")
f.close ()
f = open ("essai.txt", "a")  ###
f.write (" seconde fois ")
f.close ()

# essai.txt : premiere fois  seconde fois 

File: chap7_fichiers.tex, line 180


f = open ("essai.txt", "r")  # ouverture du fichier en mode lecture
for ligne in f :             # pour toutes les lignes du fichier
    print ligne              # on affiche la ligne (*)
f.close ()                   # on ferme le fichier

File: chap7_fichiers.tex, line 192


f = open ("essai.txt", "r") # ouverture du fichier en mode lecture
l = f.readlines ()          # lecture de toutes les lignes, placées dans une liste
f.close ()                  # fermeture du fichier

for s in l : print s        # on affiche les lignes à l'écran (*)

File: chap7_fichiers.tex, line 208


f = open ("essai.txt", "r") # ouverture du fichier en mode lecture
l = f.readlines ()          # lecture de toutes les lignes, placées dans une liste
f.close ()                  # fermeture du fichier

     # contiendra la liste des lignes nettoyées
l_net = [ s.strip ("\n\r") for s in l ] 

File: chap7_fichiers.tex, line 225


nom  ; prénom ; livre
Hugo  ; Victor  ; Les misérables
Kessel ; Joseph  ; Le lion
Woolf ; Virginia  ; Mrs Dalloway
Calvino ; Italo  ; Le baron perché

File: chap7_fichiers.tex, line 237


mat = []                      # création d'une liste vide,
f = open ("essai.txt", "r")   # ouverture du fichier en mode lecture
for li in f :                 # pour toutes les lignes du fichier
    s = li.strip ("\n\r")     # on enlève les caractères de fin de ligne
    l = s.split (";")         # on découpe en colonnes
    mat.append (l)            # on ajoute la ligne à la matrice
f.close ()                    # fermeture du fichier

File: chap7_fichiers.tex, line 267


import zipfile
file = zipfile.ZipFile ("exemplezip.zip", "r")
for info in file.infolist () :
    print info.filename, info.date_time, info.file_size
file.close ()

File: chap7_fichiers.tex, line 279


import zipfile
file = zipfile.ZipFile ("exemplezip.zip", "r")
data = file.read ("informatique/testzip.py")
file.close ()
print data

File: chap7_fichiers.tex, line 296


import zipfile
file = zipfile.ZipFile ("test.zip", "w")
file.write ("fichier.txt", "nom_fichier_dans_zip.txt", zipfile.ZIP_DEFLATED)
file.close ()

envoi d'un mail automatiquement

import smtplib
from email.MIMEMultipart    import MIMEMultipart
from email.MIMEBase         import MIMEBase
from email.MIMEText         import MIMEText
from email.Utils            import formatdate
from email                  import Encoders
import os

def envoyer_mail (aqui, sujet, contenu, files = []):
    de              = "email de l'auteur"
    msg             = MIMEMultipart()
    msg ['From']    = de
    msg ['To']      = aqui
    msg ['Date']    = formatdate (localtime = True)
    msg ['Subject'] = sujet

    msg.attach(  MIMEText (contenu) )
    for file in files:
        part = MIMEBase('application', 'octet-stream')
        part.set_payload ( open(file,'rb').read () )
        Encoders.encode_base64 (part)
        part.add_header ('Content-Disposition',  \
                         'attachment; filename="%s"' % os.path.basename (file))
        msg.attach (part)

    smtp = smtplib.SMTP ("smtp.gmail.com", 587)
    smtp.ehlo ()
    smtp.starttls ()
    smtp.ehlo ()
    smtp.login ("login", "mot_de_passe")

    smtp.sendmail (de, aqui, msg.as_string () )
    smtp.close()
    
envoyer_mail ( "destinataire", "sujet","contenu", ["mail.py"] )

(1)

# coding: latin-1
import glob
import os.path

def liste_fichier_repertoire (folder, filter) :
    # résultats
    file,fold = [], []
    
    # recherche des fichiers obéissant au filtre
    res = glob.glob (folder + "\\" + filter)
    
    # on inclut les sous-répertoires qui n'auraient pas été
    # sélectionnés par le filtre
    rep = glob.glob (folder + "\\*")
    for r in rep : 
        if r not in res and os.path.isdir (r) : 
            res.append (r)
            
    # on ajoute fichiers et répertoires aux résultats
    for r in res :
        path = r
        if os.path.isfile (path) :
            # un fichier, rien à faire à part l'ajouter
            file.append (path)
        else :
            # sous-répertoire : on appelle à nouveau la fonction
            # pour retourner la liste des fichiers inclus 
            fold.append (path)
            fi,fo = liste_fichier_repertoire (path, filter)
            file.extend (fi)  # on étend la liste des fichiers
            fold.extend (fo)  # on étend la liste des répertoires 
    # fin
    return file,fold
    
folder = r"D:\Dupre\_data\informatique"
filter = "*.tex"
file,fold = liste_fichier_repertoire (folder, filter)

for f in file : print "fichier ", f
for f in fold : print "répertoire ", f

(2)

# coding: latin-1
import os

def liste_fichier_repertoire (folder) :
    file, rep = [], []
    for r, d, f in os.walk (folder) :
        for a in d : rep.append (r + "/" + a)
        for a in f : file.append (r + "/" + a)
    return file, rep
    
folder = r"D:\Dupre\_data\informatique"
file,fold = liste_fichier_repertoire (folder)

for f in file : print "fichier ", f
for f in fold : print "répertoire ", f

(1)

# coding: latin-1
import struct
# on enregistre un entier, un réel et 4 caractères
i = 10
x = 3.1415692
s = "ABCD"

# écriture
file = open ("info.bin", "wb")
file.write ( struct.pack ("i" , i) )
file.write ( struct.pack ("d" , x) )
file.write ( struct.pack ("cccc" , *s) )
file.close ()

# lecture
file = open ("info.bin", "rb")
i = struct.unpack ("i",      file.read (4)) 
x = struct.unpack ("d",      file.read (8)) 
s = struct.unpack ("cccc",   file.read (4)) 
file.close ()

# affichage pour vérifier que les données ont été bien lues
print i  # affiche (10,)
print x  # affiche (3.1415692000000002,)
print s  # affiche ('A', 'B', 'C', 'D')

(2)

# coding: latin-1
import struct
# on enregistre un entier, un réel et n caractères
i = 10
x = 3.1415692
s = "ABCDEDF"

# écriture
file = open ("info.bin", "wb")
file.write ( struct.pack ("i" , i) )
file.write ( struct.pack ("d" , x) )
file.write ( struct.pack ("i" , len(s)) )  # on sauve la dimension de s
file.write ( struct.pack ("c" * len(s) , *s) )
file.close ()

# lecture
file = open ("info.bin", "rb")
i = struct.unpack ("i",      file.read (4)) 
x = struct.unpack ("d",      file.read (8)) 
l = struct.unpack ("i",      file.read (4)) # on récupère la dimension de s
l = l [0]  # l est un tuple, on s'intéresse à son unique élément
s = struct.unpack ("c" * l,  file.read (l)) 
file.close ()

# affichage pour contrôler
print i  # affiche (10,)
print x  # affiche (3.1415692000000002,)
print s  # affiche ('A', 'B', 'C', 'D', 'E', 'D', 'F')

File: chap7_fichiers.tex, line 470


import pickle

dico = {'a': [1, 2.0, 3, "e"], 'b': ('string', 2), 'c': None}
lis  = [1, 2, 3]

f = open ('data.bin', 'wb')
pickle.dump (dico, f)
pickle.dump (lis, f)
f.close()

File: chap7_fichiers.tex, line 487


f = open ('data.bin', 'rb')
dico = pickle.load (f)
lis  = pickle.load (f)
f.close()

(1)

import pickle
import copy

class Test :
    def __init__ (self) :
        self.chaine = "a"
        self.entier = 5
        self.tuple  = { "h":1, 5:"j" }

t = Test ()

f = open('data.bin', 'wb')  # lecture
pickle.dump (t, f)
f.close()

f = open('data.bin', 'rb')  # écriture
t = pickle.load (f)
f.close()

(2)

import pickle
import copy

class Test :
    def __init__ (self) :
        self.x = 5
        self.y = 3
        self.calcule_norme ()   # attribut calculé
    def calcule_norme (self) :
        self.n = (self.x ** 2 + self.y ** 2) ** 0.5
    def __getstate__ (self) :
        """conversion de Test en un dictionnaire"""
        d = copy.copy (self.__dict__)
        del d ["n"]  # attribut calculé, on le sauve pas
        return d
    def __setstate__ (self,dic) :
        """conversion d'un dictionnaire dic en Test"""
        self.__dict__.update (dic)
        self.calcule_norme ()  # attribut calculé

t = Test ()

f = open('data.bin', 'wb')  # lecture
pickle.dump (t, f)
f.close()

f = open('data.bin', 'rb')  # écriture
t = pickle.load (f)
f.close()

File: chap7_fichiers.tex, line 516


# coding: latin-1
import glob
import shutil
def copie_repertoire (rep1, rep2) :
    """copie tous les fichiers d'un répertoire rep1 vers un autre rep2"""
    li = glob.glob (rep1 + "/*.*")   # récupère dans une liste fichiers et 
                                     # répertoires qui respectent le filtre
    for l in li :
        to = l.replace (rep1, rep2)  # nom du fichier copié 
                                     # (on remplace rep1 par rep2)
        shutil.copy (l, to)
copie_repertoire ("c:/original", "c:/backup")

File: chap7_fichiers.tex, line 535


c:\python26\python.exe synchro.py c:/original c:/backup

File: chap7_fichiers.tex, line 552


interpréteur_python programme_python argument1 argument2 ...

lancer un programme \pythons en ligne de commande

# coding: latin-1
import glob
import shutil
def copie_repertoire (rep1, rep2) :
    """copie tous les fichiers d'un répertoire rep1 vers un autre rep2"""
    li = glob.glob (rep1 + "/*.*")
    for l in li :
        to = l.replace (rep1, rep2)  # nom du fichier copié 
                                     # (on remplace rep1 par rep2)
        shutil.copy (l, to)
        
import sys
                      # sys.argv [0] --> nom du programme (ici, synchro.py)
rep1 = sys.argv [1]   # récupération du premier paramètre
rep2 = sys.argv [2]   # récupération du second paramètre
copie_repertoire (rep1, rep2)

File: chap7_fichiers.tex, line 578


c:\python26\python.exe c:\batch\synchro.py 
          "c:\Program Files\source" "c:\Program Files\backup"

File: chap7_fichiers.tex, line 588


import os
os.system ("c:\python26\python.exe c:\batch\synchro.py " \
           "\"c:\Program Files\source\" \"c:\Program Files\backup\"")

lancer un navigateur en ligne de commande

mat = ["Victor Hugo 6".split (), "Marcel Proust 3".split () ]
f = open ("tableau.html", "w")
f.write ("<body><html>\n")
f.write ("<table border=\"1\">\n")
for m in mat :
    f.write ("<tr>")
    for c in m :
        f.write ("<td>" + c + "</td>")
    f.write ("</tr>\n")
f.write ("</table>")
f.close ()

import os
os.system ("\"C:\\Program Files\\Mozilla Firefox\\firefox.exe\" tableau.html")
os.system ("\"C:\\Program Files\\Internet Explorer\\iexplore.exe\"" \
           " d:\\temp\\tableau.html")

File: chap7_fichiers.tex, line 611


s = """date 0 : 14/9/2000     
date 1 : 20/04/1971     date 2 : 14/09/1913     date 3 : 2/3/1978     
date 4 : 1/7/1986     date 5 : 7/3/47     date 6 : 15/10/1914     
date 7 : 08/03/1941     date 8 : 8/1/1980     date 9 : 30/6/1976"""

File: chap7_fichiers.tex, line 621


[0-3]?[0-9]/[0-1]?[0-9]/([0-2][0-9])?[0-9][0-9]

File: chap7_fichiers.tex, line 630


import re
# première étape : construction
expression = re.compile ("([0-3]?[0-9]/[0-1]?[0-9]/([0-2][0-9])?[0-9][0-9])")
# seconde étape  : recherche
res = expression.findall (s)  
print res

File: chap7_fichiers.tex, line 641


[('14/9/2000', '20'), ('20/04/1971', '19'),  ('14/09/1913', '19'), 
 ('2/3/1978', '19'),  ('1/7/1986', '19'),    ('7/3/47', ''),      
 ('15/10/1914', '19'), ('08/03/1941', '19'), ('8/1/1980', '19'),  
 ('30/6/1976', '19')]

File: chap7_fichiers.tex, line 679


s = r"D:\Dupre\_data\informatique\support\vba\image/vbatd1_4.png"
print re.compile ( "[\\\\/]image[\\\\/].*[.]png").search(s) # résultat positif
print re.compile (r"[\\/]image[\\/].*[.]png").search(s)     # même résultat

File: chap7_fichiers.tex, line 701


import re
s = "<h1>mot</h1>"
print re.compile ("(<.*>)") .match (s).groups () # ('<h1>mot</h1>',)
print re.compile ("(<.*?>)").match (s).groups () # ('<h1>',)

File: chap7_fichiers.tex, line 750


expression = re.compile ("([0-3]?[0-9]/[0-1]?[0-9]/([0-2][0-9])?[0-9][0-9])[^\d]")
print expression.search (s).group(1,2) # affiche ('14/9/2000', '20')
c = expression.search (s).span(1)      # affiche (9, 18)
print s [c[0]:c[1]]                    # affiche 14/9/2000

(1)

# coding: latin-1
import mutagen.mp3, mutagen.easyid3, os, re

def infoMP3 (file, tags) :
    """retourne des informations sur un fichier MP3 sous forme de 
    dictionnaire (durée, titre, artiste, ...)"""
    a = mutagen.mp3.MP3(file)
    b = mutagen.easyid3.EasyID3(file)
    info = { "minutes":a.info.length/60, "nom":file }
    for k in tags :
        try : info [k] = str (b [k][0])
        except : continue
    return info
    
def all_files (repertoire, tags, ext = re.compile (".mp3$")) :
    """retourne les informations pour chaque fichier d'un répertoire"""
    all = []
    for r, d, f in os.walk (repertoire) :
        for a in f : 
            if not ext.search (a) : continue
            t = infoMP3 (r + "/" + a, tags)
            if len (t) > 0 : all.append (t)
    return all
    
def heart_notitle_mots (all, avoid,sep,heart) :
    """retourne trois résultats
    - les chansons dont le titre valide l'expression régulière heart
    - les chansons dont le titre valide l'expression régulière avoid
    - le nombre moyen de mots dans le titre d'une chanson"""
    liheart, notitle  = [], []
    nbmot,nbsong      = 0,0
    for a in all :
        if "title" not in a : 
            notitle.append (a)
            continue
        ti = a ["title"].lower ()
        if avoid.match (ti) : 
            notitle.append (a)
            continue
        if heart.search (ti) : liheart.append (a)
        nbsong += 1
        nbmot  += len ([ m for m in sep.split (ti) if len (m) > 0 ])
    return liheart, notitle, float (nbmot)/nbsong

tags  = "title album artist genre tracknumber".split ()
all = all_files (r"D:\musique", tags)

avoid = re.compile ("^(((audio)?track( )?( - )?[0-9]{1,2})|(piste [0-9]{1,2}))$")
sep   = re.compile ("[- ,;!'.?&:]")
heart = re.compile ("((heart)(?!((ache)|(land))))")
liheart, notitle, moymot = heart_notitle_mots (all, avoid, sep, heart)

print "nombre de mots moyen par titre ", moymot
print "somme des durée contenant heart ", sum ( [ s ["minutes"] for s in liheart] )
print "chanson sans titre ", len (notitle)
print "liste des titres "
for s in liheart : print "   ",s ["title"]

File: chap7_fichiers.tex, line 787


import re
date = "05/22/2010"
exp  = "([0-9]{1,2})/([0-9]{1,2})/(((19)|(20))[0-9]{2})"
com  = re.compile (exp)
print com.search (date).groups ()    # ('05', '22', '2010', '20', None, '20')

File: chap7_fichiers.tex, line 795


exp  = "(?P<jj>[0-9]{1,2})/(?P<mm>[0-9]{1,2})/(?P<aa>((19)|(20))[0-9]{2})"
com  = re.compile (exp)
print com.search (date).groupdict () # {'mm': '22', 'aa': '2010', 'jj': '05'}

(2)

# coding: latin-1
"""ce programme détermine toutes les fonctions définies dans 
un programme et jamais appelées"""
import glob, os, re

def trouve_toute_fonction (s, exp, gr, expm = "^$") :
    """ à partir d'une chaîne de caractères correspondant
    à un programme Python, cette fonction retourne 
    une liste de 3-uples, chacun contient :
        - le nom de la fonction
        - (debut,fin) de l'expression dans la chaîne
        - la ligne où elle a été trouvée
       
    Paramètres:
       - s    : chaîne de caractères
       - exp  : chaîne de caractères correspond à l'expression
       - gr   : numéro de groupe correspondant au nom de la fonction
       - expm : expression négative
    """
    exp = re.compile (exp)
    res = []
    pos = 0
    r = exp.search (s, pos)   # première recherche
    while r != None :
        temp = (r.groups () [gr], r.span (gr), r.group (gr))
        x    = re.compile ( expm.replace ("function", temp [0]) )
        if not x.match (temp [2]) :  
            # l'expression négative n'est pas trouvé, on peut ajouter ce résultat
            res.append (temp)
        r    = exp.search (s, r.end (gr) )     # recherche suivante
    return res

def get_function_list_definition (s) :
    """trouve toutes les définitions de fonctions"""
    return trouve_toute_fonction (s, \
              "\ndef[ ]+([a-zA-Z_][a-zA-Z_0-9]*)[ ]*[(].*[)][ ]*[:]", 0)

def get_function_list_call (s) :
    """trouve tous les appels de fonctions"""
    return trouve_toute_fonction (s, \
              "\n.*[=(,[{ .]([a-zA-Z_][a-zA-Z_0-9]*)(?![ ]?:)[ ]*[(].*[)]?", 0, \
              "^\\n[ ]*(class|def)[ ]+function.*$")
                
def detection_fonction_pas_appelee (file) :                
    """retourne les couples de fonctions jamais appelées suivies
    du numéro de la ligne où elles sont définies"""

    f       = open (file, "r")
    li      = f.readlines ()
    f.close ()
    sfile   = "".join (li)
    
    funcdef = get_function_list_definition (sfile)
    funccal = get_function_list_call (sfile)
    f2 = [ p [0] for p in funccal ]
    res = []
    for f in funcdef :
        if f [0] not in f2 : 
            ligne = sfile [:f [1][0]].count ("\n")
            res.append ( (f [0], ligne+2))
    return res
    
def fonction_inutile () :  # ligne 63
    pass

if __name__ == "__main__" :
    file    = "fonction.py"
    print detection_fonction_pas_appelee (file)   
            # affiche [('fonction_inutile', 63)]

File: chap7_fichiers.tex, line 823


import datetime
naissance = datetime.datetime (1975,11,8,10,0,0)
jour = naissance.now () # obtient l'heure et la date actuelle
print jour              # affiche 2010-05-22 11:24:36.312000
age = jour - naissance  # calcule une différence
print age               # affiche 12614 days, 1:25:10.712000

File: chap7_fichiers.tex, line 838


import calendar
c = calendar.Calendar ()
for d in c.itermonthdays2 (1975,8) : print d

File: chap7_fichiers.tex, line 862


# coding: latin-1
st =  "eé"
su = u"eé"  # raccourci pour su = unicode ("eé", "latin-1")
            # ou encore      su = unicode ("eé".decode ("latin-1"))
            
print type (st)                                    # affiche <type 'str'>
print type (su)                                    # affiche <type 'unicode'>
print len (st),        ";", st                     # affiche  2 ; eé
print len (repr (st)), ";", repr (st)              # affiche  7 ; 'e\xe9'
print len (su),        ";", su.encode ("latin-1")  # affiche  2 ; eé
print len (repr (su)), ";", repr (su)              # affiche  8 ; u'e\xe9'

File: chap7_fichiers.tex, line 879


import codecs
f = codecs.open ("essai.txt", "r", "cp1252")  # jeu Windows
s = "".join (f.readlines ())
f.close ()
print type (s)              # affiche <type 'unicode'>
print s.encode ("cp1252")   # pour l'afficher, 
                            # il faut convertir l'unicode en "cp1252"

File: chap7_fichiers.tex, line 923


import sys
import locale
             # retourne le jeu de caractères par défaut
print sys.getdefaultencoding ()    # affiche ascii
             # retourne le jeu de caractères du système d'exploitation
print locale.getdefaultlocale()    # affiche ('fr_FR', 'cp1252')

File: chap8_interface.tex, line 59


zone_texte = Tkinter.Label (text = "zone de texte")

File: chap8_interface.tex, line 63


import Tkinter         # import de Tkinter
root = Tkinter.Tk ()   # création de la fenêtre principale
# ...
obj = Tkinter.Label (text = "zone de texte")
# ...
obj.pack ()            # on ajoute l'objet à la fenêtre principale
root.mainloop ()       # on affiche enfin la fenêtre principal et on attend
                       # les événements (souris, clic, clavier)

File: chap8_interface.tex, line 79


zone_texte = Tkinter.Label (text = "zone de texte")

File: chap8_interface.tex, line 83


zone_texte = Tkinter.Label (text = "premier texte")
# ...
# pour changer de texte
zone_texte.config (text = "second texte")

File: chap8_interface.tex, line 104


zone_texte.config (state = Tkinter.DISABLED)

File: chap8_interface.tex, line 108


zone_texte.config (state = Tkinter.NORMAL)

File: chap8_interface.tex, line 127


bouton = Tkinter.Button (text = "zone de texte")

File: chap8_interface.tex, line 131


bouton = Tkinter.Button (text = "premier texte")
# ...
# pour changer de texte
bouton.config (text = "second texte")

File: chap8_interface.tex, line 153


bouton.config (state = Tkinter.DISABLED)

File: chap8_interface.tex, line 157


bouton.config (state = Tkinter.NORMAL)

File: chap8_interface.tex, line 167


b = Tkinter Button ()
im = Tkinter.PhotoImage (file = "chameau.gif")
b.config (image = im)

File: chap8_interface.tex, line 192


saisie = Tkinter.Entry ()

File: chap8_interface.tex, line 196


# le premier paramètre est la position
# où insérer le texte (second paramètre)
saisie.insert (pos, "contenu")

File: chap8_interface.tex, line 202


contenu = saisie.get ()

File: chap8_interface.tex, line 206


# supprime le texte entre les positions pos1, pos2
saisie.delete (pos1, pos2)

File: chap8_interface.tex, line 211


saisie.delete (0, len (saisie.get ()))

File: chap8_interface.tex, line 234


saisie = Tkinter.Text ()

File: chap8_interface.tex, line 238


# le premier paramètre est la position
# où insérer le texte (second paramètre)
pos = "0.0"
saisie.insert (pos, "première ligne\nseconde ligne")

File: chap8_interface.tex, line 245


# retourne le texte entre deux positions
pos1 = "0.0"
pos2 = "end"  # ou Tkinter.END
contenu = saisie.get (pos1, pos2)

File: chap8_interface.tex, line 252


# supprime le texte entre les positions pos1, pos2
saisie.delete (pos1, pos2)

File: chap8_interface.tex, line 257


saisie.delete ("0.0", "end")
# on peut aussi utiliser 
# saisie.delete ("0.0", Tkinter.END)

File: chap8_interface.tex, line 267


# modifie les dimensions de la zone
# width <--> largeur
# height <--> hauteur en lignes
saisie.config (width = 10, height = 5)

File: chap8_interface.tex, line 306


# crée un objet entier pour récupérer la valeur de la case à cocher,
# 0 pour non cochée, 1 pour cochée
v    = Tkinter.IntVar ()
case = Tkinter.Checkbutton (variable = v)

File: chap8_interface.tex, line 315


v.get ()  # égal à 1 si la case est cochée, 0 sinon

File: chap8_interface.tex, line 321


case.select ()      # pour cocher
case.deselect ()    # pour décocher

File: chap8_interface.tex, line 327


case.config (text = "case à cocher")

File: chap8_interface.tex, line 362


# crée un objet entier partagé pour récupérer le numéro du bouton radio activé
v     = Tkinter.IntVar ()
case1 = Tkinter.Radiobutton (variable = v, value = 10)
case2 = Tkinter.Radiobutton (variable = v, value = 20)
case3 = Tkinter.Radiobutton (variable = v, value = 30)

File: chap8_interface.tex, line 370


v.get ()  #  retourne le numéro du bouton radio coché (ici, 10, 20 ou 30)

File: chap8_interface.tex, line 374


v.set (numero)  # numéro du bouton radio à cocher
                # pour cet exemple, 10, 20 ou 30

File: chap8_interface.tex, line 379


case1.config (text = "premier bouton")
case2.config (text = "second bouton")
case3.config (text = "troisième bouton")

File: chap8_interface.tex, line 417


li  = Tkinter.Listbox ()

File: chap8_interface.tex, line 423


# modifie les dimensions de la liste
# width <--> largeur
# height <--> hauteur en lignes
li.config (width = 10, height = 5)

File: chap8_interface.tex, line 432


pos = 0   # un entier, "end" ou Tkinter.END pour insérer ce mot à la fin
li.insert (pos, "première ligne")

File: chap8_interface.tex, line 439


pos1 = 0    # un entier
pos2 = None # un entier, "end" ou Tkinter.END pour supprimer tous les éléments
            # de pos1 jusqu'au dernier
li.delete (pos1, pos2 = None)

File: chap8_interface.tex, line 448


pos1 = 0
li.select_set (pos1, pos2 = None)
# sélectionne tous les éléments entre les indices pos1 et 
# pos2 inclus ou seulement celui d'indice pos1 si pos2 == None

File: chap8_interface.tex, line 457


pos1 = 0
li.select_clear (pos1, pos2 = None)
# retire la sélection de tous les éléments entre les indices 
# pos1 et pos2 inclus ou seulement celui d'indice pos1 si pos2 == None

File: chap8_interface.tex, line 466


sel = li.curselection ()

File: chap8_interface.tex, line 472


for i in range (0,li.size ()) :
    print li.get (i)

File: chap8_interface.tex, line 492


frame      = Tkinter.Frame (parent)
scrollbar  = Tkinter.Scrollbar (frame)
li         = Tkinter.Listbox (frame, width = 88, height = 6, \
                              yscrollcommand = scrollbar.set)
scrollbar.config (command = li.yview)
li.pack (side = Tkinter.LEFT)
scrollbar.pack (side = Tkinter.RIGHT, fill = Tkinter.Y)

File: chap8_interface.tex, line 508


li = Tkinter.Listbox (frame, width = 88, height = 6, exportselection=0)

liste avec barre de défilement

# coding: latin-1
import tkinter as Tk
root = Tk.Tk ()

o = Tk.ScrolledListBox (root)
for k in range (0,100) : o.listbox.insert (Tk.END, "ligne " + str (k))
o.pack ()

def print_file () :                     # voir chapitre sur les événements
    print (o.listbox.selection_get ())  # idem 

b = Tk.Button (root, text = "print")    
b.config (command = print_file)         # idem 
b.pack ()

root.mainloop ()                        # idem 

liste \codesindex{ComboBox

# coding: latin-1
import tkinter as Tk
root = Tk.Tk ()

o = Tk.ComboBox (root, label = "label")
o.insert (Tk.END, "ligne 1")
o.insert (Tk.END, "ligne 2")
o.insert (Tk.END, "ligne 3")
o.insert (Tk.END, "ligne 4")
o.pack ()

def print_file () :                     # voir le chapitre sur les événéments
    print (o.cget ("value"))            # idem

b = Tk.Button (root, text = "print")
b.config (command = print_file)         # idem
b.pack ()

root.mainloop ()                        # idem

File: chap8_interface.tex, line 552


ca  = Tkinter.Canvas ()

File: chap8_interface.tex, line 556


# modifie les dimensions du canevas
# width <--> largeur en pixels
# height <--> hauteur en pixels
ca.config (width = 10, height = 5)

File: chap8_interface.tex, line 563


  # dessine deux lignes du point 10,10 au point 40,100 et au point 200,60
  # de couleur bleue, d'épaisseur 2
ca.create_line (10,10,40,100, 200,60, fill = "blue", width = 2)
  # dessine une courbe du point 10,10 au point 200,60
  # de couleur rouge, d'épaisseur 2, c'est une courbe de Bézier
  # pour laquelle le point  40,100 sert d'assise
ca.create_line (10,10, 40,100, 200,60, smooth=1, fill = "red", width = 2)
  # dessine un rectangle plein de couleur jaune, de bord noir et d'épaisseur 2
ca.create_rectangle (300,100,60,120, fill = "gray", width = 2)
  # écrit du texte de couleur noire au point 80,80 et avec la police arial
ca.create_text (80,80, text = "écrire", fill = "black", font = "arial")

File: chap8_interface.tex, line 592


widget.config (state = Tkinter.DISABLED) # grisé
widget.config (state = Tkinter.NORMAL)   # aspect normal

File: chap8_interface.tex, line 598


l = Tkinter.Label (text = "légende")

File: chap8_interface.tex, line 604


l = Tkinter.Label ()
l.config (text = "légende")

File: chap8_interface.tex, line 611


Help on method configure in module Tkinter:

configure(self, cnf=None, **kw) unbound Tkinter.Label method
    Configure resources of a widget.
    
    The values for resources are specified as keyword
    arguments. To get an overview about
    the allowed keyword arguments call the method keys.

File: chap8_interface.tex, line 624


__init__(self, master=None, cnf={}, **kw) unbound Tkinter.Label method
    Construct a label widget with the parent MASTER.
    
    STANDARD OPTIONS
    
        activebackground, activeforeground, anchor,
        background, bitmap, borderwidth, cursor,
        disabledforeground, font, foreground,
        highlightbackground, highlightcolor,
        highlightthickness, image, justify,
        padx, pady, relief, takefocus, text,
        textvariable, underline, wraplength
    
    WIDGET-SPECIFIC OPTIONS
    
        height, state, width

File: chap8_interface.tex, line 664


l = Tkinter.Label (text = "première ligne")
l.pack ()
s = Tkinter.Entry ()
s.pack ()
e = Tkinter.Label (text = "seconde ligne")
e.pack ()

File: chap8_interface.tex, line 686


l = Tkinter.Label (text = "première ligne")
l.pack (side = Tkinter.RIGHT)
s = Tkinter.Entry ()
s.pack (side = Tkinter.RIGHT)
e = Tkinter.Label (text = "seconde ligne")
e.pack (side = Tkinter.RIGHT)

File: chap8_interface.tex, line 711


s.pack_forget ()  # disparition
s.pack ()         # insertion à un autre endroit

File: chap8_interface.tex, line 723


l = Tkinter.Label (text = "première ligne")
l.grid (column = 0, row = 0)
s = Tkinter.Entry ()
s.grid (column = 0, row = 1)
e = Tkinter.Label (text = "seconde ligne")
e.grid (column = 1, row = 0)

File: chap8_interface.tex, line 757


s.grid_forget ()  # disparition

File: chap8_interface.tex, line 769


l = Tkinter.Label (text = "première ligne")
l.place (x=10,y=50)

File: chap8_interface.tex, line 784


f = Tkinter.Frame ()

File: chap8_interface.tex, line 790


l = Tkinter.Label (f, text = "première ligne")

File: chap8_interface.tex, line 796


f = Tkinter.Frame ()
l = Tkinter.Label (f, text = "première ligne")
l.pack ()                     # positionne l à l'intérieur de f
s = Tkinter.Entry (f)
s.pack ()                     # positionne s à l'intérieur de f
f.pack (side = Tkinter.LEFT)  # positionne f à l'intérieur   
                              #   de la fenêtre principale
e = Tkinter.Label (text = "seconde ligne")
e.pack_forget ()
e.pack (side = Tkinter.RIGHT) # positionne e à l'intérieur 
                              #   de la fenêtre principale

File: chap8_interface.tex, line 832


root = Tkinter.Tk ()
#  ici, on trouve le code qui définit les objets
#  et leur positionnement
root.mainloop ()

File: chap8_interface.tex, line 856


e = Tkinter.Entry ()
e.pack ()
e.focus_set ()

Tkinter, bouton

# coding: latin-1
# la première ligne autorise les accents
import Tkinter
root = Tkinter.Tk ()
b = Tkinter.Button (text = "fonction change_legende")
b.pack ()

def change_legende () :
    global b
    b.config (text = "nouvelle légende")

b.config (command = change_legende)
root.mainloop ()

File: chap8_interface.tex, line 951



w.bind (ev, fonction)

Tkinter, fonction \codesindex{bind

import Tkinter
root = Tkinter.Tk ()
b = Tkinter.Button (text = "appuyer sur une touche")
b.pack ()

def affiche_touche_pressee (evt) :
    print "--------------------------- touche pressee"
    print "evt.char = ", evt.char
    print "evt.keysym = ", evt.keysym
    print "evt.num = ", evt.num
    print "evt.x,evt.y = ", evt.x, ",", evt.y
    print "evt.x_root,evt.y_root = ", evt.x_root, ",", evt.y_root
    print "evt.widget = ", evt.widget
    
b.bind ("<Key>", affiche_touche_pressee)
b.bind ("<Button-1>", affiche_touche_pressee)
b.bind ("<Motion>", affiche_touche_pressee)
b.focus_set ()

root.mainloop ()

File: chap8_interface.tex, line 1020


evt.char =  ??
evt.keysym =  ??
evt.num =  1
evt.x,evt.y =  105 , 13
evt.x_root,evt.y_root = 
               292 , 239
evt.widget =  .9261224

File: chap8_interface.tex, line 1032


evt.char =  
evt.keysym =  Return
evt.num =  ??
evt.x,evt.y =  105 , 13
evt.x_root,evt.y_root = 
               292 , 239
evt.widget =  .9261224

File: chap8_interface.tex, line 1061


b.bind ("<button-1>", affiche_touche_pressee)

File: chap8_interface.tex, line 1067


Traceback (most recent call last):
  File "exemple_bind.py", line 17, in ?
    b.bind ("<button-1>", affiche_touche_pressee)
  File "c:\python26\lib\lib-tk\Tkinter.py", line 933, in bind
    return self._bind(('bind', self._w), sequence, func, add)
  File "c:\python26\lib\lib-tk\Tkinter.py", line 888, in _bind
    self.tk.call(what + (sequence, cmd))
_tkinter.TclError: bad event type or keysym "button"

File: chap8_interface.tex, line 1083


b.bind_all ("<Button-1>", affiche_touche_pressee)

File: chap8_interface.tex, line 1097



w.unbind (ev)
w.unbind_all (ev)

File: chap8_interface.tex, line 1132


m = Tkinter.Menu ()

File: chap8_interface.tex, line 1136


root.config (menu = m)

File: chap8_interface.tex, line 1140


mainmenu  = Tkinter.Menu ()
msousmenu = Tkinter.Menu ()
mainmenu.add_cascade (label = "sous-menu 1", menu = msousmenu)

File: chap8_interface.tex, line 1146


def fonction1 () :
    ....
m = Tkinter.Menu ()
mainmenu.add_command (label = "fonction 1", command = fonction1)

Tkinter, menu

import tkinter as Tkinter
root = Tkinter.Tk ()

e = Tkinter.Text (width = 50, height = 10)
e.pack ()

m = Tkinter.Menu ()

sm1 = Tkinter.Menu ()
sm2 = Tkinter.Menu ()

m.add_cascade (label = "sous-menu 1", menu = sm1)
m.add_cascade (label = "sous-menu 2", menu = sm2)

nb = 0

def affiche () : print ("fonction affiche")
def calcul () : print ("fonction calcul ", 3 * 4)
def ajoute_bouton () :
    global nb
    nb += 1
    b = Tkinter.Button (text = "bouton " + str (nb))
    b.pack ()

sm1.add_command (label = "affiche",       command = affiche)
sm1.add_command (label = "calcul",        command = calcul)
sm2.add_command (label = "ajoute_bouton", command = ajoute_bouton)
sm2.add_command (label = "fin",           command = root.destroy)

root.config (menu = m, width = 200)
root.title ("essai de menu")
#help (Tkinter.Tk)
root.mainloop ()

File: chap8_interface.tex, line 1169


m = Tkinter.Menu ()
m.add_command (...)
m.delete (1, 2) # supprime le second intitulé
                # supprime les intitulés compris entre 1 et 2 exclu

File: chap8_interface.tex, line 1180


import Tkinter
root = Tkinter.Tk ()
Tkinter.Button (text = "fin", command = root.destroy).pack ()
root.mainloop ()

File: chap8_interface.tex, line 1213


import Tkinter
win = Tkinter.Toplevel ()
win.mainloop ()

File: chap8_interface.tex, line 1221


# zone_texte appartient à la fenêtre principale
zone_texte = Tkinter.Label (text = "premier texte")

File: chap8_interface.tex, line 1226


# zone_texte appartient à la fenêtre top
top = Tkinter.Toplevel ()
zone_texte = Tkinter.Label (top, text = "premier texte")

plusieurs fenêtre \codesindex{Toplevel

# coding: latin-1
import Tkinter

class nouvelle_fenetre :
    resultat = []
    def top (self) :
        sec = Tkinter.Toplevel ()
        Tkinter.Label (sec, text="entrer quelque chose").pack ()
        saisie = Tkinter.Entry (sec)
        saisie.pack()
        Tkinter.Button (sec, text = "valider", command = sec.quit).pack ()
        sec.mainloop ()
        nouvelle_fenetre.resultat.append ( saisie.get () )
        sec.destroy ()

root = Tkinter.Tk() #fenetre principale
a = Tkinter.Button (text    = "fenêtre Toplevel", 
                    command = nouvelle_fenetre ().top)
a.pack()
root.mainloop()

for a in nouvelle_fenetre.resultat :
    print "contenu ", a

sélection d'un fichier

import tkinter.tix as Tk
root = Tk.Tk ()

def command_print () : print( box.cget("value"))

box = Tk.FileSelectBox (root)
box.config (directory="c:\\")
box.pack ()
Tk.Button (root, text = "print", command = command_print).pack ()

root.mainloop ()

Tkinter, compte à rebours

import Tkinter
root = Tkinter.Tk ()
l = Tkinter.Label (text = "0 secondes")
l.pack ()
sec = 0
id = None

def change_legende() :
    global l
    global sec
    global id
    sec += 1
    l.config (text = "%d secondes" % sec)
    id = l.after (1000, change_legende)

l.after (1000, change_legende)

root.mainloop ()

File: chap8_interface.tex, line 1294


l.after_cancel (id)

\codesindex{Listbox

# coding: latin-1
import Tkinter

class MaListbox (Tkinter.Listbox) :
    def __init__ (self, master = None, cnf={}, **kw) :
        Tkinter.Listbox.__init__ (self, master, cnf, **kw)  
        self.bind ("<Motion>", self.mouvement)
        self.pos = None  # mémoire l'ancienne position du curseur
    def mouvement (self, ev) :
        pos = self.nearest (ev.y)  # nouvelle position du curseur
        if pos < 0 or pos >= self.size () : return
        if self.pos != pos :
            if self.pos != None : self.itemconfigure(self.pos, bg='')
            self.itemconfigure (pos, bg='gray')
            self.pos = pos

root = Tkinter.Tk ()
b = MaListbox ()
b.insert ("end", "ligne 1")
b.insert ("end", "ligne 2")
b.insert ("end", "ligne 3")
b.pack ()
b.focus_set ()
root.mainloop ()

Tkinter avec des classes

# coding: latin-1
import Tkinter as Tk

class MaFenetre :
    def __init__ (self, win) :
        self.win = win
        self.creation ()
        
    def creation (self) :
        b1 = Tk.Button (self.win, text="bouton 1", command=self.commande_bouton1)
        b2 = Tk.Button (self.win, text="bouton 2", command=self.commande_bouton2)
        b3 = Tk.Button (self.win, text="disparition", command=self.disparition)
        b1.grid (row=0, column=0)
        b2.grid (row=0, column=1)
        b3.grid (row=0, column=2)
        self.lab = Tk.Label (self.win, text = "-")
        
    def commande_bouton1 (self) :
        # on déplace l'objet lab de type Label
        self.lab.configure (text = "bouton 1 appuyé")
        self.lab.grid (row = 1, column = 0)
        
    def commande_bouton2 (self) :
        # on déplace l'objet lab de type Label
        self.lab.configure (text = "bouton 2 appuyé")
        self.lab.grid (row = 1, column = 1)
        
    def disparition (self) :
        # on fait disparaître l'objet lab de type Label
        self.lab.grid_forget ()
    
if __name__ == "__main__" :
    root = Tk.Tk ()
    f = MaFenetre (root)
    root.mainloop ()

File: chap8_interface.tex, line 1332


root = Tk.Tk ()
f = Tk.Frame ()
f.pack ()
MaFenetre (f)      # première instance
g = Tk.Frame ()
g.pack ()
MaFenetre (g)      # seconde instance
root.mainloop ()

Tkinter, séquence d'événements

# coding: latin-1
import Tkinter as Tk

class MaFenetreSeq :
    def __init__ (self, win) :
        self.win = win
        self.creation ()
        self.sequence = []
        
    def creation (self) :
        b1 = Tk.Button (self.win, text="bouton 1", command=self.commande_bouton1)
        b2 = Tk.Button (self.win, text="bouton 2", command=self.commande_bouton2)
        b3 = Tk.Button (self.win, text="remise à zéro", command=self.zero)
        b1.grid (row=0, column=0)
        b2.grid (row=0, column=1)
        b3.grid (row=0, column=2)
        self.lab = Tk.Label (self.win, text = "-")
        
    def commande_bouton1 (self) :
        # ajoute 1 à la liste self.sequence
        self.sequence.append (1)
        self.controle ()
        
    def commande_bouton2 (self) :
        # ajoute 2 à la liste self.sequence
        self.sequence.append (2)
        self.controle ()
        
    def zero (self) :
        # on vide la liste self.sequence
        self.sequence = []
        self.lab.grid_forget ()
        
    def controle (self) :
        # on compare la liste sequence à [1,2,1] et [2,2,1,1]
        # dans ce cas, on fait apparaître l'objet lab
        l = len (self.sequence)
        if l >= 3 and self.sequence [l-3:] == [1,2,1] :
            self.lab.configure (text = "séquence 1 2 1")
            self.lab.grid (row = 1, column = 0)
        elif l >= 4 and self.sequence [l-4:] == [2,2,1,1] :
            self.lab.configure (text = "séquence 2 2 1 1")
            self.lab.grid (row = 1, column = 1)
    
if __name__ == "__main__" :
    root = Tk.Tk ()
    f = MaFenetreSeq (root)
    root.mainloop ()

utilisation de messages personnalisés

# coding: latin-1
import Tkinter
def affiche_touche_pressee () : root.event_generate ("<<perso>>", rooty = -5)
def perso (evt) : print "perso", evt.y_root
root = Tkinter.Tk ()
b = Tkinter.Button (text = "clic", \
                    command = affiche_touche_pressee)
b.pack ()
root.bind ("<<perso>>", perso)  # on intercepte un événement personnalisé
root.mainloop ()

premier thread

# coding: cp1252
import threading, time

class MonThread (threading.Thread) :
    def __init__ (self, jusqua) :      # jusqua = donnée supplémentaire
        threading.Thread.__init__(self)# ne pas oublier cette ligne 
                                       # (appel au constructeur de la classe mère)
        self.jusqua = jusqua           # donnée supplémentaire ajoutée à la classe
        
    def run (self) :
        for i in range (0, self.jusqua) :
            print "thread ", i
            time.sleep (0.1)    # attend 100 millisecondes sans rien faire
                                # facilite la lecture de l'affichage
        
m = MonThread (1000)        # crée le thread
m.start ()                  # démarre le thread, 
                            # l'instruction est exécutée en quelques millisecondes
                            # quelque soit la durée du thread

for i in range (0,1000) :
    print "programme ", i
    time.sleep (0.1)            # attend 100 millisecondes sans rien faire
                                # facilite la lecture de l'affichage

File: chap9_thread.tex, line 59


programme  0
thread  0
thread  1
programme  1
thread  2
programme  2
programme  3
thread  3
programme  4
thread  4
...

deux threads secondaires

# coding: cp1252
import threading, time

class MonThread (threading.Thread) :
    def __init__ (self, jusqua, s) :
        threading.Thread.__init__ (self)
        self.jusqua = jusqua
        self.s = s
        
    def run (self) :
        for i in range (0, self.jusqua) :
            print "thread ", self.s, " : ", i
            time.sleep (0.1)
        
m = MonThread (1000, "A")
m.start ()

m2 = MonThread (1000, "B")  # crée un second thread
m2.start ()                 # démarre le thread, 

for i in range (0,1000) :
    print "programme ", i
    time.sleep (0.1)

File: chap9_thread.tex, line 82


thread  A  :  0
programme  0
thread  B  :  0
thread  A  :  1
thread  B  :  1
programme  1
thread  B  :  2
thread  A  :  2
...

(1)

# coding: latin-1
import threading, time

class MonThread (threading.Thread) :
    def __init__ (self, jusqua) :
        threading.Thread.__init__ (self)
        self.jusqua = jusqua
        self.etat = False       # l'état du thread est soit False (à l'arrêt)
                                # soit True (en marche)
        
    def run (self) :
        self.etat = True                        # on passe en mode marche
        for i in range (0, self.jusqua) :
            print "thread itération ", i
            time.sleep (0.1)
        self.etat = False                       # on revient en mode arrêt
        
m = MonThread (10)          # crée un thread
m.start ()                  # démarre le thread, 

print "début"

while m.etat == False :
    # on attend que le thread démarre
    time.sleep (0.1)  # voir remarque ci-dessous
    
while m.etat == True :
    # on attend que le thread s'arrête
    # il faut introduire l'instruction time.sleep pour temporiser, il n'est pas 
    # nécessaire de vérifier sans cesse que le thread est toujours en marche
    # il suffit de le vérifier tous les 100 millisecondes
    # dans le cas contraire, la machine passe son temps à vérifier au lieu
    # de se consacrer à l'exécution du thread
    time.sleep (0.1)
    
print "fin"

(2)

# coding: latin-1
import threading, time

class MonThread (threading.Thread) :
    def __init__ (self, jusqua, event) :    # event = objet Event
        threading.Thread.__init__ (self)    #       = donnée supplémentaire
        self.jusqua = jusqua                
        self.event  = event                 # on garde un accès à l'objet Event
        
    def run (self) :
        for i in range (0, self.jusqua) :
            print "thread itération ", i
            time.sleep (0.1)
        self.event.set ()                   # on indique qu'on a fini : 
                                            # on active l'object self.event
print "début"
        
event = threading.Event ()       # on crée un objet de type Event
event.clear ()                   # on désactive l'ojet Event
m = MonThread (10, event)        # crée un thread
m.start ()                       # démarre le thread, 
event.wait ()                    # on attend jusqu'à ce que l'objet soit activé
                                 # event.wait (0.1) : n'attend qu'un
print "fin"                      #          seulement 1 dizième de seconde

File: chap9_thread.tex, line 136


m.start ()
while not event.isSet ():
    print "j'attends"
    event.wait (0.1)
print "fin"

partager des données

# coding: latin-1
import threading, time

message = ""
verrou  = threading.Lock ()

def ajoute (c) :
    global message     # message et verrou sont des variables gloables
    global verrou      # pour ne pas qu'elle disparaisse dès la fin de la fonction
    verrou.acquire ()  # on protège ce qui suit  (*)
    
    s = message + c    # instructions jamais exécutée simultanément par 2 threads
    time.sleep (0.001) # time.sleep : pour exagérer le défaut de synchronisation
    message = s        # si verrou n'est pas utilisé
    
    verrou.release ()  # on quitte la section protégée  (*)

class MonThread (threading.Thread) :
    def __init__ (self, jusqua, event, s) :
        threading.Thread.__init__ (self)
        self.jusqua = jusqua 
        self.s      = s
        self.event  = event
        
    def run (self) :
        for i in range (0, self.jusqua) :
            ajoute (self.s)
            time.sleep (0.003)
        self.event.set ()
        
print "début"

# synchronisation attente
e1 = threading.Event ()
e2 = threading.Event ()
e1.clear ()
e2.clear ()

m1 = MonThread (10, e1, "1")     # crée un thread
m1.start ()                      # démarre le thread, 
m2 = MonThread (10, e2, "2")     # crée un second thread
m2.start ()                      # démarre le second thread, 

e1.wait ()
e2.wait ()

print "longueur ", len(message) # affiche 20
print "message = ", message     # affiche quelque chose comme 12212112211212121221

thread et interface graphique

# coding: latin-1
import threading, time, random, copy

# définition du thread
class MonThread (threading.Thread) :
    def __init__ (self, win, res) :
        threading.Thread.__init__ (self)
        self.win = win  # on mémorise une référence sur la fenêtre
        self.res = res
        
    def run (self) :
        for i in range (0, 10) :
            print "thread ", i
            time.sleep (0.1)
            
          # afin que le thread retourne un résultat
          # self.res désigne thread_resultat qui reçoit un nombre de plus
        h = random.randint (0,100)
        self.res.append (h)    
        
          # on lance un événement <<thread_fini>> à la fenêtre principale 
          # pour lui dire que le thread est fini, l'événement est ensuite 
          # géré par la boucle principale de messages
          # on peut transmettre également le résultat lors de l'envoi du message
          # en utilisant un attribut de la classe Event pour son propre compte
        self.win.event_generate ("<<thread_fini>>", x = h)
    
thread_resultat = []

def lance_thread () :
    global thread_resultat
      # fonction appelée lors de la pression du bouton
      # on change la légnde de la zone de texte
    text .config (text = "thread démarré")
    text2.config (text = "thread démarré")
      # on désactive le bouton pour éviter de lancer deux threads en même temps
    bouton.config (state = TK.DISABLED)
      # on lance le thread
    m = MonThread (root, thread_resultat)
    m.start ()
    
def thread_fini_fonction (e) :
    global thread_resultat
      # fonction appelée lorsque le thread est fini
    print "la fenêtre sait que le thread est fini"
      # on change la légende de la zone de texte
    text .config (text = "thread fini + résultat " + str (thread_resultat))
    text2.config (text = "thread fini + résultat (e.x) " + str (e.x))
      # on réactive le bouton de façon à pouvoir lancer un autre thread
    bouton.config (state = TK.NORMAL)

import Tkinter as TK

# on crée la fenêtre
root   = TK.Tk ()
bouton = TK.Button (root, text = "thread départ", command = lance_thread)
text   = TK.Label (root, text = "rien")
text2  = TK.Label (root, text = "rien")
bouton.pack ()
text.pack ()
text2.pack ()

# on associe une fonction à un événement <<thread_fini>> propre au programme
root.bind ("<<thread_fini>>", thread_fini_fonction)

# on active la boucle principale de message
root.mainloop ()

joueurs asynchrones

# coding: latin-1
import threading, time, Queue, random

class Joueur (threading.Thread) :
    
    # initialisation
    def __init__ (self, nom, e, nb = 1000, temps = 0.1) :
        threading.Thread.__init__(self)
        self.nb    = nb
        self.queue = Queue.Queue ()
        self.nom   = nom
        self.event = e
        self.temps = temps  # temps de réflexion
    def Joueur (self, autre_joueur) : self.autre = autre_joueur
        
    # méthodes : l'adversaire m'envoie un message
    def Joue    (self, nombre) : self.queue.put_nowait ( ("essai", nombre) )
    def Dessus  (self, nombre) : self.queue.put_nowait ( ("dessus", nombre) )
    def Dessous (self, nombre) : self.queue.put_nowait ( ("dessous", nombre) )
    def Gagne   (self, nombre) : 
        while not self.queue.empty () :
            try :self.queue.get ()
            except : pass
        self.queue.put ( ("gagne", nombre) )
              
    # je joue
    def run (self) :
        x = random.randint (0,self.nb)
        print self.nom, " : je joue (", x, ")"
        i = 0
        a = 0
        b = self.nb
        while True :
            time.sleep (self.temps)
            
            try : 
                m,n = self.queue.get_nowait ()       # désynchronisé
                #m,n = self.queue.get (timeout = 0.5)# l'un après l'autre
            except Queue.Empty : m,n = None,None
                
            # traitement du message --> réponse à l'adversaire
            if m == "essai" :
                if n == x : 
                    self.autre.Gagne (n)
                    print self.nom, " : j'ai perdu après ", i, " essais"
                    break
                elif n < x : self.autre.Dessus  (n)
                else       : self.autre.Dessous (n)
            elif m == "dessus" :  
                a = max (a, n+1)
                continue  # assure l'équité en mode l'un après l'autre
            elif m == "dessous" : 
                b = min (b, n-1)
                continue  # assure l'équité en mode l'un après l'autre
            elif m == "gagne" :
                print self.nom, " : j'ai gagné en ", i, " essais, solution ", n
                break

            # on fait une tentative
            if a == b : n = a
            else : n = random.randint (a,b)
            self.autre.Joue (n)
            i += 1
            print self.nom, " : je tente ", n, " écart ", b-a, \
                  " à traiter ", self.queue.qsize ()

        # fini
        print self.nom, " : j'arrête"
        self.event.set ()
        
# on crée des verrous pour attendre la fin de la partie        
e1 = threading.Event ()
e2 = threading.Event ()
e1.clear ()
e2.clear ()

# création des joueurs
A = Joueur ("A", e1, 1000, temps = 0.1)
B = Joueur ("B", e2, 1000, temps = 0.3)

# chaque joueur sait qui est l'autre
A.Joueur (B)
B.Joueur (A)

# le jeu commence
A.start ()
B.start ()

# on attend la fin de la partie
e1.wait ()
e2.wait ()

File: chap9_thread.tex, line 274


A  : je joue ( 8 )
B  : je joue ( 569 )
A  : je tente  42  écart  1000  à traiter  0
A  : je tente  791  écart  1000  à traiter  0
...
A  : je tente  528  écart  62  à traiter  0
B  : je tente  20  écart  43  à traiter  57
A  : je tente  508  écart  62  à traiter  0
A  : je tente  548  écart  62  à traiter  0
B  : je tente  8  écart  43  à traiter  59
A  : j'ai perdu après  67  essais
A  : j'arrête
B  : j'ai gagné en  23  essais, solution  8
B  : j'arrête

File: montant_num.tex, line 35


import string
s = "dix-neuf"

l = s.replace ("-", " ")
l = string.replace ("-", " ")

File: montant_num_cor.tex, line 10


# coding: latin-1
def lire_separation(s):
    """divise un nombre littéral en mots"""
    s = s.replace ("-", " ")     # on remplace les tirets par des espaces
                                 # pour découper en mots même
                                 # les mots composés
    return s.split ()

File: montant_num_cor.tex, line 24


import re
def lire_separation(s):
    """divise un nombre littéral en mots avec les expressions régulières"""
    return re.compile ("[- ]").split (s)

File: montant_num_cor.tex, line 35


def valeur_mot (s) :
    """convertit numériquement les nombres inclus entre 0 et 16 inclus,
    20, 30, 40, 50, 60, s est une chaîne de caractères, le résultat est entier"""
    if   s == "zéro"      : return 0
    elif s == "un"        : return 1
    elif s == "deux"      : return 2
    elif s == "trois"     : return 3
    elif s == "quatre"    : return 4
    elif s == "cinq"      : return 5
    elif s == "six"       : return 6
    elif s == "sept"      : return 7
    elif s == "huit"      : return 8
    elif s == "neuf"      : return 9
    elif s == "dix"       : return 10
    elif s == "onze"      : return 11
    elif s == "douze"     : return 12
    elif s == "treize"    : return 13
    elif s == "quatorze"  : return 14
    elif s == "quinze"    : return 15
    elif s == "seize"     : return 16
    elif s == "vingt"     : return 20
    elif s == "trente"    : return 30
    elif s == "quarante"  : return 40
    elif s == "cinquante" : return 50
    elif s == "soixante"  : return 60
    else                  : return 0      # ce cas ne doit normalement pas 
                                          # se produire

File: montant_num_cor.tex, line 69


def valeur_mot (s) :
    dico = {'cinquante': 50, 'quarante': 40, 'onze': 11, 'huit': 8, 'six': 6, \
            'quinze': 15, 'trente': 30, 'douze': 12, 'cinq': 5, 'deux': 2, \
            'quatorze': 14, 'neuf': 9, 'soixante': 60, 'quatre': 4, \
            'zéro': 0, 'treize': 13, 'trois': 3, 'seize': 16, \
            'vingt': 20, 'un': 1, 'dix': 10, 'sept': 7}
    if s not in dico : return 0   # cas imprévu, on peut résumer ces deux lignes
    else : return dico [s]        # par return dico.get (s, 0)

File: montant_num_cor.tex, line 85


def lire_dizaine_liste(s):
    """convertit une liste de chaînes de caractères dont
    juxtaposition forme un nombre littéral compris entre 0 et 99"""
    r       = 0         # contient le résultat final
    dizaine = False     # a-t-on terminé le traitement des dizaines ?
    for mot in s:
        n = lire_unite (mot)
        if n == 20 :
            if not dizaine and r > 0 and r != 60 :
                r       *= n     # cas 80
                dizaine  = True
            else : r += n
        else : r += n
    return r

File: montant_num_cor.tex, line 106


def lire_dizaine(s):
    li = lire_separation (s)
    return lire_dizaine_liste (li)

File: montant_num_cor.tex, line 116


def ecrit_unite (x):
    """convertit un nombre compris inclus entre 0 et 16 inclus,
    20, 30, 40, 50, 60 en une chaîne de caractères"""
    if   x == 0: return "zéro"
    elif x == 1: return "un"
    elif x == 2: return "deux"
    elif x == 3: return "trois"
    elif x == 4: return "quatre"
    elif x == 5: return "cinq"
    elif x == 6: return "six"
    elif x == 7: return "sept"
    elif x == 8: return "huit"
    elif x == 9: return "neuf"
    elif x == 10: return "dix"
    elif x == 11: return "onze"
    elif x == 12: return "douze"
    elif x == 13: return "treize"
    elif x == 14: return "quatorze"
    elif x == 15: return "quinze"
    elif x == 16: return "seize"
    elif x == 20: return "vingt"
    elif x == 30: return "trente"
    elif x == 40: return "quarante"
    elif x == 50: return "cinquante"
    elif x == 60: return "soixante"
    elif x == 70: return "soixante-dix"
    elif x == 80: return "quatre-vingt"
    elif x == 90: return "quatre-vingt-dix"
    else        : return "zéro"

File: montant_num_cor.tex, line 150


def mot_valeur (x):
    """convertit un nombre compris inclus entre 0 et 16 inclus,
    20, 30, 40, 50, 60 en une chaîne de caractères"""
    dico = {'cinquante': 50, 'quarante': 40, 'onze': 11, 'huit': 8, 'six': 6, \
            'quinze': 15, 'trente': 30, 'douze': 12, 'cinq': 5, 'deux': 2, \
            'quatorze': 14, 'neuf': 9, 'soixante': 60, 'quatre': 4, \
            'zéro': 0, 'treize': 13, 'trois': 3, 'seize': 16, \
            'vingt': 20, 'un': 1, 'dix': 10, 'sept': 7}
    inv = {}
    for k,v in dico.iteritems () : inv [v] = k
    inv [70] = "soixante-dix"
    inv [80] = "quatre-vingt"
    inv [90] = "quatre-vingt-dix"
    return inv [x]

File: montant_num_cor.tex, line 171


def ecrit_dizaine(x):
    """convertit un nombre entre 0 et 99 sous sa forme littérale"""

    if x <= 16 : return ecrit_unite(x)

    s       = ""
    dizaine = x / 10
    unite   = x % 10
    s = mot_valeur (dizaine*10)
    s += " "
    s += mot_valeur (unite)
    return s

File: montant_num_cor.tex, line 190


for i in xrange(0,100):
    s = ecrit_dizaine (i)
    j = lire_dizaine (s)
    if i != j : print "erreur ", i, " != ", j, " : ", s

conversion de montant littéral en numérique

# coding: cp1252
import string

def lire_separation(s):
    """divise un nombre littéral en mots"""
    s = string.replace (s, "-", " ")
    return string.split (s)

def lire_separation(s):
    """divise un nombre littéral en mots"""
    return re.compile ("[- ]").split (s)

def valeur_mot (s) :
    """convertit numériquement les nombres inclus entre 0 et 16 inclus,
    20, 30, 40, 50, 60, s est une chaîne de caractères, le résultat est entier"""
    if   s == "zéro"      : return 0
    elif s == "un"        : return 1
    elif s == "deux"      : return 2
    elif s == "trois"     : return 3
    elif s == "quatre"    : return 4
    elif s == "cinq"      : return 5
    elif s == "six"       : return 6
    elif s == "sept"      : return 7
    elif s == "huit"      : return 8
    elif s == "neuf"      : return 9
    elif s == "dix"       : return 10
    elif s == "onze"      : return 11
    elif s == "douze"     : return 12
    elif s == "treize"    : return 13
    elif s == "quatorze"  : return 14
    elif s == "quinze"    : return 15
    elif s == "seize"     : return 16
    elif s == "vingt"     : return 20
    elif s == "trente"    : return 30
    elif s == "quarante"  : return 40
    elif s == "cinquante" : return 50
    elif s == "soixante"  : return 60
    else                  : return 0
        
def valeur_mot (s) :
    """convertit numériquement les nombres inclus entre 0 et 16 inclus,
    20, 30, 40, 50, 60, s est une chaîne de caractères, le résultat est entier"""
    dico = {'cinquante': 50, 'quarante': 40, 'onze': 11, 'huit': 8, 'six': 6, \
            'quinze': 15, 'trente': 30, 'douze': 12, 'cinq': 5, 'deux': 2, \
            'quatorze': 14, 'neuf': 9, 'soixante': 60, 'quatre': 4, \
            'zéro': 0, 'treize': 13, 'trois': 3, 'seize': 16, \
            'vingt': 20, 'un': 1, 'dix': 10, 'sept': 7}
    if s not in dico : return 0
    else : return dico [s]

def lire_dizaine_liste(s):
    """convertit une liste de chaîne de caractères dont
    juxtaposition forme un nombre littéral compris entre
    0 et 99"""
    r       = 0         # contient le résultat final
    dizaine = False     # a-t-on terminé le traitement des dizaines ?
    for mot in s:
        n = valeur_mot (mot)
        if n == 20 :
            if not dizaine and r > 0 and r != 60:
                r       *= n     # cas 80
                dizaine  = True
            else : r += n
        else : r += n
    return r

def lire_dizaine(s):
    s2 = s.replace ("-", " ")
    li = string.split (s2)
    return lire_dizaine_liste (li)

def mot_valeur (x):
    """convertit un nombre compris inclus entre 0 et 16 inclus,
    20, 30, 40, 50, 60 en une chaîne de caractères"""
    if   x == 0: return "zéro"
    elif x == 1: return "un"
    elif x == 2: return "deux"
    elif x == 3: return "trois"
    elif x == 4: return "quatre"
    elif x == 5: return "cinq"
    elif x == 6: return "six"
    elif x == 7: return "sept"
    elif x == 8: return "huit"
    elif x == 9: return "neuf"
    elif x == 10: return "dix"
    elif x == 11: return "onze"
    elif x == 12: return "douze"
    elif x == 13: return "treize"
    elif x == 14: return "quatorze"
    elif x == 15: return "quinze"
    elif x == 16: return "seize"
    elif x == 20: return "vingt"
    elif x == 30: return "trente"
    elif x == 40: return "quarante"
    elif x == 50: return "cinquante"
    elif x == 60: return "soixante"
    elif x == 70: return "soixante-dix"
    elif x == 80: return "quatre-vingt"
    elif x == 90: return "quatre-vingt-dix"
    else        : return "zéro"
        
def mot_valeur (x):
    """convertit un nombre compris inclus entre 0 et 16 inclus,
    20, 30, 40, 50, 60 en une chaîne de caractères"""
    dico = {'cinquante': 50, 'quarante': 40, 'onze': 11, 'huit': 8, 'six': 6, \
            'quinze': 15, 'trente': 30, 'douze': 12, 'cinq': 5, 'deux': 2, \
            'quatorze': 14, 'neuf': 9, 'soixante': 60, 'quatre': 4, \
            'zéro': 0, 'treize': 13, 'trois': 3, 'seize': 16, \
            'vingt': 20, 'un': 1, 'dix': 10, 'sept': 7}
    inv = {}
    for k,v in dico.iteritems () : inv [v] = k
    inv [70] = "soixante-dix"
    inv [80] = "quatre-vingt"
    inv [90] = "quatre-vingt-dix"
    return inv [x]
    
def ecrit_dizaine(x):
    """convertit un nombre entre 0 et 99 sous sa forme littérale"""

    if x <= 16:
        return mot_valeur (x)

    s       = ""
    dizaine = x / 10
    unite   = x % 10
    s = mot_valeur (dizaine*10)
    s += " "
    s += mot_valeur (unite)
    return s
    
for i in xrange(0,100):
    s = ecrit_dizaine (i)
    j = lire_dizaine (s)
    if i != j :
        print "erreur ", i, " != ", j, " : ", s

(1)

def pion_prendre(i,j,damier):
   c = damier [i][j]
   if c == 0: return False  # case vide, impossible de prendre
   c = 3 - c                # couleur de l'adversaire

   if damier [i-1][j-1] == c :     # s'il y a un pion adverse en haut à gauche
       if damier [i-2][j-2] == 0 : # si la case d'après en diagonale est vide
           return True             # on peut prendre     

   # on répète ce test pour les trois autres cases
   if damier [i-1][j+1] == c and damier [i-2][j+2] == 0: return True
   if damier [i+1][j-1] == c and damier [i+2][j-2] == 0: return True
   if damier [i+1][j+1] == c and damier [i+2][j+2] == 0: return True
        
   # si tous les tests ont échoué, on ne peut pas prendre
   return False

(2)

def pion_prendre(i,j,damier):
   c = damier [(i,j)]       # ou encore damier [i,j]
   if c == 0: return False  # case vide, impossible de prendre
   c = 3 - c                # couleur de l'adversaire

   # test pour une prise du pion dans les quatre cases voisines
   if damier [i-1,j-1] == c and damier [i-2,j-2] == 0: return True
   if damier [i-1,j+1] == c and damier [i-2,j+2] == 0: return True
   if damier [i+1,j-1] == c and damier [i+2,j-2] == 0: return True
   if damier [i+1,j+1] == c and damier [i+2,j+2] == 0: return True
        
   # si tous les tests ont échoué, on ne peut pas prendre
   return False

(3)

def pion_prendre(i,j,damier):
   c = damier [10*i+j]
   if c == 0: return False  # case vide, impossible de prendre
   c = 3 - c                # couleur de l'adversaire

   # test pour une prise du pion dans les quatre cases voisines
   if damier [10*(i-1)+j-1] == c and damier [10*(i-2)+j-2] == 0: return True
   if damier [10*(i-1)+j+1] == c and damier [10*(i-2)+j+2] == 0: return True
   if damier [10*(i+1)+j-1] == c and damier [10*(i+2)+j-2] == 0: return True
   if damier [10*(i+1)+j+1] == c and damier [10*(i+2)+j+2] == 0: return True
        
   return False

(4)

def pion_prendre(i,j,damier):
   c = damier [i][j]
   if c == 0: return False  # case vide, impossible de prendre
   c = 3 - c                # couleur de l'adversaire

   # on répète ce test pour les trois autres cases
   if i >= 2                 and j >= 2                  and \
      damier [i-1][j-1] == c and damier [i-2][j-2] == 0: return True
   if i >= 2                 and j < len (damier)-2      and \
      damier [i-1][j+1] == c and damier [i-2][j+2] == 0: return True
      
   if i < len (damier)-2     and j >= 2                  and \
      damier [i+1][j-1] == c and damier [i+2][j-2] == 0: return True
   if i < len (damier)-2     and j < len (damier)-2      and \
      damier [i+1][j+1] == c and damier [i+2][j+2] == 0: return True
        
   return False

File: partie_dames.tex, line 98


if c <= 0 : return False  # au lieu de if c == 0 : return False

File: partie_dames.tex, line 109


damier [(i-1,j-1)]   # est équivalent à    
damier [ i-1,j-1 ]   # cette ligne

File: langue_fa_cor.tex, line 12


def lit_fichier (nom) :
    f = open (nom, "r")                   # ouverture du fichier
    l = f.read ()                         # on récupère le contenu
    f.close ()                            # on ferme le fichier
    return l                              # on retourne le contenu

File: langue_fa_cor.tex, line 22


import urllib                       # import du module urllib
def lit_url (nom) : 
    f = urllib.urlopen (nom)        # on ouvre l'url
    res = f.read ()                 # on lit son contenu
    f.close ()                      # on termine la lecture
    return res                      # on retourne le résultat

File: langue_fa_cor.tex, line 32


def lit (texte) :
    if texte.startswith ("http") : s = lit_url (texte)  # Internet
    else : s = lit_fichier (texte)                      # fichier texte
    return s
    
s = lit ("hugo.txt")

File: langue_fa_cor.tex, line 43


def lit (texte) :
    try :
        s = lit_fichier (texte)            # fichier texte
        return s
    except :                               # si cela ne marche pas,
        s = lit_url (texte)                # on suppose que texte 
        return s                           # est une adresse Internet
    
s = lit ("hugo.txt")

File: langue_fa_cor.tex, line 57


def compte_lettre_count (texte) :
    texte = texte.upper ()             # pour éviter les accents
    res = { }                          # résultat, vide pour le moment
    for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" :  # pour tout l'alphabet
        res [c] = texte.count (c)      # on compte les occurrences de c
    return res

File: langue_fa_cor.tex, line 68


def compte_lettre (texte) :
    texte = texte.upper ()              # pour éviter les accents
    res = { }                           # résultat, vide pour le moment
    for c in texte :                    # pour tous les caractères du texte
        if not("A" <= c <= "Z") : continue # si ce n'est pas une lettre, on passe
        if c not in res : res [c] = 1   # si elle n'est pas là, on lui affecte 1
        else : res [c] += 1        # sinon, on augmente son nombre d'apparitions
    return res    

File: langue_fa_cor.tex, line 83


def comparaison () :
    s = lit_fichier ("hugo.txt")
    compte_lettre_count (s)      # on ne mémorise pas les résultats
    compte_lettre (s)            # car on souhaite mesurer le temps passé

import profile                   # import du module profile
profile.run ("comparaison()")    # mesure du temps passé dans la fonction 
                                 # comparaison et les fonctions qu'elle appelle

File: langue_fa_cor.tex, line 96


ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1    0.160    0.160    0.174    0.174 langue.py:19(compte_lettre)
     1    0.000    0.000    0.017    0.017 langue.py:31(compte_lettre_count)
     1    0.000    0.000    0.190    0.190 langue.py:43(comparaison)

File: langue_fa_cor.tex, line 117


ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1    0.120    0.120    0.133    0.133 langue.py:19(compte_lettre)
     1    0.002    0.002    0.082    0.082 langue.py:32(compte_lettre_count)

File: langue_fa_cor.tex, line 143


def compte_lettre (texte) :
    # ...
    s = sum (res.values ())
    for k in res :
        res [k] = float (res [k]) / s
    return res

File: langue_fa_cor.tex, line 169


# le dernier jour d'un condamné
c1 = compte_lettre (lit_url ("http://www.gutenberg.org/dirs/etext04/8ldrj10.txt"))
# the man who laughs
c2 = compte_lettre (lit_url ("http://www.gutenberg.org/files/12587/12587-8.txt"))

car = c1.keys ()
car.sort ()
for k in car :
    print k, " : ", "% 2.2f" % (c1 [k] * 100), "%", " % 2.2f" % (c2 [k] * 100), "%"

File: langue_fa_cor.tex, line 184


def langue_lettre (texte) :
    if "http" in texte : s = lit_url (texte)   # cas URL
    else : s = lit_fichier (texte)             # cas fichier
    c = compte_lettre (s)                      # on compte les lettres
    return c ["W"], c ["H"]                    # on retourne deux fréquences

File: langue_fa_cor.tex, line 194


def langue_lettre (texte) :
    ...                                        # lignes inchangées
    return c.get ("W", 0.0), c.get ("H", 0.0)  # on retourne deux fréquences

File: langue_fa_cor.tex, line 202


def curve (li) :
    cx,cy = [], []
    for l in li :                 # pour tous les textes de la liste
        x,y = langue_lettre (l)   # coordonnées d'un texte, fréquence W et H
        cx.append (x)             # on ajoute x à la liste des abscisses
        cy.append (y)             # on ajoute y à la liste des ordonnées
    return cx,cy

File: langue_fa_cor.tex, line 215


frcx,frcy = curve (fr)          # on récupère les coordonnées des textes français
encx,ency = curve (en)          # on récupère les coordonnées des textes anglais

import pylab                         # import du module matplotlib
pylab.plot (frcx, frcy, "rx",ms=10,\ 
                            mew=2.5) # on trace la courbe des textes français  
pylab.plot (encx, ency, "bv")        # on trace la courbe des textes anglais
pylab.legend (("francais", "anglais"), loc=2)  # légende (sans accent)
pylab.title ("langue")               # titre
pylab.xlabel ("frequence de W")      # légende de l'axe des abscisses
pylab.ylabel ("frequence de H")      # légende de l'axe des ordonnées
pylab.savefig ("graphe.png")         # enregistrement sous forme d'image
pylab.show ()                        # on fait apparaître le graphique

File: langue_fa_cor.tex, line 244


def est_anglais (texte) :
    w,h = langue_lettre (texte)
    return w > 0.01

File: langue_fa_cor.tex, line 281


<a href="http://...."> texte qui apparaît à l'écran </a>

File: langue_fa_cor.tex, line 289

                  
import urllib       # pour accéder une adresse internet
import re           # pour traiter les expressions régulières
                    
def list_url (site, root, nbpage = 100) :
    
    # expression régulières
    # tous les liens commençant par root et entre guillemets
    # exemple :  "http://www.lemonde.fr/index,0.26.html"
    # on place entre parenthèses la partie intéressante : 
    # c'est-à-dire tout ce qu'il y a entre les guillemets
    s = "\"(" + root + "[-_~a-zA-Z0-9/.?,]*?)\""
    exp  = re.compile (s, re.IGNORECASE)
    
    res    = [ ]         # résultat
    pile   = [ site ]    # page à explorer
    
    while len (pile) > 0 and len (res) < nbpage :
    
        # on bascule toutes les pages de pile vers res    
        for u in pile : 
            if u not in res : res.append (u)
        
        u = pile.pop ()  # on s'intéresse à la prochaine page
            
        try :
            f       = urllib.urlopen (u)      # accès à l'url
            text    = f.read ()               # on lit son contenu
            f.close ()                        # fin de l'accès
            
            liens = exp.findall (text)        # recherche de tous les liens
            for u in liens :
                if u in pile or u in res :    # on passe au suivant si 
                    continue                  # déjà vu
                    
                # on enlève les images et autres fichiers indésirables
                if ".gif" in u or ".png" in u or ".jpg" in u : continue
                if ".cs" in u or ".css" in u or ".js" in u : continue
                
                # on ajoute le liens à la liste des liens à explorer
                pile.append (u)
            
        except IOError, exc:
            print "problème avec url ", u
            continue 
            
    return res

File: langue_fa_cor.tex, line 340

    
url  = "http://www.lemonde.fr/"   # un journal français
res  = list_url (url, url)
for r in res : print r

url  = "http://www.nytimes.com/"  # un journal américain
res  = list_url (url, url)
for r in res : print r

File: langue_fa_cor.tex, line 374

    
import mdp,copy,numpy
nbfr,nben = len (fr), len (en)
all = numpy.array (fr + en)    # construction du nuage de points

node = mdp.nodes.PCANode()     # ACP
node.train (all)               # construction de l'ACP
y    = node (all)              # on peut aussi écrire y = mdp.pca (all)

# obtention des coordonnées des points dans le plan de projection
frcx = [ y [i,0] for i in range (0, nbfr) ]
frcy = [ y [i,1] for i in range (0, nbfr) ]
encx = [ y [i,0] for i in range (nbfr, nbfr + nben) ]
ency = [ y [i,1] for i in range (nbfr, nbfr + nben) ]

# dessin des points dans le plan de projection
# c'est le même code que précédemment
# ...

File: langue_fa_cor.tex, line 405

    
# même début que le programme précédent
allfr = numpy.array (fr)    # points français
allen = numpy.array (en)    # points anglais

node = mdp.nodes.FDANode ()
node.train (allfr, "fr")
node.train (allen, "en")
node.stop_training ()
node.train (allfr, "fr")
node.train (allen, "en")
y    = node (all)

détection automatique de la langue d'un texte

# coding: latin-1

def lit_fichier (nom) :
    """lit un fichier texte et retourne une chaine
    de caracteres incluant tout son contenu"""
    f = open (nom, "r")
    l = f.readlines ()
    f.close ()
    l = [ i.strip (" \n\r") for i in l ]
    return "".join (l)

def lit_url (nom) :
    import urllib
    f = urllib.urlopen (nom) 
    res = f.read ()
    f.close ()
    return res.replace ("\n", "").replace ("\r", "")
    
def compte_lettre1 (texte) :
    texte = texte.upper ()
    res = { }
    for c in texte :
        if not ("A" <= c <= "Z") : continue
        if c not in res : res [c] = 1 
        else : res [c] += 1
    s = sum (res.values ())
    if s > 0 :
        for k in res :
            res [k] = float (res [k]) / float (s)
    return res

def compte_lettre2 (texte) :
    texte = texte.upper ()
    res = { }
    for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" :
    #for i in xrange (32,256) :
    #    c = chr (i)
        res [c] = texte.count (c)
    s = sum (res.values ())
    if s > 0 :
        for k in res :
            res [k] = float (res [k]) / float (s)
    return res
    
def compte_lettre (texte) :
    res = compte_lettre1 (texte)
    res = compte_lettre2 (texte)
    return res
    
if False :
    texte = lit_url ("http://www.gutenberg.org/dirs/etext04/8ldrj10.txt")
    def compteprofile () :
        for i in range (0,100) :
            compte_lettre (texte)
            
    import profile
    profile.run ('compteprofile ()')
    import sys
    sys.exit (0)

def langue_lettre (texte) :
    if "http" in texte : s = lit_url (texte)
    else : s = lit_fichier (texte)
    s = s.replace ("www", "")
    s = s.replace ("http", "").replace (".htm", "")
    s = s.replace ("href", "")
    c = compte_lettre (s)
    return c.get ("W", 0.0), c.get ("H", 0.0)
    
def langue_lettre4 (texte) :
    if "http" in texte : s = lit_url (texte)
    else : s = lit_fichier (texte)
    s = s.replace ("www", "")
    s = s.replace ("http", "").replace (".htm", "")
    s = s.replace ("href", "")
    c = compte_lettre (s)
    return c.get ("H", 0.0), c.get ("U", 0.0), c.get ("W", 0.0), c.get ("Y", 0.0)
    
def curve (li) :
    cx,cy = [], []
    for l in li :
        #print "processing ", l
        x,y = langue_lettre (l)
        print len (cx), "-", x,y,l
        cx.append (x)
        cy.append (y)
    print cx, cy
    return cx,cy
        
def curve4 (li) :
    all = []
    for l in li :
        #print "processing ", l
        x,y,z,t = langue_lettre4 (l)
        all.append ( [x,y,z,t] )
        print len (all), "-", l
    return all
        

if False :
    #s2 = lit_fichier ("hugo_the_man_who_laugh.txt")
    #c2 = compte_lettre (s2)

    #s3 = lit_fichier ("hugo_legend_siecle_francais.txt")
    #c3 = compte_lettre (s3)

    # le dernier jour d'un condamné
    s1 = lit_url ("http://www.gutenberg.org/dirs/etext04/8ldrj10.txt")
    c1 = compte_lettre (s1)

    # the man who laughs
    s2 = lit_url ("http://www.gutenberg.org/files/12587/12587-8.txt")
    c2 = compte_lettre (s2)

    car = c1.keys ()
    car.sort ()
    for k in car :
        print k, " : ", "% 2.2f" % (c1 [k] * 100), "%",
        print "     % 2.2f" % (c2 [k] * 100), "%"
    
if False :
    fr = []
    en = []

    fr.append ("http://www.gutenberg.org/dirs/etext04/8ldrj10.txt")
    en.append ("http://www.gutenberg.org/files/12587/12587-8.txt")
    fr.append ("http://www.gutenberg.org/files/17489/17489-8.txt")
    en.append ("http://www.gutenberg.org/dirs/etext98/2ws2610.txt")
    fr.append ("http://www.gutenberg.org/files/2998/2998-8.txt")
    fr.append ("http://www.gutenberg.org/dirs/etext03/zadig10.txt")
    en.append ("http://www.gutenberg.org/files/4300/4300-8.txt")
    en.append ("http://www.gutenberg.org/files/174/174.txt")
    
if True :
    f = open ("lemonde.txt", "r")
    fr = f.readlines ()
    f.close ()
    fr = [ l.strip (" \n\t") for l in fr ]
    #fr = fr [:100]

    f = open ("nytimes.txt", "r")
    en = f.readlines ()
    f.close ()
    en = [ l.strip (" \n\t") for l in en ]
        
    #en = en [:100]

allfr = curve4 (fr)
allen = curve4 (en)
import pickle
f = open ("data.bin", "wb")
pickle.dump (allfr, f)
pickle.dump (allen, f)
f.close ()
stop

frcx,frcy = curve (fr)
encx,ency = curve (en)

print len (frcx), len (frcy)
print len (encx), len (ency)

f = open ("curve.txt", "w")
f.write (str (frcx) + "\n")
f.write (str (frcy) + "\n")
f.write (str (encx) + "\n")
f.write (str (ency) + "\n")
f.close ()

import pylab
pylab.plot (frcx, frcy, "rx",ms=5)
pylab.plot (encx, ency, "bo")
pylab.legend ((r"francais", "anglais"), loc=2)
pylab.title ("langue")
pylab.xlabel ("frequence de W")
pylab.ylabel ("frequence de H")
pylab.show ()


File: carre_magique.tex, line 23


class CarreMagique :
    def __init__ (self, nb) :
        self.nb = nb
        
m = [ [9, 3, 3], [ 4,5,6] , [3,8,2] ]

File: carre_magique.tex, line 41


def __str__ (self) :
    s = ""
    s += str (self.nb [0][0])
    return s

File: carre_magique.tex, line 68


a = calcul1 (3)
b = calcul2 (a)
c = calcul3 (b) # c résultat souhaité et affiché

File: carre_magique_cor.tex, line 9


cm = CarreMagique (m)

File: carre_magique_cor.tex, line 16


<__main__.CarreMagique instance at 0x01A254E0>

(1)

# coding: latin-1

class CarreMagique :
    
    def __init__ (self, nb) :
        """on place la matrice nb (liste de listes) 
        dans la classe accessible par le mot-clé self"""
        self.nb = nb
        
    # réponse à la question 2
    def __str__ (self) :
        """méthode appelée lorsque on cherche à afficher 
        un carré magique avec l'instruction print"""
        s = ""
        for i in range (0, len (self.nb)) :
            for j in range (0, len (self.nb)) : s += str ( self.nb [i][j]) + " "
            s += "\n" # pour passer à la ligne
        # réponse à la question 4
        s += "somme " + str (self.somme_ligne (0))
        return s
        
    # réponse à la question 3
    def somme_ligne (self, i) :
        s = 0
        for j in range (0, len (self.nb)) : s += self.nb [i][j]
        return s
        
    # réponse à la question 5
    def somme_colonne (self, j) :
        s = 0
        for i in range (0, len (self.nb)) : s += self.nb [i][j]
        return s
        
    # réponse à la question 6
    def est_magique (self) :
        # on stocke toutes les sommes
        l = []
        for i in range (0, len (self.nb)) : l.append ( self.somme_ligne (i) )
        for j in range (0, len (self.nb)) : l.append ( self.somme_colonne (j) )
            
        # réponse à la question 7
        l.append ( self.somme_diagonale (0)) 
        l.append ( self.somme_diagonale (1))

        # on trie la liste
        l.sort ()
        
        # on compare le plus petit et le plus grand, s'il sont égaux, 
        # le carré est magique
        return l [0] == l [ len(l)-1 ]
        
    # réponse à la question 7
    def somme_diagonale (self, d) :
        """d vaut 0 ou 1, première ou seconde diagonale"""
        s = 0
        if d == 0 :
            for i in range (0, len (self.nb)) : s += self.nb [i][i]
        else :
            for i in range (0, len (self.nb)) : 
                s += self.nb [i][len(self.nb)-i-1]
        return s
        
    # réponse à la question 8
    def nombre_differents (self) :
        """retourne True si tous les nombres sont différents,
        on place les nombres un par un dans un dictionnaire,
        dès que l'un d'eux s'y trouve déjà,
        on sait que deux nombres sont identiques, le résultat est False"""
        k = { }
        for i in range (0, len (self.nb)) :
            for j in range (0, len (self.nb)) :
                c = self.nb [i][j]
                if c in k : return False     # pas besoin d'aller plus loin
                                             # il y a deux nombres identiques
                else : k [c] = 0
        return True
        
        
m = [ [9, 3, 7],  [ 4,5,6] , [1,8,2] ]
cm = CarreMagique (m)           # réponse à la question 1
print cm                        # affiche 15
print cm.est_magique ()         # affiche False
print cm.nombre_differents ()   # affiche True

m = [ [9, 9, 9],  [9, 9, 9], [9, 9, 9] ]
cm = CarreMagique (m)
print cm                        # affiche 15
print cm.est_magique ()         # affiche True
print cm.nombre_differents ()   # affiche False

(2)

from carre_magique import CarreMagique
res = []
for a in range (1,10) :
    for b in range (1,10) :
        for c in range (1,10) :
            for d in range (1,10) :
                for e in range (1,10) :
                    for f in range (1,10) :
                        for g in range (1,10) :
                            for h in range (1,10) :
                                for i in range (1,10) :
                                    l  = [ [a,b,c], [d,e,f], [g,h,i] ]
                                    cm = CarreMagique (l)
                                    if cm.nombre_differents () and \
                                                  cm.est_magique () :
                                        res.append (cm)

print len (res)
for r in res :
    print r

(3)

# coding: latin-1
from carre_magique import CarreMagique

dim = 3
nb  = dim*dim
res = []         # contiendra la liste des carrés magiques

# le compteur : neuf nombres 1
ind = [1 for i in range (0,nb) ]

while ind [0] <= nb :
    
    # transformation d'une liste en une liste de listes
    # [1,2,3,4,5,6,7,8,9] --> [[1,2,3],[4,5,6],[7,8,9]]
    l = []
    for i in range (0, dim) :
        l.append ( ind [i*dim:(i+1)*dim] )
    
    # on vérifie que le carré est magique et 
    # a des nombres tous différents
    cm = CarreMagique (l)
    if cm.nombre_differents () and cm.est_magique () :
        res.append (cm)

    # on passe au carré suivant : 
    i        = nb-1      # dernier indice (9 ici)
    ind [i] += 1         # addition de 1 au dernier indice
    while i > 0 and ind [i] > nb :
        ind [i-1] += 1   # un des indices est supérieur à nb (9 ici)
        ind [i]    = 1   # on le remet à 1
        i         -= 1   # et on propage l'information à l'indice inférieur

# résultat final
print len (res)
for r in res : print r

(4)

# coding: latin-1
from carre_magique import CarreMagique

dim = 3
nb  = dim*dim
M   = 9 ** nb    # on va tester 9^9 carrés possibles
res = []         # contiendra la liste des carrés magiques

for n in xrange (0,M) :
    
    # on décompose n en liste
    ind = []
    k   = n
    for t in range (0,nb) :
        dec = k % nb
        k   = k / nb
        ind.append (dec+1)
    
    # transformation d'une liste en une liste de listes
    # [1,2,3,4,5,6,7,8,9] --> [[1,2,3],[4,5,6],[7,8,9]]
    l = []
    for i in range (0, dim) :
        l.append ( ind [i*dim:(i+1)*dim] )
    
    # on vérifie que le carré est magique et 
    # a des nombres tous différents
    cm = CarreMagique (l)
    if cm.nombre_differents () and cm.est_magique () :
        res.append (cm)

# résultat final
print len (res)
for r in res : print r

File: carre_magique_cor.tex, line 47


Traceback (most recent call last):
  File "carre_magique_tous5.py", line 9, in <module>
    for n in range (0,M) :
MemoryError

(5)

# coding: latin-1
from carre_magique import CarreMagique

def echange (p, i, pos) :
    # échange de deux éléments d'indice i et pos du tableau p
    if i != pos :
        e       = p [i]
        p [i]   = p [pos]
        p [pos] = e

def permutation (res, dim, pos = 0, p = None) :
    # parcours des permutations par récurrence
    # pour le premier appel à la fonction permutation
    if p == None : p = range (1, dim*dim+1)
        
    if pos < len (p) :
        # on organise les permutations de l'élément p [pos], p [pos+1], ...
        for i in range (pos, len (p)) :
            echange (p, i, pos)
            permutation (res, dim, pos+1, p)
            echange (p, i, pos)
    else :
        # pos correspond au dernier élément : il n'y a plus de permutation
        # possible avec les éléments qui suivent
        # on teste donc le nouveau carré
        l = []
        for i in range (0, len (p)/dim) :
            l.append ( p [i*dim:(i+1)*dim] )
        cm = CarreMagique (l)
        if cm.est_magique () : res.append (cm)
    
# permutations
res = []
permutation ( res, 3 )
# résultats
print "nombre de carrés ", len (res)
for r in res : print r

File: quicksort.tex, line 46

			
racine = NoeudTri ("un")
racine.insere ("unite")
racine.insere ("deux")
print racine

File: quicksort.tex, line 60


c:\python26\python setup.py install

File: quicksort.tex, line 70


digraph GA {
    2 [label="deux",style=filled,shape=record]
    3 [label="abc" ,style=filled,shape=record]
    2 -> 3 [label="<"]
}

File: quicksort.tex, line 97


g = open ("graph.txt", "w")  #
g.write (graph)              # partie écriture dans un fichier
g.close ()                   #
dot = pydot.graph_from_dot_file ("graph.txt") # partie graphe
dot.write_png ("graph.png", prog="dot")       # avec pydot

File: quicksort_cor.tex, line 10


class NoeudTri (object):
    def __init__(self,s):
        self.mot = s

File: quicksort_cor.tex, line 19


class NoeudTri (object):
    def __init__(self,s): self.mot = s
    def __str__(self)   : return self.mot + "\n"  # \n : passage à la ligne

File: quicksort_cor.tex, line 28


class NoeudTri (object):
    def __init__(self,s): self.mot = s
    def __str__(self)   : return self.mot + "\n"

    def insere (self,s):
        c = cmp (s, self.mot)
        if   c == -1 : self.avant = NoeudTri (s)  # ajout d'un successeur
        elif c ==  1 : self.apres = NoeudTri (s)  # ajout d'un successeur

File: quicksort_cor.tex, line 43


class NoeudTri (object):
    def __init__(self,s): self.mot = s
        
    def __str__(self):
        s = ""
        if "avant" in self.__dict__: s += self.avant.__str__ ()
        s += self.mot + "\n"
        if "apres" in self.__dict__: s += self.apres.__str__()
        return s

    def insere (self,s):
        c = cmp (s, self.mot)
        if   c == -1 : self.avant = NoeudTri (s)
        elif c ==  1 : self.apres = NoeudTri (s)

File: quicksort_cor.tex, line 64


deux
un
unite

(1)

# coding: latin-1
import string

class SecondeInserstion (AttributeError):
    "insertion d'un mot déjà inséré"

class NoeudTri :
    
    def __init__(self,s): self.mot = s
        
    # la création d'un nouveau noeud a été placée dans une méthode
    def nouveau_noeud (self, s) : 
        return self.__class__ (s)
        #return NoeudTri (s)
        
    def __str__(self):
        s = ""
        if "avant" in self.__dict__: s += self.avant.__str__ ()
        s += self.mot + "\n"
        if "apres" in self.__dict__: s += self.apres.__str__()
        return s

    def insere (self,s):
        c = cmp (s, self.mot)
        if c == -1:
            if "avant" in self.__dict__ : self.avant.insere (s) # délégation
            else :  self.avant = self.nouveau_noeud (s)         # création
        elif c == 1:
            if "apres" in self.__dict__ : self.apres.insere (s) # délégation
            else: self.apres = self.nouveau_noeud (s)           # création
        else:
            raise SecondeInsertion, "mot : " + s
        
l = ["un", "deux", "unite", "dizaine", "exception", "dire", \
     "programme", "abc", "xyz", "opera", "quel"]
     
racine = None
for mot in l :
    if racine == None : 
        # premier cas : aucun mot --> on crée le premier noeud
        racine = NoeudTri (mot)
    else : 
        # second cas : il y a déjà un mot, on ajoute le mot suivant 
        # à l'arbre
        racine.insere (mot)

print racine

(2)

# coding: latin-1
import string
import pydot
import quicksort

class NoeudTri2 (quicksort.NoeudTri):

    def chaine_graphe (self):
        # le principe est le même que pour la méthode __str__
        # excepté que le format est différent
        g = str (id (self)) + ' [label="' + self.mot \
                            + '",style=filled,shape=record,fontsize=60]\n'
        if "avant" in self.__dict__:
            h  = self.avant.chaine_graphe ()
            g += h + str (id (self)) + " -> " + str (id (self.avant)) \
                   + ' [label="<",fontsize=60]' + '\n'
        if "apres" in self.__dict__:
            h  = self.apres.chaine_graphe ()
            g += h + str (id (self)) + " -> " + str (id (self.apres)) \
                   + ' [label=">",fontsize=60]' + "\n"
        return g

    #def nouveau_noeud (self, s) : return NoeudTri2 (s)
        
    def image (self, file, im) :
        # on crée un graphe : on récupère le code du graphe
        graph = self.chaine_graphe ()
        # auquel on ajoute un début et une fin
        graph = "digraph GA {\n" + graph + "}\n"
        
        # puis on l'écrit dans le fichier file
        g = open (file, "w")
        g.write (graph)
        g.close ()

        # enfin, on convertit ce fichier en image
        dot = pydot.graph_from_dot_file (file)
        dot.write_png (im, prog="dot")

def construit_arbre () :
    # même code que dans le programme précédent
    # mais inclus dans une fonction
    l = ["un", "deux", "unite", "dizaine", "exception", "dire", \
         "programme", "abc", "xyz", "opera", "quel"]
    racine = None
    for mot in l :
        if racine == None : racine = NoeudTri2 (mot)
        else : racine.insere (mot)
    return racine
    
racine = construit_arbre ()
print racine
racine.image ("graph.txt", "graph.png")

File: quicksort_cor.tex, line 99


Traceback (most recent call last):
  File "quicksort2.py", line 53, in <module>
    racine.image ("graph.txt", "graph.png")
  File "quicksort2.py", line 27, in image
    graph = self.chaine_graphe ()
  File "quicksort2.py", line 14, in chaine_graphe
    h  = self.avant.chaine_graphe ()
AttributeError: NoeudTri instance has no attribute 'chaine_graphe'

File: quicksort_cor.tex, line 112


def nouveau_noeud (self, s) : return self.__class__ (s)

File: quicksort_cor.tex, line 120


digraph GA {
18853120 [label="un",style=filled,shape=record]
28505472 [label="deux",style=filled,shape=record]
28505712 [label="abc",style=filled,shape=record]
28505472 -> 28505712 [label="<"]
28505552 [label="dizaine",style=filled,shape=record]
28505592 [label="dire",style=filled,shape=record]
28505552 -> 28505592 [label="<"]
28505632 [label="exception",style=filled,shape=record]
28505672 [label="programme",style=filled,shape=record]
28505792 [label="opera",style=filled,shape=record]
28505672 -> 28505792 [label="<"]
28505832 [label="quel",style=filled,shape=record]
28505672 -> 28505832 [label=">"]
28505632 -> 28505672 [label=">"]
28505552 -> 28505632 [label=">"]
28505472 -> 28505552 [label=">"]
18853120 -> 28505472 [label="<"]
28505512 [label="unite",style=filled,shape=record]
28505752 [label="xyz",style=filled,shape=record]
28505512 -> 28505752 [label=">"]
18853120 -> 28505512 [label=">"]
}

sortie HTML

# coding: latin-1
import quicksort2

# construction de l'arbre
racine = quicksort2.construit_arbre ()
# construction de l'image du graphe
racine.image ("graph.txt", "graph.png")

# création d'un fichier HTML
f = open ("page.html", "w")
f.write ("<body><html>\n")              # début

f.write ("<H1> liste triée </H1>\n")    # titre pour la liste triée
s = str (racine)                        # on récupère la liste triée
s = s.replace ("\n", "<BR>\n")          # <BR> permet de passer à la ligne
f.write (s)

f.write ("<H1> graphe </H1>\n")         # titre pour l'image
f.write ('<img src="graph.png" width=400/>\n')    # image

f.write ("<H1> code du graphe </H1>\n") # titre pour le code du graphe
s = racine.chaine_graphe ()             # on récupère le code du graphe
f.write ("<pre>\n")                     # on l'affiche tel quel
f.write (s)
f.write ("</pre>\n")

f.write ("</html></body>\n")            # fin
f.close ()

# on lance le navigateur automatiquement pour afficher la page
import os
os.system (r'"C:\Program Files\Mozilla Firefox\firefox" page.html')

File: quicksort_cor.tex, line 158


<body><html>
<H1> liste triée </H1>
abc<BR>
deux<BR>
...
unite<BR>
xyz<BR>
<H1> graphe </H1>
<img src="graph.png" width=400/>
<H1> code du graphe </H1>
<pre>
13697312 [label="un",style=filled,shape=record,fontsize=60]
13697192 [label="deux",style=filled,shape=record,fontsize=60]
34692472 [label="abc",style=filled,shape=record,fontsize=60]
...
13697232 -> 34692592 [label=">",fontsize=60]
13697312 -> 13697232 [label=">",fontsize=60]
</pre>
</html></body>

sortie PDF

# coding: latin-1
import quicksort2

# construction de l'arbre
racine = quicksort2.construit_arbre ()
# construction de l'image du graphe
racine.image ("graph.txt", "graph.png")

# construction du début du fichier tex
package = """a4 amsmath amssymb subfigure float latexsym amsfonts
epic eepic makeidx multido varindex moreverb alltt fancyvrb fancyhdr
color eurosym tabularx placeins url shorttoc""".split ()

header = """\\documentclass[french,11pt]{article}\n\\usepackage[french]{babel}
\\usepackage[usenames]{color}\\usepackage{""" + \
                          "}\n\\usepackage{".join (package) + \
"""}\\usepackage[small,normal]{caption2}\\urlstyle{sf}
\\usepackage[pdftex]{graphicx}\usepackage[T1]{fontenc}
\DefineVerbatimEnvironment{verbatimx}{Verbatim}{frame=single, 
framerule=.1pt, framesep=1.5mm, fontsize=\\footnotesize,xleftmargin=0pt}
\\begin{document}\n"""

# création d'un fichier tex
f = open ("page.tex", "w")
f.write (header)

f.write ("\\title{Tri quicksort}\n")    # définit le titre
f.write ("\\maketitle\n")               # écrit le titre
f.write ("\\tableofcontents\n")         # table des matières

f.write ("\\section{liste triée}\n")    # titre pour la liste triée
s = str (racine)                        # on récupère la liste triée
s = s.replace ("\n", "\\\\  \n")        # \\ passe à la ligne
f.write ("\\begin{tabular}{|l|}\n")
f.write (s)
f.write ("\\end{tabular}\n")

f.write ("\\section{graphe}\n")         # titre pour l'image
f.write ('\\includegraphics[height=5cm]{graph.png}\n')    # image

f.write ("\\section{code du graphe}\n") # titre pour le code du graphe
s = racine.chaine_graphe ()             # on récupère le code du graphe
f.write ("\\begin{verbatimx}\n")        # on l'affiche tel quel
f.write (s)
f.write ("\\end{verbatimx}\n")

f.write ("\\end{document}\n")            # fin
f.close ()

# on compile deux fois le fichier pour que la table des matières
# soit bien prise en compte
import os
os.system (r'"C:\Program Files\MiKTeX 2.7\miktex\bin\pdflatex" page.tex')
os.system (r'"C:\Program Files\MiKTeX 2.7\miktex\bin\pdflatex" page.tex')

# on affiche le résultat avec Adobe Reader
os.system (r'"C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe" page.pdf')

File: cluster.tex, line 28


import random
n = random.gauss (0,1)  # loi normale de moyenne 0, de variance 1
u = random.random ()    # loi uniforme [0,1]
import math
x,y = math.cos (t), math.sin(t)  # cosinus, sinus

File: cluster.tex, line 40


import matplotlib.pyplot as plt
x   = [ ... ]
y   = [ ... ]
fig = plt.figure()
ax  = fig.add_subplot(111)
ax.plot (x,y, 'o')
plt.savefig ("im1.png") # ou plt.show () pour afficher le graphe

File: cluster.tex, line 62


import numpy as np
mat = np.matrix ( [[1,2],[3,4]] ) # crée une matrice 2*2
s   = mat.shape           # égale à (nombre de lignes, nombre de colonnes)
l   = mat [0,:]           # retourne la première ligne
c   = mat [:,0]           # retourne la première colonne
mat [:,0] = mat [:,1]     # la première ligne est égale à la seconde
o   = np.ones ( (10,10) ) # crée un matrice de 1 10x10
d   = np.diag (d)         # extrait la diagonale d'une matrice
dd  = np.matrix (d)       # transforme d en matrice
t   = mat.transpose ()    # obtient la transposée
e   = mat [0,0]           # obtient de première élément
k   = mat * mat           # produit matriciel
m   = mat * 4             # multiplie la matrice par 4
mx  = np.max (mat [0,:])  # obtient le maximum de la première ligne
s   = np.sum (mat [0,:])  # somme de la première ligne
l   = mat.tolist ()       # transformer une matrice en list

File: cluster.tex, line 82


mat = np.diagflat ( np.ones ( (1,4) ) )
print mat  # matrice diagonale
t   =  mat == 0
print t    # matrice de booléens
mat [ mat == 0 ] = 4
print mat  # ...

File: cluster.tex, line 93


def sqrt (x) : return x**0.5 if x >= 0 else 0
func = np.vectorize (sqrt, otypes=[float])
mat  = func (dist)  # dist est une matrice

File: cluster.tex, line 134


import matplotlib.pyplot as plt
x1   = [ ... ]
y1   = [ ... ]
x2   = [ ... ]
y2   = [ ... ]
fig = plt.figure()
ax  = fig.add_subplot(111)
ax.plot (x1,y1, 'o')
ax.plot (x2,y2, 'x')
plt.savefig ("im2.png")

File: cluster.tex, line 198


def download_quotes (code, d1, d2) :
    root = "http://ichart.yahoo.com/table.csv?s=%s&a=%02d&b=%d&c=%d" \
                               "&d=%02d&e=%d&f=%d&g=d&ignore=.csv" % \
              (code, d1.month-1, d1.day, d1.year, d2.month-1, d2.day, d2.year)
    f    = urllib.urlopen (root)
    qu   = f.read ()
    f.close ()
    lines = qu.split ("\n")
    lines = [ l .strip (" \n\r") for l in lines ]
    head  = lines [0]
    lines = lines [1:]
    lines = [ l.split (",") for l in lines if "," in l ]
    lines = [ (get_date (l[0]), l) for l in lines ]
    lines = [ l [1] for l in lines if d1 <= l [0] <= d2 ]
    lines = [ "\t".join (l) for l in lines ]
    
    return "\n".join ([head ] + lines)

File: cluster.tex, line 220


import datetime
import os.path
def telecharge_et_ecrit_dans_un_fichier (code) :
    year  = datetime.datetime (2009,1,1) - datetime.datetime (2008,1,1)
    today = datetime.datetime (2009,1,1).now ()
    lyear = today - year
    file  = code + ".txt"
    if os.path.exists (file) : return  # si le fichier existe déjà, ne le fait pas
    res   = download_quotes (a, lyear, today)
    f     = open (file, "w")
    f.write (res)
    f.close ()

File: cluster_cor.tex, line 9


def random_set (nb = 100) :
    res = []
    for i in range (0, nb) :
        x,y = random.gauss (0,1),random.gauss (0,1)
        res.append ([x,y])
    for i in range (0, nb*2) :
        x,y = random.gauss (0,1),random.gauss (0,1)
        n   = (x**2 + y**2) ** 0.5
        if n == 0 : n == 1.0
        x  *= 5.0 / n
        y  *= 5.0 / n
        x  += random.gauss (0,0.5)
        y  += random.gauss (0,0.5)
        res.append ([x,y])
    return res

classification non supervisée

# coding: latin-1
import sys,random,copy,math
import matplotlib.pyplot as plt
import numpy as np
    
def random_set (nb = 100) :
    """construit un échantillon aléatoire avec deux cercles concentriques, 
    nb pour le premier, nb*2 pour le second"""
    res = []
    for i in range (0, nb) :
        x,y = random.gauss (0,1),random.gauss (0,1)
        res.append ([x,y])
    for i in range (0, nb*2) :
        x,y = random.gauss (0,1),random.gauss (0,1)
        n   = (x**2 + y**2) ** 0.5
        if n == 0 : n == 1.0
        x  *= 5.0 / n
        y  *= 5.0 / n
        x  += random.gauss (0,0.5)
        y  += random.gauss (0,0.5)
        res.append ([x,y])
    res.sort ()
    return res
    
def draw (points, clas = None) :
    """dessine un nuage de points, si clas est une liste, 
    elle contient un indice de clas"""
    
    if clas == None :
        fig = plt.figure()
        ax = fig.add_subplot(111)
        x = [ p [0] for p in points ]
        y = [ p [1] for p in points ]
        ax.plot (x,y, 'o')
        plt.savefig ("im1.png")
    else :
        fig = plt.figure()
        ax = fig.add_subplot(111)
        x = [ p [0] for p,c in zip (points, clas) if c == 0 ]
        y = [ p [1] for p,c in zip (points, clas) if c == 0 ]
        ax.plot (x,y, 'o')
        x = [ p [0] for p,c in zip (points, clas) if c == 1 ]
        y = [ p [1] for p,c in zip (points, clas) if c == 1 ]
        ax.plot (x,y, 'x')
        plt.savefig ("im2.png")
        
def distance_ligne (mat) :
    """retourne une matrice dont chaque case correspond 
    aux distances entre lignes"""
    prod = mat * mat.T
    dist = copy.deepcopy (prod)
    lin  = dist.shape [0]
    
    di = np.diag (prod)
    di = np.matrix (di)
    one  = np.ones ((1,lin))
    ii   = one.transpose () * di
    jj   = di.transpose () * one
    dist = prod * (-2) + ii + jj

    def sqrt (x) : return x**0.5 if x >= 0 else 0.0
    func_sqrt = np.vectorize (sqrt, otypes=[float])
    dist = func_sqrt (dist)

    # autre essai
    #def m (x)    : return x**0.6 if x >= 0 else 0.0 
    #func_m    = np.vectorize (m, otypes=[float])
    #dist = func_m (dist)
    
    #code dont la logique est plus explicite mais il est beaucoup plus lent 
    #for i in xrange (0, lin) :
    #    for j in xrange (0, lin) :
    #        x = (prod [i,i] + prod [j,j] - 2*prod [i,j])
    #        
    #        if x <= 0 : dist [i,j]= 0  #problème d'arrondi numérique
    #        else : dist [i,j]= x**0.5
        
    return dist
    
def iteration (dist) :
    """itération de l'algorithme"""
    dist = distance_ligne (dist)
    lin  = dist.shape [0]
    for i in xrange (0, lin) :
        x = np.max (dist [i,:])
        y = dist [i,:] * (1.0 / x )#* lin)
        dist [i,:] = y
    return dist
        
def algorithme_cluster (points) :
    """algorithme"""
    mat     = np.matrix (points)
    lin,col = mat.shape
    dist    = distance_ligne (mat)
    for i in range (0,50) :
        print "itération i", i, np.min (dist [0,1:]), \
                                np.max (dist), np.sum (dist [0,:])
        dist = iteration (dist)
        
    M    = np.max (dist [0,:])/2
    res  = dist [0,:]
    good = res > M
    bad  = res <= M
    res [good]= 1
    res [bad] = 0
    li   = res.tolist () [0]

    return li

if __name__ == "__main__" :
    
    # construction of the random set (two circles, a line)
    rnd = random_set ()
    #draw (rnd)
    clas = algorithme_cluster (rnd)
    draw (rnd, clas)
    plt.show ()

classification non supervisée d'actions

# coding: latin-1
import sys
import random
import matplotlib.pyplot as plt
import numpy as np
import copy
import math
import os
from cluster import *

import urllib
import datetime
import sys

def get_cac40_quotes () :
    """récupère les cotes du CAC40 depuis un fichier texte
    format : quote \t nom
    """
    file  = "cac40_quote.txt"
    quote = open (file, "r").readlines ()
    quote = [ q.strip (" \n\r") for q in quote ]
    quote = [ q.split ("\t") for q in quote if len (q) > 0 ]
    assert 38 <= len (quote) <= 40
    return quote
    
def get_date (s) :
    """convertit une date depuis une chaîne de caractères vers un format Python"""
    y,m,d = s.split ("-")
    y,m,d = int(y),int(m),int(d)
    d     = datetime.datetime (y,m,d)
    return d

def download_quotes (code, d1, d2) :
    """
    télécharge la cotation d'une action entre deux dates
        - code: cote
        - d1:   première date (format python)
        - d2:   seconde date (format python)
    """
    root = "http://ichart.yahoo.com/table.csv?s=%s&a=%02d&b=%d&c=%d" \
                               "&d=%02d&e=%d&f=%d&g=d&ignore=.csv" % \
              (code, d1.month-1, d1.day, d1.year, d2.month-1, d2.day, d2.year)
              
    f    = urllib.urlopen (root)
    qu   = f.read ()
    f.close ()
    lines = qu.split ("\n")
    lines = [ l .strip (" \n\r") for l in lines ]
    head  = lines [0]
    lines = lines [1:]
    lines = [ l.split (",") for l in lines if "," in l ]
    lines = [ (get_date (l[0]), l) for l in lines ]
    lines = [ l [1] for l in lines if d1 <= l [0] <= d2 ]
    lines = [ "\t".join (l) for l in lines ]
    
    return "\n".join ([head ] + lines)
    
def get_quotes_internet (all) :
    """télécharge toutes les cotations pour les cotes dans all 
       pour les 6 derniers mois
        - all: dictionnaire { cote: nom complet }
        - enregistre le résultat dans un fichier pour éviter de télécharger
            les cours à chaque exécution
    """
    year2  = datetime.datetime (2009,1,1) - datetime.datetime (2008,6,1)
    today = datetime.datetime (2009,1,1).now ()
    lyear = today - year2
    path  = "quotes/"
    for a,nom in all :
        file = path + a + ".txt"
        if os.path.exists (file) : continue
        res = download_quotes (a, lyear, today)
        f = open (file, "w")
        f.write (res)
        f.close ()
        
        print "loading ", a, " from ", lyear , " to ", today, \
              " lines ", len (res.split ("\n"))
                
def get_close_ret (code) :
    """retourne la série des rendements depuis un fichier de cotations
    créé par la fonction get_quotes_internet"""
    file = "quotes/" + code + ".txt"
    lines = open (file, "r").readlines ()
    lines = lines [1:]
    lines = [ l for l in lines if "\t" in l ]
    lines = [l.strip ("\n\r ").split ("\t") [4] for l in lines ]
    lines = [ float (x) for x in lines ]
    lines = [ (lines [x]-lines [x-1])/lines [x-1] for x in xrange (1, len (lines))]
    return lines
    
def get_matrix (all) :
    """retourne la matrice des autocorrélations"""
    colonnes = []
    for a,nom in all :
        close = get_close_ret (a)
        if len (colonnes) != 0 and len (close) != len (colonnes [0]) :
            message = "problème avec %s longueur %d <> %d " % \
                               (nom, len (close), len (colonnes [0]))
            raise Exception ("les données ne sont pas alignées dans le temps, " \
                 "une série ne contient le même nombre d'observations\n" + message)
        colonnes.append (close)
    mat = np.matrix (colonnes)  # s'il y a une erreur ici, cela signifie que les 
                                # actions n'ont pas des cotations aux mêmes dates
    cor = np.corrcoef (mat)
    return cor


if __name__ == "__main__" :
    
    if not os.path.exists ("quotes"): os.mkdir ("quotes")
    quotes = get_cac40_quotes ()
    get_quotes_internet (quotes)
    mat = get_matrix (quotes)
    print mat.shape
    li  = algorithme_cluster (mat)
    print li
    for a,b in zip (quotes,li) :
        print b, a [1], "\t", a [0]
    

, correction 2006

# coding: latin-1
# question 1
def lit_fichier (file) :
    f = open (file, "r")
    mot = []
    for l in f :
        mot.append ( l.replace ("\n", "") )
    f.close ()
    return mot

mot = lit_fichier ("td_note_texte.txt")
print mot

# question 2
def est_trie (mot) :
    for i in range (1, len (mot)) :
        if mot [i-1] > mot [i] :
            return False
    return True
    
tri = est_trie (mot)
print "liste triée ", tri

# question 3
def cherche (mot, m) :
    for i in range (0, len (mot)) :
        if mot [i] == m : 
            return i
    return -1
    
print "mot ACHATS ", cherche (mot, "ACHATS")
print "mot achats ", cherche (mot, "achats")

# question 4
un   = cherche (mot, "UN")
deux = cherche (mot, "DEUX")
print "recherche normale ", un, deux
print "nombre d'itérations", un + deux

# question 5, 6, nbun et nbdeux contiennent le nombre de comparaisons
def cherche_dicho (mot, m) :
    a = 0
    b = len (mot)-1
    nb = 0
    while a < b :
        nb += 1
        p = (a+b)/2
        if   mot [p] == m :  return p,nb
        elif mot [p] >  m :  b = p-1
        else :               a = p+1
    return -1,nb
    
un,nbun     = cherche_dicho (mot, "UN")
deux,nbdeux = cherche_dicho (mot, "DEUX")
print "recherche dichotomique ", un, deux
print "nombre d'itérations ", nbun + nbdeux

# question 7
"""
Lors d'une recherche simple, au pire, l'élément cherche sera 
en dernière position, ce qui signifie n itérations pour le trouver. 
Le coût de la recherche simple est en O(n).
"""

# question 8
"""
Lors de la recherche dichotomique, à chaque itération, on divise par deux 
l'ensemble dans lequel la recherche s'effectue,
au départ n, puis n/2, puis n/4 jusqu'à  ce que n/2^k soit nul 
c'est-à-dire k = partie entière de ln n / ln 2
il y a au plus k itérations donc le coût de l'algorithme est en O (ln n).
"""

File: td_note_2007.tex, line 63


class Date :
    def __init__ (self, jour, mois) :
        ...

, correction 2007

# coding: latin-1
####################################
# exercice 1
####################################

# question 1
def numero (jour, mois, duree = [31, 28, 31,30,31,30,31,31,30,31,30,31] ) :
    s = 0
    for i in range (0,mois-1) :
        s += duree [i]
    s += jour - 1
    return s+1
    
# question 2
def conversion_liste (li) :
    res = []
    for jour,mois in s : res.append ( numero (jour, mois))
    # pareil que 
    # for i in range (0, len (s)) : res.append ( numero (s [i][0], s [i][1]))
    return res
    
def ecart (num) :
    res = []
    for i in range (1, len (num)) :
        d = num [i] - num [i-1]
        res.append (d)
    return res
    

s = [ (1,1), (9,4), (1,5), (8,5), (17,5), (4,6), (14,7), \
        (15,8), (1,11), (11,11), (25,12) ]
r = conversion_liste (s)
ec = ecart (r)

# question 3
pos = ec.index ( max (ec) )
print "position de l'écart le plus grand ", pos
print "jour ", s [pos], " --> ", s [pos+1]

####################################
# exercice 2
####################################

# question 4
class Date :
    def __init__ (self, jour, mois) :
        self.jour = jour
        self.mois = mois
        self.duree = [31, 28, 31,30,31,30,31,31,30,31,30,31]
        
    # question 5
    def numero (self) :
        s = 0
        for i in range (0,self.mois-1) :
            s += self.duree [i]
        s += self.jour - 1
        return s+1
        
    # question 6    
    def difference (self, autre) :
        return self.numero () - autre.numero ()

def conversion_date (s) :
    res = []
    for jour,mois in s :
        res.append ( Date (jour, mois) )
    return res
    
def ecart_date (date) :
    ec = []
    for i in range (1, len (date)) :
        ec.append ( date [i].difference ( date [i-1] ) )
    return ec


# question 7
s = [ (1,1), (9,4), (1,5), (8,5), (17,5), (4,6), \
             (14,7), (15,8), (1,11), (11,11), (25,12) ]

r = conversion_date (s)
ec = ecart_date (r)
pos = ec.index ( max (ec) )
print "position de l'ecart le plus grand ", pos
print "jour ", s [pos], " --> ", s [pos+1]

# question 8
"""
La conversion en Date est faite une fois pour les dates (1,1) et (25,12) 
et 2 fois pour les autres en effet, la méthode difference effectue 
la conversion en numéros des dates self et autre
la fonction ecart_date calcule date [i].difference ( date [i-1] ) et 
                                         date [i+1].difference ( date [i] )
            --> la date [i] est convertie 2 fois
"""

# question 9
"""
On peut par exemple stocker la conversion en numéro 
dans le constructeur comme suit :
"""

class Date :
    def __init__ (self, jour, mois) :
        self.jour = jour
        self.mois = mois
        self.duree = [31, 28, 31,30,31,30,31,31,30,31,30,31]
        self.num = self.numero ()
        
    # question 5
    def numero (self) :
        s = 0
        for i in range (0,self.mois-1) :
            s += self.duree [i]
        s += self.jour - 1
        return s+1
        
    # question 6    
    def difference (self, autre) :
        return self.num - autre.num


r = conversion_date (s)
ec = ecart_date (r)
pos = ec.index ( max (ec) )
print "position de l'écart le plus grand ", pos
print "jour ", s [pos], " --> ", s [pos+1]

File: td_note_2008.tex, line 26


l = [ (1, "un"), (3, "deux",), (2, "deux"), (1, "hun"), (-1, "moinsun") ]
l.sort (reverse = True)
print l

File: td_note_2008.tex, line 34


[(3, 'deux'), (2, 'deux'), (1, 'un'), (1, 'hun'), (-1, 'moinsun')]

, correction 2008

# coding: latin-1
# la première ligne autorise les accents dans un programme Python
# la langue anglaise est la langue de l'informatique, 
# les mots-clés de tous les langages
# sont écrits dans cette langue.

####################################
# exercice 1
####################################
#

# question 1
def lit_fichier (file) :
    f = open (file, "r")
    li = f.readlines ()           # découpage sous forme de lignes
    f.close ()
    res = []
    for l in li :
        s = l.replace ("\n", "")
        s = s.split (" ")         # le séparateur des colonnes est l'espace
        res.append (s)
    return res
    
    
mat = lit_fichier ("logpdf.txt")
for m in mat [0:5] :       # on affiche les 5 premières lignes
    print m                # parce que sinon, c'est trop long
    
# question 2
def compte_date (mat) :
    d = { }
    for m in mat :
        date = m [1]   # clé
        if date in d : d [date] += 1
        else : d [date] = 1
    return d
       
dico_date = compte_date (mat)
print dico_date

# remarque générale : si le fichier logpdf.txt contient des lignes 
# vides à la fin, il se produira une erreur à la ligne 34 (date = m [1])
# car la matrice mat contiendra des lignes avec une seule colonne et non quatre.
# Il suffit soit de supprimer les lignes vides du fichier logpdf.txt
# soit de ne pas les prendre en compte lors de la lecture de ce fichier.

# question 3
# La méthode sort trie la liste mais comment ?
# Il est facile de trier une liste de nombres mais une liste de couples de 
# nombres ? L'exemple montre que la liste est triée selon le premier élément de 
# chaque couple. Pour les cas où deux couples ont un premier élément en commun, 
# les éléments semblent triés selon le second élément. L'exemple suivant le monte :

l = [(1, "un"), (3, "deux",), (2, "deux"), (1, "hun"), (1, "un"), (-1, "moinsun")]
l.sort (reverse = True)
print l  # affiche [(3, 'deux'), (2, 'deux'), (1, 'un'), 
         #          (1, 'un'),   (1, 'hun'), (-1, 'moinsun')]

# question 4
def dix_meilleures (dico) :
    # dans cette fonction on crée une liste de couples (valeur,clé) ou 
    # la clé représente une date et valeur le nombre de téléchargement 
    # pour cette date
    li = []
    for d in dico :
        cle = d
        valeur = dico [cle]
        li.append ( ( valeur, cle ) )
    li.sort (reverse = True)
    return li [0:10]
        
dix = dix_meilleures (dico_date)
print dix # la première date est (283, '26/Sep/2007')

# les quatre premières dates correspondent aux quatre premiers TD en 2007 à l'ENSAE

# question 5
# la date est en colonne 1, le document en colonne 3
# on fait un copier-coller de la fonction compte_date en changeant un paramètre
def compte_document (mat) :
    d = { }
    for m in mat :
        doc = m [3]   # clé, 3 au lieu de 1 à la question 2
        if doc in d : d [doc] += 1
        else : d [doc] = 1
    return d

dix = dix_meilleures ( compte_document (mat) )
print dix   # le premier document est 
            # (323, '/mywiki/Enseignements?.....target=python_cours.pdf'),

# question 6
def heure (s) :
    hs = s [0:2]           # on extrait la partie correspondant à l'heure
    return int (hs)        # on retourne la conversion sous forme d'entiers
    
# question 7
# on recommence avec un copier-coller
def compte_heure (mat) :
    d = { }
    for m in mat :
        h = m [2]   # clé, 2 au lieu de 1 à la question 2
        cle = heure (h)
        if cle in d : d [cle] += 1
        else : d [cle] = 1
    return d

h = compte_heure (mat)
dix = dix_meilleures ( h )
print dix   # la première heure est  (432, 17), ce qui correspond à l'heure des TD

for i in h :
    print i, "h  ", h [i]
    
# Il y a beaucoup plus de téléchargement entre 20h et 2h du matin 
# que le matin avant 10h.
# Le site est plutôt consulté le soir.
# La conclusion ne serait pas aussi évidente avec un site consulté par des gens
# du monde entier puisque 6h du matin est une heure de l'après midi au Japon.
# Il faudrait croiser l'heure avec la position géographique de la personne
# qui consulte le site.

File: td_note_2009.tex, line 22


pieces = [1,2,5,10,20,50]
...

File: td_note_2009.tex, line 45


pieces = [1,2,4,5,10,20,50]

, correction 2009

# coding: latin-1

###################################
# question 1 : retourner un tableau
###################################

pieces = [1,2,5,10,20,50]
pieces.reverse ()
print pieces # affiche [50, 20, 10, 5, 2, 1]

# il existait d'autres solutions
pieces.sort (reverse = True)

# ou encore l'utilisation d'une fonction compare modifiée 
# qui s'inspire de l'exemple 
# http://www.xavierdupre.fr/enseignement/initiation/... 
# ...initiation_via_python_ellipse/chap2_type_tex_-_tri-_3.html

# on encore un tri programmé
# http://www.xavierdupre.fr/enseignement/initiation/...
# ...initiation_via_python_ellipse/chap3_syntaxe_tex_-_tri-_27.html

##################################################################
# question 2 : trouve la plus grande pièce inférieure à un montant
##################################################################

def plus_grande_piece (montant, pieces) :
    # on suppose que les pièces sont triées par ordre décroissant
    
    for p in pieces :
        if p <= montant : return p
    
    # on peut ajouter la ligne
    return 0
    # qui correspond au fait qu'aucune pièce plus petite ou égale au montant
    # n'a été trouvé --> le montant est négatif ou nul

# on vérifie
print "plus_grande_piece (80, pieces) =", plus_grande_piece (80, pieces)  
                  # affiche 50

####################################
# question 3 : décomposer un montant
####################################

def decomposer (montant, pieces) :
    # on suppose que les pièces sont triées par ordre décroissant
    res = [ ]  # contiendra la liste des pièces pour le montant 
    while montant > 0 :
        p = plus_grande_piece (montant, pieces)  # on prend la plus grande pièce 
                                                 # inférieure ou égale au montant
        res.append (p)                           # on l'ajoute à la solution
        montant -= p                             # on ôté p à montant : 
                                       # c'est ce qu'il reste encore à décomposer
    return res
    
print "decomposer (98, pieces) =", decomposer (98, pieces)  
                # affiche [50, 20, 20, 5, 2, 1]
                
print "decomposer (99, pieces) =", decomposer (99, pieces)  
                # affiche [50, 20, 20, 5, 2, 2]
    
######################################################
# question 4 : trouver la décomposition la plus grande
######################################################

def maximum_piece (pieces) :
    # détermine le nombre maximum de pièces à utiliser
    maxi    = 0
    montant = 0
    for m in range (1, 100) :
        r = decomposer (m, pieces)    
        if len (r) >= maxi :    # si on remplace cette ligne par if len (r) > maxi :
            maxi    = len (r)   # on trouve le plus petit montant 
                                # avec la pire décomposition
            montant = m         # et non le plus grand montant 
                                # avec la pire décomposation
    return maxi, montant

print "maximum_piece (pieces) =", maximum_piece (pieces) # affiche (6, 99)

##################################
# question 5 : décomposition de 98
##################################

pieces4 = [1,2,4,5,10,20,50]
pieces4.reverse ()

print "decomposer (98, pieces) = ", decomposer (98, pieces)    # [50, 20, 20, 5, 2, 1]
print "decomposer (98, pieces4) = ", decomposer (98, pieces4)  # [50, 20, 20, 5, 2, 1]

"""
Les deux décompositions sont identiques. 
Or il existe une décomposition plus courte avec la pièce 4 :
98 = 50 + 20 + 20 + 4 + 4 = 5 pièces

L'algorithme fait la même erreur lorsqu'il décompose le montant 8. 
Il cherche toujours la plus grande pièce inférieure au montant qui est 5. 
Il lui est alors impossible d'utiliser la pièce 4  pour décomposer 8. 

Cet algorithme ne fournit pas la bonne solution avec ce nouveau jeu de pièces.
"""

#################################
# question 6 : algorithme optimal
#################################

# version récursive : très longue
def decomposer_optimal (montant, pieces) :
    if montant in pieces : 
        return [ montant ]
    else :
        r = [ 1 for m in range (0, montant) ]
        for p in pieces :
            if montant > p : # si ce test n'est pas fait, la récurrence peut être infinie
                             # car les montants négatifs ne sont pas pris en compte 
                             # par le premier test
                dec = decomposer_optimal (montant - p, pieces) + [p]
                if len (dec) < len (r) :
                    r = dec

        return r
        
# print "decomposer_optimal (98, pieces4) =", decomposer_optimal (98, pieces4)
# trop long
        
# version non récursive 
def decomposer_optimal (montant, pieces) :
    memo = [ [ 1 for l in range (0, m) ] for m in range (0, montant+1) ]
    # memo [i] contient la pire décomposition du montant i (que des pièces de un)
    
    # pour les pièces de pieces, on sait faire plus court
    for p in pieces :
        if p < len (memo) :
            memo [p] = [ p ]
        
    for m in range (1, montant+1) :
        for p in pieces :
            if m > p :
                # on calcule la nouvelle décomposition
                dec = [p] + memo [m-p] 
                # si elle est plus courte, on la garde
                if len (dec) < len (memo [m] ) :
                    memo [m] = dec
                    
    # on retourne la meilleur décomposition pour montant
    return memo [ montant ]

# beaucoup plus rapide
print "decomposer_optimal (98, pieces4) =",  decomposer_optimal (98, pieces4) 
             # affiche [50, 20, 20, 4, 4]


#######################
# question 7 : résultat
#######################


# pour trouver la décomposition la plus longue avec n'importe quel jeu de pièces
# on reprend la fonction maximum_piece et on remplace decomposer par decomposer optimale

def maximum_piece (pieces) :
    # détermine le nombre maximum de pièces à utiliser
    maxi    = 0
    montant = 0
    for m in range (1, 100) :
        r = decomposer_optimal (m, pieces)    
        if len (r) >= maxi :    # si on remplace cette ligne par if len (r) > maxi :
            maxi    = len (r)   # on trouve le plus petit montant 
                                # avec la pire décomposation
            montant = m         # et non le plus grand montant 
                                # avec la pire décomposation
    return maxi, montant

print "maximum_piece (pieces) =", maximum_piece (pieces) # affiche (6, 99)
print "maximum_piece (pieces4) =", maximum_piece (pieces4) # affiche (5, 99)


# on teste pour toutes les pièces [3,4,6,7,8,9] 
# ajoutées au jeu de pièces standard [1,2,5,10,20,50]
ensemble = [3,4,6,7,8,9]

for ajout in [3,4,6,7,8,9] :
    pieces = [1,2,5,10,20,50] + [ ajout ]
    pieces.sort (reverse = True)
    print "maximum_piece (" + str (pieces) + ") = ", maximum_piece (pieces)

# résultat :
"""
maximum_piece ([50, 20, 10, 5, 3, 2, 1]) =  (6, 99) 
maximum_piece ([50, 20, 10, 5, 4, 2, 1]) =  (5, 99)  # 4, ok
maximum_piece ([50, 20, 10, 6, 5, 2, 1]) =  (6, 99)
maximum_piece ([50, 20, 10, 7, 5, 2, 1]) =  (5, 99)  # 7, ok
maximum_piece ([50, 20, 10, 8, 5, 2, 1]) =  (5, 99)  # 8, ok
maximum_piece ([50, 20, 10, 9, 5, 2, 1]) =  (5, 98)  # 9, ok
"""


############################
# question 8 : décomposition
############################

"""
On cherche ici le coût de la fonction decomposer_optimal en fonction du montant.
Il n'y a qu'une seule boucle qui dépend du montant, le coût de la fonction est en O(n).

Dans la version récursive, le coût est le résultat d'une suite récurrente :
u(n) = u(n-1) + ... + u(n-d)
où d est le nombre de pièces.

Le coût est donc en O(a^n) où a est la plus grande des racines du polynôme :

P (x) = x^d - x^(d-1) - ... - 1

P(1) < 0 et lim P(x) = infini lorsque x tend vers infini, 
donc la plus grande des racines est supérieure à 1.
Le coût de la fonction decomposer_optimal récursive est en O(a^n) avec 1,96 < a < 1,97.

Pour des explications plus conséquentes, voir la page 
http://fr.wikipedia.org/wiki/Suite_r%C3%A9currente_lin%C3%A9aire 
sur les suites récurrentes et l'exercice 12.3.3 du livre :
http://www.xavierdupre.fr/enseignement/initiation/...
 ...initiation_via_python_ellipse.pdf
(ou 13.3.3 http://www.xavierdupre.fr/enseignement/...
 ...initiation/initiation_via_python_small.pdf).
"""

File: td_note_2009_rattrape.tex, line 37


N10   P10   gris     corde
N15   P15   rouge    chandelier
N8    P8    marron   fer à cheval

File: td_note_2009_rattrape.tex, line 54


N3    P3    cuisine
N19   P19   bureau
N20   P20   salle à manger

File: td_note_2009_rattrape.tex, line 65


def convertit_fichier_en_matrice (fichier) :
...

File: td_note_2009_rattrape.tex, line 77


def convertit_matrice_en_dictionnaire (matrice) :
...

File: td_note_2009_rattrape.tex, line 89


def fusion_dictionnaire (dico1, dico2) :

File: td_note_2009_rattrape.tex, line 98


def convertit_dictionnaire_en_matrice (dico) :

File: td_note_2009_rattrape.tex, line 106


def convertit_matrice_en_fichier (mat, fichier) :

File: td_note_2009_rattrape.tex, line 114


def fusion_fichier (fichier1, fichier2, fichier_resultat) :

File: td_note_2009_rattrape.tex, line 122


def union_moins_intersection_fichier (fichier1, fichier2, fichier_resultat) :

, correction 2009

# coding: latin-1
# Question 1

def convertit_fichier_en_matrice (file):
    f = open (file, "r") 
    l = f.readlines ()   
    f.close ()           

    mat = list()
    for s in l :
        l = s.strip ("\n\r").split ("\t")
        mat.append (l)
    return mat

# Question 2

def convertit_matrice_en_dictionnaire (matrice) :
    d={}
    for line in matrice :
        d[line[0],line[1]] = line [2:]
    return d

# Question 3

def fusion_dictionnaire (dico1, dico2) :
    dico={}
    for k in dico1 :
        if k in dico2 : dico[k] = dico1[k] + dico2[k]
    return dico

# Question 4

def convertit_dictionnaire_en_matrice (dico) :
    m =[]
    for k,v in dico.iteritems () :
        line = list (k) + v
        m.append (line)
    return m
            
# Question 5

def convertit_matrice_en_fichier (mat,nomfichier):
    f = open (nomfichier, "w")
    for line in mat :
        f.write ( "\t".join ( [ str (x) for x in line ] ) + "\n")
    f.close ()

# Question 6

def fusion_fichier (fichier1, fichier2, fichier_resultat) :
    matrice1    = convertit_fichier_en_matrice(fichier1)
    matrice2    = convertit_fichier_en_matrice(fichier2)
    dico1       = convertit_matrice_en_dictionnaire(matrice1)
    dico2       = convertit_matrice_en_dictionnaire(matrice2)
    dico        = fusion_dictionnaire (dico1,dico2)
    matrice     = convertit_dictionnaire_en_matrice(dico)
    convertit_matrice_en_fichier (matrice,fichier_resultat)

fusion_fichier (    "td_note_2009_cluedo_1.txt", 
                    "td_note_2009_cluedo_2.txt", 
                    "cluedo.txt")

# Question 7

def fusion_dictionnairebis (dico1,dico2) :
    l1=dico1.keys()
    l2=dico2.keys()
    dico={}
    for k in l1 :
        if k not in l2 : dico[k]=[]
    for k in l2 :
        if k not in l1 : dico[k]=[]
    return dico

def union_moins_intersection_fichier (fichier1, fichier2, fichier_resultat):
    matrice1    = convertit_fichier_en_matrice(fichier1)
    matrice2    = convertit_fichier_en_matrice(fichier2)
    dico1       = convertit_matrice_en_dictionnaire(matrice1)
    dico2       = convertit_matrice_en_dictionnaire(matrice2)
    
    dico        = fusion_dictionnairebis (dico1,dico2)
    
    matrice     = convertit_dictionnaire_en_matrice(dico)
    convertit_matrice_en_fichier (matrice,fichier_resultat)

union_moins_intersection_fichier (  "td_note_2009_cluedo_1.txt", 
                                    "td_note_2009_cluedo_2.txt", 
                                    "cluedo2.txt")

# Question 8
"""
Il suffit de fusionner les fichiers deux par deux 
en procédant par récurrence. On fusionne d'abord les
deux premiers, puis on fusionne le troisième 
au résultat de la première fusion...
"""

File: td_note_2010.tex, line 30


def sous_nuage (nb, x, y, v) :  # retourne une liste de 2-uples

File: td_note_2010.tex, line 35


def n_sous_nuages (n, nb) :     # retourne une liste de 2-uples

File: td_note_2010.tex, line 41


import matplotlib.pyplot as plt
x   = [ ... ]
y   = [ ... ]
fig = plt.figure()
ax  = fig.add_subplot(111)
ax.plot (x,y, 'o')
plt.savefig ("im1.png") # ou plt.show () pour afficher le graphe

File: td_note_2010.tex, line 52


def random_class (points, n) :  # retourne une liste d'entiers

File: td_note_2010.tex, line 67


def proche_barycentre (point, barycentres) :   # retourne un entier

File: td_note_2010.tex, line 72


def association_barycentre (points, barycentres) :  # retourne une liste d'entiers

File: td_note_2010.tex, line 82


def barycentre_classe (points, classes, numero_class) :   # retourne un 2-uple
def tous_barycentres  (points, classes) :       # retourne une liste de 2-uples

File: td_note_2010.tex, line 88


def nuees_dynamiques (points, nombre_classes) : # retourne une liste d'entiers

File: td_note_2010.tex, line 98


import matplotlib.pyplot as plt
x1  = [ ... ]
y1  = [ ... ]
x2  = [ ... ]
y2  = [ ... ]
fig = plt.figure()
ax  = fig.add_subplot(111)
ax.plot (x1,y1, 'o')
ax.plot (x2,y2, 'x')     # ligne ajoutée, 'x', 'bo', ...
plt.savefig ("im2.png")  # 'rx', 'go', 'gs', 'bs', ...

File: td_note_2010.tex, line 133


def n_sous_nuages (n, nb):
    m = []
    for i in range (0,n):
        x = 5*random.random()
        y = 5*random.random()
        d = sous_nuage(nb,x,y,1)
        m += d
    return m

File: td_note_2010.tex, line 146


def n_sous_nuages (n, nb):
    m = []
    for i in range (0,n):
        x = random.randint(0,20)
        y = random.randint(0,20)
        d = sous_nuage(nb,x,y,1)
        m += d
    return m

File: td_note_2010.tex, line 168


def n_sous_nuages (n, nb):
    m = []
    for i in range (0,n):
        x = random.gauss(0,1)
        y = random.gauss(0,1)
        d = sous_nuage(nb,x,y,1)
        m += d
    return m

File: td_note_2010.tex, line 191


def n_sous_nuages (n, nb):
    m = []
    for i in range (0,n):
        x = random.gauss(0,1)
        y = random.gauss(0,1)
        d = sous_nuage(nb,x,y,1)
        m +=  [ d ]                
           # le résultat n'est 
           # plus une liste
    return m

File: td_note_2010.tex, line 209


import matplotlib.pyplot as plt
x = [ p [0] for p in n_sous_nuages (3,50) ] 
y = [ p [1] for p in n_sous_nuages (3,50) ] 
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot (x,y, 'o' )
plt.savefig ("im1.png")

File: td_note_2010.tex, line 223


def random_class(l,n):
    l = []
    for i in range(0,len(l)):
        l += [ random.randint (1,n) ]
    return l

File: td_note_2010.tex, line 234


def random_class(l,n):
    l = []
    for i in range(0,len(l)):
        l += [ random.randint (0,n) ]
    return l

File: td_note_2010.tex, line 245


d= (  (p[0]-f[0])**2+(p[1]-f[1])**2 ) ** (1/2)

File: td_note_2010.tex, line 251


def proche_barycentre (point,barycentres):
    d=distance_euclidienne(point,barycentres[0])
    for i in range (0,len(barycentres)):
        if distance_euclidienne(point,barycentres[i])<=d: 
            d=distance_euclidienne(point,barycentres[i])
    return d

File: td_note_2010.tex, line 265


def barycentre_classe (points, classes, numero_class):
    x=0
    y=0
    for i in range (0,len(classes)):
        if classes[i]==numero_class:  # ligne importante
            l=point[i]
            x=x+l[0]
            y=y+l[1]
    c=[x/n,y/n]                       # ligne importante
    return c

File: td_note_2010.tex, line 284


def tous_barycentres (points,classes):
    c=[]
    for i in classes :   # or on a len(classes) == len(points)
        c+=[barycentre_classe (points,classes,i)]
    return c

File: td_note_2010.tex, line 294


def tous_barycentres (points,classes):
    c=[]
    mx=max(classes)        # il faut ajouter +1
    for i in range(0,mx) : 
        c+=[barycentre_classe (points,classes,i)]
    return c

File: td_note_2010.tex, line 309


def nuees_dynamiques (points,nombre_classes):
    l = random_class (points,nombre_classes)
    for j in range (0,10):
        c = tous_barycentres (points, l)
        a = association_barycentre (points,c)
                        # il faut ajouter ici l = a pour corriger la fonction
    return a

File: td_note_2010.tex, line 321


def nuees_dynamiques (points,nombre_classes):
    for j in range (0,10):
        l = random_class (points,nombre_classes)
        c = tous_barycentres (points, l)
        a = association_barycentre (points,c)
        l = a
    return a

File: td_note_2010.tex, line 333


def nuees_dynamiques (n,nb):
    for j in range (0,10):
        points = n_sous_nuage (n,nb)
        l = random_class (points,nombre_classes)
        c = tous_barycentres (points, l)
        a = association_barycentre (points,c)
        l = a
    return a

, correction 2010

# coding: latin-1
import random
import numpy

def dessin (nuage, image = None) :
    """dessine un nuage de points
    @param      nuage       le nuage de points
    @param      image       si None, on affiche le nuage au travers d'une fenêtre,
                            sinon, image correspond à un nom d'image 
                            sur disque dur qui contiendra le graphique final"""
    import matplotlib.pyplot as plt
    x = [ p[0] for p in nuage ]
    y = [ p[1] for p in nuage ]
    plt.clf ()
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot (x,y, 'o')
    if image == None :  plt.show ()
    else :              plt.savefig (image)
    
def dessin_classes (nuage, classes, image = None) :
    """dessine un nuage, donne des couleurs différentes
    selon que le point appartient à telle ou telle classes
    @param      nuage           nuage[i], c'est le point i
    @param      classes         classes [i] est la classe associée au point i
    @param      image           voir la fonction précédente
    """
    import matplotlib.pyplot as plt
    x = {}
    y = {}
    for i in range (0, len (nuage)) :
        cl = classes [i]
        if cl not in x : 
            x [cl] = []
            y [cl] = []
        x [cl].append ( nuage [i][0] )
        y [cl].append ( nuage [i][1] )
    plt.clf ()
    fig = plt.figure()
    ax = fig.add_subplot(111)
    for cl in x :
        ax.plot (x [cl], y [cl], "+")
    if image == None :  plt.show ()
    else :              plt.savefig (image)
        
def sous_nuage (nb, x, y) :
    """retourne un ensemble de points tirés aléatoirement selon
    une loi normale centrée autour du point x,y
    @param      nb              nombre de points
    @param      x               abscisse du centre
    @param      y               ordonnée du centre
    @return                     une liste de points ou matrice de deux colonnes
                                - la première correspond aux abscisses, 
                                - la seconde aux ordonnées
    """
    res = []
    for i in xrange (0, nb) :
        xx = random.gauss (0,1)
        yy = random.gauss (0,1)
        res.append ( [x+xx, y+yy] )
    return res
    
def n_sous_nuages (nb_class, nb_point) :
    """crée un nuage de points aléatoires 
    @param      nb_class        nombre de sous nuages
    @param      nb_point        nombre de points dans chaque sous nuage
    @return                     une liste de points ou matrice de deux colonnes
                                - la première correspond aux abscisses, 
                                - la seconde aux ordonnées"""
    res = []
    for c in xrange (0, nb_class) :
        x = random.gauss (0,1) * 5
        y = random.gauss (0,1) * 5
        res += sous_nuage (nb_point, x,y)
    return res
    
def random_class ( nuage, n) :  
    """choisis aléatoirement un entier pour chaque point du nuage
    @param      nuage           un nuage de points (matrice de deux colonnes)
    @param      n               nombre de classes
    @return                     une liste d'entiers
    """
    res = [ ]
    for p in nuage :
        c = random.randint (0, n-1)
        res.append (c)
    return res
    
def proche_barycentre (point, barycentres) :
    """détermine le barycentre le plus d'un point 
    @param      point           liste de 2 réels : [x,y]
    @param      barycentres     liste de n points = matrice de deux colonnes,
                                chaque ligne correspond à un barycentre
    @return                     un entier qui correspond à l'index
                                du barycentre le plus proche"""
    dmax = 1e6
    for i in range (0, len (barycentres)) :
        b  = barycentres [i]
        dx = point [0] - b [0]
        dy = point [1] - b [1]
        d  = (dx**2 + dy**2) ** 0.5
        if d < dmax :
            dmax = d
            m    = i
    return m
    
def association_barycentre (points, barycentres) :
    """détermine pour chaque point le barycentre le plus proche
    @param      points          nuage (matrice de deux colonnes)
    @param      barycentres     c'est aussi une matrice de deux colonnes mais
                                avec moins de lignes
    @return                     liste d'entiers, chaque entier
                                correspond à la classe du point points[i],
                                c'est-à-dire l'index du barycentre le plus proche
                                ici: 
                                point:      points [i]
                                classe:     res[i]
                                barycentre: barycentres[ res[i] ]
    """
    res = []
    for p in nuage :
        m = proche_barycentre (p, barycentres)
        res.append (m)
    return res
    
def barycentre_classe (points, classes, numero_class) :
    """calcule le barycentre d'une classe
    @param      points          ensemble de points (matrice de deux colonnes)
    @param      classes         liste d'entiers de même longueur, 
                                chaque élément classes[i] est la classe de point[i]
    @param      numero_class    classe pour laquelle on doit calculer le barycentre
    @return                     résultat barycentre x,y
    
    dans cette fonction, on doit calculer le barycentre d'une classe
    c'est-à-dire le barycentre des points points[i] 
    pour lesquelles classes[i] == numero_class
    """
    mx,my = 0.0,0.0
    nb    = 0
    for i in range (0, len (points)) :
        p = points [i]
        c = classes [i]
        if c != numero_class : continue
        nb += 1
        mx += p [0]
        my += p [1]
    return mx/nb, my/nb
    
def tous_barycentres (points, classes) :
    """calcule les barycentres pour toutes les classes
    @param      points      points, nuage, matrice de deux colonnes
    @param      classes     liste d'entiers
    @return                 liste de barycentre = matrice de deux colonnes 
    """
    mx          = max (classes)+1
    barycentre  = []
    for m in range (0,mx) :
        b = barycentre_classe (points, classes, m)
        barycentre.append (b)
    return barycentre
    
def numpy_tous_barycentres (points, classes) :
    """écriture de barycentre_classe et tous_barycentres
    en une seule fonction avec numpy
    """
    nbcl = max (classes)+1
    mat  = numpy.matrix (points)
    vec  = numpy.array ( classes )
    clas = numpy.zeros ( (len (points), nbcl) )
    for i in range (0, nbcl) : 
        clas [ vec == i, i ] = 1.0 
    nb   = clas.sum (axis = 0)
    for i in range (0, nbcl) : 
        clas [ vec == i, i ] = 1.0 / nb [i]
    ba = mat.transpose () * clas
    ba = ba.transpose ()
    ba = ba.tolist ()
    barycentre = [ b for b in ba ]
    return barycentre
    
def numpy_tous_barycentres2 (points, classes) :
    """écriture de barycentre_classe et tous_barycentres
    en une seule fonction avec numpy
    """
    nbcl        = max (classes)+1
    mat         = numpy.matrix (points)
    matt        = mat.transpose ()
    matcl       = numpy.matrix (classes).transpose ()
    barycentre  = []
    for c in xrange (0, nbcl) :
        w  = numpy.matrix (matcl)
        w [matcl==c] = 1
        w [matcl!=c] = 0
        wt = w.transpose ()
        r  = matt * w
        n  = wt * w
        r /= n [0,0]
        barycentre += [ [ r [0,0], r [1,0] ] ]
        
    return barycentre
    
def nuees_dynamiques (points, nbcl) :
    """algorithme des nuées dynamiques
    @param      points          ensemble points = matrice de deux colonnes
    @param      nbcl            nombre de classes demandées
    @return                     un tableau incluant la liste d'entiers
    """
    classes = random_class (points, nbcl)
    
    # on a le choix entre la version sans numpy
    for i in range (0,10) :
        print "iteration",i, max (classes)+1
        barycentres = tous_barycentres (points, classes)        # ou l'un
        classes     = association_barycentre (points, barycentres)
    cl1 = classes
    
    # ou la première version avec numpy
    for i in range (0,10) :
        print "iteration",i, max (classes)+1
        barycentres = numpy_tous_barycentres (points, classes)  # ou l'autre
        classes     = association_barycentre (points, barycentres)
    cl2 = classes
    
    # ou la seconde version avec numpy
    for i in range (0,10) :
        print "iteration",i, max (classes)+1
        barycentres = numpy_tous_barycentres2 (points, classes)  # ou l'autre
        classes     = association_barycentre (points, barycentres)
    cl3 = classes
    
    # on doit trouver cl1 == cl2 == cl3
    if cl1 != cl2 or cl1 != cl3 :
        print "erreur de calculs dans l'une des trois fonctions"
    return classes
            
# début du programme : on construit un nuage de points
nuage = n_sous_nuages (3, 50)
# on appelle l'algorithme
classes = nuees_dynamiques (nuage, 3)
# on dessine le résultat
dessin_classes (nuage, classes)

File: td_note_2010_rattrape.tex, line 73


[['Auxerre', 3.537309885, 47.767200469999999], 
 ['Bastia', 9.4343004229999998, 42.661758419999998], 
 ...         

File: td_note_2010_rattrape.tex, line 81


def get_tour () :
    stour = """Auxerre	3,537309885	47,76720047
Bastia	9,434300423	42,66175842
Bordeaux	-0,643329978	44,80820084"""
    ...
    return tour

File: td_note_2010_rattrape.tex, line 93


def distance (tour, i,j) :
    ...
    return d

File: td_note_2010_rattrape.tex, line 101


def longueur_tour (tour) :
    ...
    return d

File: td_note_2010_rattrape.tex, line 109


import pylab
def graph (tour) :
    x = [ t[1] for t in tour ]
    y = [ t[2] for t in tour ]
    ....
    ....
    pylab.plot (x,y)
    for ville,x,y in tour :
        pylab.text (x,y,ville)
    pylab.show ()

File: td_note_2010_rattrape.tex, line 132


def permutation (tour) :

File: td_note_2010_rattrape.tex, line 164


def retourne (tour, i,j) :

File: td_note_2010_rattrape.tex, line 171


def croisement (tour) :

File: td_note_2010_rattrape.tex, line 177


def resoud_et_dessine (tour) :

, correction 2010

# coding: latin-1
import random, numpy, math, pylab, copy

###
### réponse à la question 1
###

def get_tour () :
    tour = """Auxerre	3,537309885	47,76720047
Bastia	9,434300423	42,66175842
Bordeaux	-0,643329978	44,80820084
Boulogne	1,579570055	50,70875168
Caen	-0,418989986	49,14748001
Le Havre	0,037500001	49,45898819
Lens	2,786649942	50,40549088
Lille	2,957109928	50,57350159
Lyon	4,768929958	45,70447922
Paris	2,086790085	48,65829086
Lyon	4,768929958	45,70447922
Marseille	5,290060043	43,1927681
Lille	2,957109928	50,57350159
Nantes	-1,650889993	47,16867065
Rennes	-1,759150028	48,05683136
Toulouse	1,356109977	43,5388298
Strasbourg	7,687339783	48,49562836
Nancy	6,134119987	48,66695023
Nice	7,19904995	43,6578598
Saint-Etienne	4,355700016	45,39992905
Brest	-4,552110195	48,36014938
Metz	6,11729002	49,0734787
Sedan	4,896070004	49,68407059
Grenoble	5,684440136	45,13940048
Annecy	6,082499981	45,8782196""".replace (",", ".").split ("\n")
    # ligne d'avant : on découpe l'unique chaîne de caractères
    
    # ligne suivant : on découpe chaque ligne en colonne
    tour = [ t.strip ("\r\n ").split ("\t") for t in tour ]
    # puis on convertit les deux dernières colonnes
    tour = [ t [:1] + [ float (x) for x in t [1:] ] for t in tour ]
    return tour

###
### réponse à la question 2
###

def distance (tour, i,j) :
    dx = tour [i][1] - tour [j][1]
    dy = tour [i][2] - tour [j][2]
    return (dx**2 + dy**2) ** 0.5
    
###
### réponse à la question 3
###

def longueur_tour (tour) :
    # n villes = n segments
    d = 0
    for i in xrange (0,len(tour)-1) :
        d += distance (tour, i,i+1)
    # il ne faut pas oublier de boucler pour le dernier segment
    d += distance (tour, 0,-1)       
    return d
    
###
### réponse à la question 4
###

def graph (tour) :
    x = [ t[1] for t in tour ]
    y = [ t[2] for t in tour ]
    x += [ x [0] ]   # on ajoute la dernière ville pour boucler
    y += [ y [0] ]   #
    pylab.plot (x,y)
    for ville,x,y in tour :
        pylab.text (x,y,ville)
    pylab.show ()
    
###
### réponse à la question 5
###

def permutation (tour) :
    
    # on calcule la longueur du tour actuelle
    best  = longueur_tour (tour)
    
    # variable fix : dit combien d'échanges ont eu lieu depuis la 
    # dernière amélioration
    fix   = 0
    while True :
        # on tire deux villes au hasard
        i = random.randint (0, len(tour)-1)
        j = random.randint (0, len(tour)-1)
        if i == j : continue
            
        # on les échanges si i != j
        e = tour [i]
        tour [i] = tour [j]
        tour [j] = e
        
        # on calcule la nouvelle longueur
        d = longueur_tour (tour)
        
        if d >= best :
            # si le résultat est plus long --> retour en arrière
            # ce qui consiste à échanger à nouveau les deux villes
            fix += 1
            e = tour [i]
            tour [i] = tour [j]
            tour [j] = e
        else :
            # sinon, on garde le tableau tel quel
            best = d
            # et on met fix à 0 pour signifier qu'une modification a eu lieu
            fix = 0
            
        # si aucune modification n'a eu lieu durant les dernières 10000 itérations,
        # on s'arrête
        if fix > 10000 : break
            
###
### réponse à la question 6
###

def retourne (tour, i,j) :
    """
    on échange les éléments i et j
    puis i+1 et j-1
    puis i+2 et j-2
    tant que i+k < j-k 
    """
    while i <= j :
        e = tour [i]
        tour [i] = tour [j]
        tour [j] = e
        i += 1
        j -= 1

###
### réponse à la question 7
###

def croisement (tour) :
    """
    cette fonction reprend le même schéma que la fonction permutation
    on annule une modification en appelant à nouveau la fonction retourne
    """
    best  = longueur_tour (tour)
    fix   = 0
    while True :
        i = random.randint (0, len(tour)-2)
        j = random.randint (i+1, len(tour)-1)
        retourne (tour, i,j)
        d = longueur_tour (tour)
        if d >= best :
            # retour en arrière
            fix += 1
            retourne (tour, i,j)
        else :
            fix = 0
            best = d
        if fix > 10000 : break
            
###
### réponse à la question 8
###

def enchaine (tour) :
    """
    cette fonction est plus complexe que le résultat demandé pour cette question
    on enchaîne les deux fonctions (croisement, permutation) tant que
    la longueur du circuit diminue
    
    et si jamais cette longueur ne diminue plus, on perturbe le circuit 
    au plus deux fois
    en échangeant trois couples de villes choisies au hasard,
    cette dernière partie n'était pas prévue dans l'énoncé
    """
    best = longueur_tour (tour)
    tttt = copy.deepcopy (tour)
    print "debut", best
    nom  = 0
    while True :
        
        croisement (tour)
        d = longueur_tour (tour)
        print "croisement", d, best
        
        permutation (tour)
        d = longueur_tour (tour)
        print "permutation", d, best
        
        if d < best :
            best = d
            tttt = copy.deepcopy (tour)
            nom  = 0
        elif nom > 2 :
            break
        else :
            nom += 1
            for k in range (0,3) :
                i = random.randint (0, len(tour)-2)
                j = random.randint (i+1, len(tour)-1)
                e = tour [i]
                tour [i] = tour [j]
                tour [j] = e
            
    return tttt
            
if __name__ == "__main__" :
    tour = get_tour ()
    tour = enchaine (tour)
    graph (tour)

File: td_note_2011.tex, line 45


75002    2.407478    48.930141         75010    2.405963    48.921033
75002    2.400573    48.913487         75018    2.391144    48.934509

, correction 2011

# coding: latin-1
import urllib2, math

# question 1
def lit_fichier () :
    # le principe est le même que pour le chargement d'un fichier
    # le programme lit directement les informations depuis Internet
    f = urllib2.urlopen ("http://www.xavierdupre.fr/enseignement"\
                         "/examen_python/restaurant_paris.txt")
    s = f.read ()
    f.close ()
    lines = s.split ("\n")  # on découpe en lignes
    # on découpe en colonnes
    lines = [ _.strip ("\n\r ").split ("\t") for _ in lines if len (_) > 0 ]  
    lines = [ _ for _ in lines if len (_) == 3 ]  # on supprime les lignes vides
    # on convertit les coordonnées en réel
    lines = [ (a [3:], float (b), float (c)) for a,b,c in lines ]
    return lines
    
# question 2
def compte_restaurant (mat) :
    # simple comptage, voir le chapitre 3...
    compte = { }
    for cp,x,y in mat :
        if cp not in compte : compte [cp] = 0
        compte [cp] += 1
    return compte
    
# question 3
def barycentre (mat) :
    # un barycentre est un point (X,Y)
    # où X et Y sont respectivement la moyenne des X et des Y
    barycentre = { }
    # boucle sur la matrice
    for cp,x,y in mat :
        if cp not in barycentre : barycentre [cp] = [ 0, 0.0, 0.0 ]
        a,b,c           = barycentre [cp]
        barycentre [cp] = [a+1, b+x, c+y]
    # boucle sur les barycentres
    for cp in barycentre :
        a,b,c = barycentre [cp]
        barycentre [cp] = [b/a, c/a]
        
    # le coût de cette fonction est en O (n log k)
    # où k est le nombre de barycentre
    # de nombreux élèves ont deux boucles imbriquées, 
    # d'abord sur la matrice, ensuite sur les barycentres
    # ce qui donne un coût en O (nk), beaucoup plus grand
    return barycentre
    
# question 4 
def distance (x1, y1, x2, y2) :
    return ((x1-x2)**2 + (y1-y2)**2)**0.5

# question 5
def plus_proche_restaurant (x,y, arr, mat) :
    m,mx,my = None, None, None
    for cp,a,b in mat :
        if cp != arr and (m == None or distance (a,b,x,y) < m) :
            mx,my = a,b
            m     = distance (a,b,x,y)
    return mx,my
    
# question 6
def densite_approchee (mat) :
    g      = barycentre (mat)
    compte = compte_restaurant (mat)
    res    = { }
    
    for cp in g :
        out  = plus_proche_restaurant (g [cp][0], g [cp][1], cp, mat)
        r    = distance (g [cp][0], g [cp][1], out [0], out [1])
        aire = math.pi * r ** 2
        res [cp] = compte [cp] / aire
        
    return res
    
if __name__ == "__main__" :
    
    if False :  #mettre à vrai pour remplacer la fonction plus_proche_restaurant
        # ajout par rapport à l'énoncé
        # en réponse à la dernière question
        # plutôt que de prendre le premier point à hors de l'arrondissement
        # on considère celui correspondant à un quantile (5%)
        # ce qui évite les quelques restaurants dont les données
        #sont erronées
        def plus_proche_restaurant_avec_amelioration (x,y, arr, mat) :
            all     = []
            for cp,a,b in mat :
                if cp != arr :
                    m = distance (a,b,x,y)
                    all.append ( (m,a,b))
            all.sort ()
            a,b = all [len(all)/20][1:]
            return a,b
            
        # ajout par rapport à l'énoncé
        plus_proche_restaurant = plus_proche_restaurant_avec_amelioration
    
    mat = lit_fichier ()
    com = densite_approchee (mat)
    ret = [ (v,k) for k,v in com.iteritems () ]
    ret.sort ()
    for a,b in ret : print "%d\t%s" % (a,b)
        
    # ajout par rapport à l'énoncé
    # permet de dessiner les restaurants, une couleur par arrondissement
    # on observe que certains points sont aberrants, ce qui réduit d'autant 
    # l'estimation du rayon d'un arrondissement (il suffit qu'un restaurant 
    # étiquetés dans le 15ème soit situé près du barycentre du 14ème.)
    import matplotlib
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.mlab as mlab
    import matplotlib.cbook as cboo

    fig = plt.figure()
    ax = fig.add_subplot(111)
    colors = [  'red', 'blue', 'yellow', 'orange', 'black', 'green', 
                'purple', 'brown', 'gray', 'magenta', 'cyan', 'pink', 'burlywood',
                'chartreuse', '#ee0055']
    for cp in barycentre (mat) :
        lx = [ m[1] for m in mat if m [0] == cp ]
        ly = [ m[2] for m in mat if m [0] == cp ]
        c  = colors [ int(cp) % len (colors) ]
        #if cp not in ["02", "20"] : continue
        ax.scatter(lx,ly, s = 5., c=c,edgecolors = 'none'  )
    plt.show ()
        
        
        
    

, énoncé 2012

#coding:latin-1
import urllib, os, os.path, numpy
def charge_donnees (nom = "donnees_enquete_2003_television.txt") :
    if os.path.exists (nom) :
        # si le fichier existe (il a déjà été téléchargé une fois)
        f = open (nom, "r")
        text = f.read ()
        f.close ()
    else :
        # si le fichier n'existe pas
        link = "http://www.xavierdupre.fr/enseignement/td_python/" + \
                 "python_td_minute/data/examen/" + nom
        url = urllib.urlopen (link)
        text = url.read ()
        # on enregistre les données pour éviter de les télécharger une seconde fois
        f = open (nom, "w")
        f.write (text)
        f.close ()
        
    lines = text.split ("\n")
    lines = [ l.split("\t") for l in lines if len(l) > 3 ]
    lines = [ [ "0" if s.strip() == "" else s for s in l ] for l in lines ]
    return lines
    
donnees = charge_donnees ()

colonne = donnees [0]
matrice = numpy.array (donnees [1:], dtype=float)
 
# quelques exemples d'utilisation du module numpy
petite_matrice = matrice [0:5,2:4]
print petite_matrice

# dimension d'une matrice
print petite_matrice.shape

# multiplication terme à terme
vecteur = petite_matrice [:,0] * petite_matrice [:,1]
print vecteur

# sum
print vecteur.sum ()

# changer une valeur selon une condition
petite_matrice [ petite_matrice [:,1] == 1, 1] = 5
print petite_matrice

# ne conserver que certaines lignes de la matrice
m = petite_matrice [ petite_matrice[:,1] == 5,: ]
print m

# créer une matrice 10x2 avec des zéros
m = numpy.zeros( (10,2) )

# trier les lignes selon la première colonne
tr = numpy.sort (petite_matrice, 0)


# dessiner deux courbes
def dessin_temperature (temperature) :
    import pylab
    u = [ t[3] for t in temperature ]
    v = [ t[4] for t in temperature ]
    pylab.plot (u)
    pylab.plot (v)
    pylab.show()   

File: td_note_2012.tex, line 41


POIDLOG       POIDSF         cLT1FREQ  cLT2FREQ
0.8894218317  4766.8652013   2         1
2.740069772   14685.431344   6         2

File: td_note_2012.tex, line 106


temperature = charge_donnees("cannes_charleville_2010_max_t.txt")

File: td_note_2012.tex, line 119


def dessin_temperature (temperature) :
    import pylab
    u = [ t[3] for t in temperature ]
    v = [ t[4] for t in temperature ]
    pylab.plot (u)
    pylab.plot (v)
    pylab.show()

, correction 2012

# coding: latin-1
# ce fichier contient le programme fournit au début de l'examen
# http://www.xavierdupre.fr/enseignement/examen_python/python_examen_2011_2012.py
from td_note_2012_enonce import *
import numpy, pylab

########################################################################
# exercice 1
########################################################################

# question 1 (+1=1p)
donnees = charge_donnees ()
colonne = donnees [0]
matrice = numpy.array (donnees [1:], dtype=float)

mat     = matrice
mat     = mat [ mat [:,3] > 0, : ]

# question 2 (+1=2p)
mat [ mat[:,3] == 1, 3 ] = 24
mat [ mat[:,3] == 2, 3 ] = 24*7
mat [ mat[:,3] == 3, 3 ] = 24*30

# question 3 (+1=3p)
res = mat [:,2] / mat [:,3]
print res.sum() / res.shape [0]       # 0.111 ~ 11,1% du temps passé devant la télévision
print res.sum() / res.shape [0] * 24  # soit 2h40min

# question 4 (+2=5p)
m = mat[:,1] * mat[:,2] / mat[:,3]
print m.sum() / mat[:,1].sum()        # 0.108 ~ 10,8%

# question 5 (+1=6p)
m = mat[ mat[:,2] > mat[:,3], : ]
print m  # il y a deux personnes et la raison la plus probable est une erreur dans l'unité de temps

# question 6 (+2=8p)
res = numpy.sort (res, 0)
print res[res.shape[0]/2]   # 0.083 ~ 8.3% = 2h

# question 7 (+2=10p)
pr = numpy.zeros ((mat.shape[0],4)) 
pr [:,0] = mat[:,2] / mat[:,3]
pr [:,1] = mat[:,1]
pr [:,2] = pr[:,0] * pr[:,1]
pr = numpy.sort (pr, 0)
total = pr[:,2].sum()
pr[0,3] = pr [0,2] 
for i in xrange (1, pr.shape[0]) :
    pr[i,3] = pr[i-1,3] + pr[i,2]
    if pr[i,3]/total > 0.5 :
        fin = i
        break
print pr[fin,3] / pr[:fin+1,1].sum()  # 0.0895 ~ 8.95%
    
########################################################################
# exercice 2
########################################################################

# question 1 (+1=1p)
temperature = charge_donnees("cannes_charleville_2010_max_t.txt")

def conversion_reel (temperature) :
    return [ [ float (x) for x in l ] for l in temperature [1:] ]

temperature = conversion_reel(temperature)

#question 2  (+2=3p)
def valeur_manquante (temperature, c) :
    for i in xrange (1, len (temperature)-1) :
        if temperature [i][c] == -1000 :
            temperature [i][c] = (temperature [i-1][c] + temperature [i+1][c]) / 2

valeur_manquante(temperature, 3)
valeur_manquante(temperature, 4)

def dessin_temperature (temperature) :
    import pylab
    u = [ t[3] for t in temperature ]
    v = [ t[4] for t in temperature ]
    pylab.plot (u)
    pylab.plot (v)
    pylab.show()

# on met en commentaire pour éviter de l'exécuter à chaque fois
# dessin_temperature(temperature)

# question 3 (+1=4p)

def distance (u,t) :
    return (u-t)**2
    
# question 4 (+3=7p)

def somme_ecart (temperature, t1, t2, T) :
    s = 0
    for i in xrange (0, len(temperature)) :
        if t1 < i < t2 :
            s += distance (temperature[i][3], T) # charleville
        else :
            s += distance (temperature[i][4], T) # cannes
    return s

# question 5 (+3=10p)

def minimisation (temperature, T) :
    best = 1e10
    t1t2 = None
    for t1 in xrange (0,len(temperature)) :
        for t2 in xrange (t1+1,len(temperature)) :
            d = somme_ecart(temperature,t1,t2,T)
            if best == None or d < best :
                best = d
                t1t2 = t1,t2
    return t1t2, best
    
#for i in range (300,363) : print "*",somme_ecart (temperature, i, i+2, 20)
print temperature [191]
print temperature [266]
for T in range (15, 25) :
    print T, "**",minimisation (temperature,T) # (191 = 11/7, 266 = 24/9)  (attendre 2 minutes)

# question 6
# Le coût de l'algorithme est on O(n^2) car l'optimisation est une double boucle sur les températures.
# Passer des jours aux semaines, c'est utiliser des séries 7 fois plus courtes, 
# l'optimisation sera 7^2 fois plus rapide.

, correction 2012

# coding: latin-1
# question 1
def frequence_lettre (mot) :
    res = { }
    for c in mot :
        if c in res : res[c] += 1
        else : res [c] = 1
    return res
    
print frequence_lettre ("aviateur")
# affiche {'a': 2, 'e': 1, 'i': 1, 'r': 1, 'u': 1, 't': 1, 'v': 1}

# Deux autres écritures de la fonction
def frequence_lettre (mot) :
    res = { c:0 for c in mot }
    for c in mot : res[c] += 1
    return res
    
def frequence_lettre (mot) :
    res = { }
    for c in mot : 
        # la méthode get retourne res[c] si cette valeur existe, 0 sinon
        res[c] = res.get( c, 0 ) + 1
    return res
    
# question 2

def anagramme (mot1, mot2) :
    h1 = frequence_lettre(mot1)
    h2 = frequence_lettre(mot2)
    
    # il fallait éviter d'écrire la ligne suivante bien qu'elle retourne le résultat cherché :
    # return h1 == h2
    
    for c in h1 :
        if c not in h2 or h1[c] != h2[c] : return False
    # il ne faut pas oublier cette seconde partie
    for c in h2 :
        if c not in h1 : return False
    return True
    
a,b = "anagramme", "agrammane"
print anagramme (a,b), anagramme (b,a) # affiche True, True

# on vérifie que la fonctionne marche aussi dans l'autre cas
a,b = "anagramme", "agrummane"
print anagramme (a,b), anagramme (b,a) # affiche False, False

# on pouvait faire plus rapide en éliminant les cas évidents
def anagramme (mot1, mot2) :
    if len(mot1) != len(mot2) : return False
    h1 = frequence_lettre(mot1)
    h2 = frequence_lettre(mot2)
    if len(h1) != len(h2) : return False

    for c in h1 :
        if h1[c] != h2.get(c, 0) : return False
    return True

, correction 2012

# coding: latin-1

# question 1

def factorielle (n) :
    res = 1
    while n > 1 : 
        res *= n
        n -= 1
    return res
    
print factorielle (3)
    
# voici la version récursive qui n'était pas demandée :    
def factorielle_recursive (n) :
    return n*factorielle_recursive (n-1) if n > 1 else 1
        
# question 2

def f(a,b) :
    
    # f(a,b) = f(a-1,b) + f(a,b-1)
    # la formule implique de calculer toutes les valeurs f(i,j)
    # avec (i,j) dans [[0,a]] x [[0,b]]
    # un moyen afin d'éviter de trop nombreux calculs est de 
    # stocker les valeurs intermédiaires de f dans une matrice
    # il faut ensuite s'assurer que f(a-1,b) et f(a,b-1) 
    # ont déjà été calculées avant de calculer f(a,b)
    # pour cela, on parcourt la matrice dans le sens des i et j croissants
    # il ne faut pas oublier les a+1,b+1 car range (a) est égal à [ 0,1, ..., a-1 ]
    
    mat = [ [ 0 for i in range (b+1) ] for j in range (a+1) ]
    for i in range (a+1) :
        for j in range (b+1) :
                if i == 0 or j == 0 :
                    mat [i][j] = max (i,j)
                else :
                    mat [i][j] = mat [i-1][j] + mat[i][j-1]
    return mat [a][b]

# on teste pour des valeurs simples
print f(0,5) # affiche 5
print f(1,1) # affiche 2
# on vérifie en suite que cela marche pour a < b et b > a
print f (4,5)  # affiche 210
print f (5,4)  # affiche 210

# autres variantes

# la version récursive ci-dessous est juste beaucoup plus longue, elle appelle
# la fonction f_recursive autant de fois que la valeur retournée 
# par la fonction cout_recursive alors que la fonction précédente 
# effectue de l'ordre de O(a*b) calculs
def f_recursive(a,b) :
    return f_recursive(a-1,b) + f_recursive(a,b-1) if a > 0 and b > 0 else max(a,b)

def cout_recursive(a,b) :
    return cout_recursive(a-1,b) + cout_recursive(a,b-1) if a > 0 and b > 0 else 1

# une autre version non récursive
def f(a,b) :
    mat = { }
    for i in range (a+1) :
        for j in range (b+1) :
                mat [i,j] = mat [i-1,j] + mat[i,j-1] if i > 0 and j > 0 else max (i,j)
    return mat [a,b]

, correction 2012

def f_recursive(a,b, memoire) :
    if (a,b) in memoire : return memoire [a,b]
    else : 
        res = f_recursive(a-1,b, memoire) + f_recursive(a,b-1, memoire) \
                    if a > 0 and b > 0 else max(a,b)
        memoire [a,b] = res
        return res

, correction 2012

# coding: latin-1

# question 1

def somme_partielle (li, i, j) :
    r = 0
    for a in range (i,j) :
        r += li [a]
    return r
    
# question 2

def plus_grande_sous_liste (li) :
    meilleur = min(li)               # ligne A
    im,jm = -1,-1
    for i in range (0,len(li)) :
        for j in range (i+1, len(li)+1) :   # ne pas oublier +1 car sinon
                        # le dernier élément n'est jamais pris en compte
            s = somme_partielle(li, i,j)
            if s > meilleur :
                meilleur = s
                im,jm = i,j
    return li [im:jm]
    
# si li ne contient que des valeurs positives, la solution est évidemment la liste entière
# c'est pourquoi il faut tester cette fonction avec des valeurs négatives
li = [ 4,-6,7,-1,8,-50,3]
m  = plus_grande_sous_liste(li)
print(m)   # affiche [7, -1, 8]

li = [1,2,3,4,5,-98,78,9,7,7]
m  = plus_grande_sous_liste(li)
print(m)   # affiche [79, 9, 7, 7]

# autre version plus courte

def plus_grande_sous_liste (li) :
    solution = [ (somme_partielle(li,i,j), i, j) \
                    for i in range (0,len(li)) \
                    for j in range (i+1, len(li)+1) ]
    m = max(solution)
    return li [m[1]:m[2]]

, correction 2012

def plus_grande_sous_liste_n2 (li) :
    meilleur = 0
    im,jm = -1,-1
    for i in range (0,len(li)) :
        s = 0
        for j in range (i, len(li)) :
            s += li[j]
            if s > meilleur :
                meilleur = s
                im,jm = i,j+1
    return li [im:jm]
    
li = [ 4,-6,7,-1,8,-50,3]
m  = plus_grande_sous_liste_n2(li)
print(m)   # affiche [7, -1, 8]

li = [1,2,3,4,5,-98,78,9,7,7]
m  = plus_grande_sous_liste_n2(li)
print(m)   # affiche [79, 9, 7, 7]    

, correction 2012

#coding:latin-1
def plus_grande_sous_liste_rapide_r (li, i,j) :
    if i == j : return 0
    elif i+1 == j : return li[i],i,i+1
    
    milieu = (i+j)//2
    
    # on coupe le problème deux
    ma,ia,ja = plus_grande_sous_liste_rapide_r (li, i, milieu)
    mb,ib,jb = plus_grande_sous_liste_rapide_r (li, milieu, j)
    
    # pour aller encore plus vite dans un cas précis
    if ja == ib :
        total = ma+mb
        im,jm = ia,jb
    else :
        # on étudie la jonction
        im,jm = milieu,milieu+1
        meilleur = li[milieu]
        s = meilleur
        for k in range (milieu+1, j) :
            s += li[k]
            if s > meilleur :
                meilleur = s
                jm = k+1
                
        total = meilleur
        meilleur = li[milieu]
        s = meilleur
        for k in range (milieu-1, i-1, -1) :
            s += li[k]
            if s > meilleur :
                meilleur = s
                im = k
        
        total += meilleur - li[milieu]
            
    if   ma >= max(mb,total) : return ma,ia,ja
    elif mb >= max(ma,total) : return mb,ib,jb
    else : return total,im,jm
        
def plus_grande_sous_liste_rapide (li) :
    m,i,j = plus_grande_sous_liste_rapide_r (li,0,len(li))
    return li[i:j]
        
li = [ 4,-6,7,-1,8,-50,3]
m  = plus_grande_sous_liste_rapide(li)
print(m)   # affiche [7, -1, 8]

li = [1,2,3,4,5,-98,78,9,7,7]
m  = plus_grande_sous_liste_rapide(li)
print(m)   # affiche [79, 9, 7, 7]    

, correction 2012

#-*- coding: latin-1 -*-
def plus_grande_sous_liste_n (li) :
    meilleur = [ None for i in li ]
    somme    = [ None for i in li ]
    best     = None
        
    for i,el in enumerate(li):
        if i == 0 or meilleur[i-1] is None:
            meilleur[i] = i
            somme[i] = el
            if best is None or somme[i] > somme[best]:
                best = i
        else:
            if el >= 0 or somme[i-1] > -el :
                meilleur[i] = meilleur[i-1] 
                somme[i] = somme[i-1] + el
                if best is None or somme[i] > somme[best]:
                    best = i
                
    i,j = meilleur[best], best+1
    return li [i:j]
    
li = [ 4,-6,7,-1,8,-50,3]
m  = plus_grande_sous_liste_n(li)
print(m)   # affiche [7, -1, 8]

li = [1,2,3,4,5,-98,78,9,7,7]
m  = plus_grande_sous_liste_n(li)
print(m)   # affiche [79, 9, 7, 7]    

File: td_note_2013_preparation.tex, line 25


import random
i = random.randint(0,5)

, correction 2013

#coding:latin-1
import random

# question 1
def sequence () :
    res = [ ]
    nb = 1
    while nb > 0 :
        i = random.randint(0,2)
        nb += i - 1
        res.append (i)
    return res

# question 2
def moyenne (nb_tirage) :
    somme = 0.0
    for i in range(nb_tirage) :
        s = sequence()
        somme += len(s)
    return somme / nb_tirage
    
s = sequence ()
print len(s),s
m = moyenne (100)
print m

, correction 2013

#coding:latin-1
import random

def randomint (a,b,c) :
    x = random.random()
    if x <= a : return 0
    elif x <= a+b : return 1
    else : return 2

def sequence (a,b,c) :
    res = [  ]
    nb = 1
    while nb > 0 :
        i = randomint(a,b,c)
        nb += i - 1
        res.append (i)
    return res

def moyenne (nb_tirage,a,b,c) :
    somme = 0.0
    for i in range(nb_tirage) :
        s = sequence(a,b,c)
        somme += len(s)
    return somme / nb_tirage
    
a,c = 0.3, 0.2
b = 1-a-c

moy = 1.0 / (a-c)
print "calcul",moy

m1 = moyenne (100000, a,b,c)
print "simulée", m1

, correction 2013

#coding:latin-1
import random, math

# question 1
def calcul_suite_a (n, e, a,b,c) :
    p = {}
    p [0,0]  = 1
    for u in range (1,n+1) :
        for k in range (e,u+2) :
            if   k == e   : p [u,k] = a * p.get ( (u-1,k+1), 0 )
            elif k == e+1 : p [u,k] = a * p.get ( (u-1,k+1), 0 ) + \
                                      b * p.get ( (u-1,k  ), 0 )
            elif k >  e+1 : p [u,k] = a * p.get ( (u-1,k+1), 0 ) + \
                                      b * p.get ( (u-1,k  ), 0 ) + \
                                      c * p.get ( (u-1,k-1), 0 )
    return p
    
def affiche_proba (ps, e) :
    n     = max ( [ k[1] for k,z in ps.iteritems () ] )
    moy = 0.0
    logru = []
    logu  = []
    for u in range (1, n+1) :
        p = ps.get((u,e),0)*1.0 
        moy += p * u
        mes = "u % 3d P(U=u) %1.6g r_u %1.6g" % (u, p, moy)
        if u < 3 or u %50 == 0 : print mes
        logru.append(math.log(moy))
        logu.append(math.log(u))
        
    import pylab
    pylab.plot ( logu, logru, "o")
    pylab.show()
    
a,c = 1.0/3, 1.0/3
b = 1-a-c
e = -1

su = calcul_suite_a(600,e,a,b,c)
affiche_proba(su, e)

File: td_note_2013_preparation.tex, line 186


u    1 P(U=u) 0.333333    r_u  0.333333
u    2 P(U=u) 0.111111    r_u  0.555556
u   50 P(U=u) 0.0013566   r_u  5.57241
u  100 P(U=u) 0.00048407  r_u  8.38753
u  150 P(U=u) 0.000264311 r_u 10.5627
u  200 P(U=u) 0.000171942 r_u 12.4016
u  250 P(U=u) 0.000123146 r_u 14.0242
u  300 P(U=u) 9.37388e-05 r_u 15.4926
u  350 P(U=u) 7.44204e-05 r_u 16.8438
u  400 P(U=u) 6.09325e-05 r_u 18.1021
u  450 P(U=u) 5.10779e-05 r_u 19.2843
u  500 P(U=u) 4.36202e-05 r_u 20.4028
u  550 P(U=u) 3.78157e-05 r_u 21.4669
u  600 P(U=u) 3.31933e-05 r_u 22.4839

File: td_note_2013_preparation.tex, line 311


import random
N = 10
M = [ [  1 if random.randint(1,5) == 1 else 0 for i in range (N) ] for j in range(N) ]
for l in M : print l
    
nb = 0
for i in range(N) :
    for j in range (N) :
        if   i > 0   and M[i-1][j] == 1 : nb += 1
        elif i < N-1 and M[i+1][j] == 1 : nb += 1
        elif j > 0   and M[i][j-1] == 1 : nb += 1
        elif j < N-1 and M[i][j+1] == 1 : nb += 1
print nb

File: td_note_2013_preparation.tex, line 329


[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0, 1, 1]
[0, 0, 0, 0, 1, 0, 1, 1, 0, 1]
[0, 0, 1, 0, 1, 0, 0, 1, 1, 1]
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
[0, 1, 0, 0, 0, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
46

File: td_note_2013_preparation.tex, line 345


[0, 1, 0]
[0, 0, 1]
[0, 0, 0]
4

File: td_note_2013_preparation.tex, line 391


import random, numpy
N  = 10
M  = [ [  1.0 if random.randint(1,5) == 1 else 0.0 for i in range (N) ] for j in range(N) ]
M  = numpy.matrix(M)
MM = numpy.matrix(M)
for i in range (N) : 
    s = numpy.sum(M[i,:])  # ou M[i,:].sum()
    if s > 0 : MM [i,:] = M [i,:] / s
print MM

File: td_note_2013_preparation.tex, line 406


import random, numpy
N  = 5
M  = [ [  1 if random.randint(1,5) == 1 else 0 for i in range (N) ] for j in range(N) ]
M  = numpy.matrix (M)
MM = numpy.matrix(M)
for i in range (N) : 
    s = numpy.sum(M[i,:])
    if s > 0 : MM [i,:] = M [i,:]*1.0 / s   # multiplication par 1.0
print MM

File: td_note_2013_exoS.tex, line 14


#coding:latin-1
import exoS
matrice = exoS.construit_matrice(100)

File: td_note_2013_exoS.tex, line 21


exoS.dessin_matrice(matrice)   # cette fonction place un point bleu pour une case contenant 1,
                               # rouge pour une case contenant 2,
                               # rien si elle contient 0

File: td_note_2013_exoS.tex, line 31


def voisins_a_valeur_nulle ( matrice, i, j ) :
    resultat = [ ]
    # ...
    return resultat

File: td_note_2013_exoS.tex, line 41


def tous_voisins_a_valeur_nulle ( matrice, liste_points ) :
    resultat = [ ]
    # ...
    return resultat

File: td_note_2013_exoS.tex, line 57


def fonction_coloriage( matrice, i0, j0) :
    # ...

File: td_note_2013.tex, line 20


def surface_coloriee ( matrice ) :
    # ...
    return surface

File: td_note_2013.tex, line 27


def fonction_coloriage_environ_1000 ( matrice, i0, j0 ) :
    # ...
    return surface

, énoncé 2013

#coding:latin-1
import math

# cette fonction construit deux spirales imbriquées dans une matrice nb x nb
# le résultat est retourné sous forme de liste de listes
def construit_matrice (nb) :
    mat = [ [ 0 for x in range (0,nb) ] for y in range(0,nb) ]

    def pointij (nb,r,th,mat,c,phase) :
        i,j = r*th * math.cos(th+phase), r*th*math.sin(th+phase)
        i,j = int(i*100/nb), int(j*100/nb)
        i,j = (i+nb)/2, (j+nb)/2
        if 0 <= i < nb and 0 <= j < nb :
            mat[i][j] = c
        return i,j

    r = 3.5
    t = 0
    for tinc in range (nb*100000) :
        t  += 1.0 * nb / 100000
        th  = t * math.pi * 2
        i,j = pointij (nb,r,th,mat,1, 0)
        i,j = pointij (nb,r,th,mat,1, math.pi)
        if i >= nb and j >= nb : break
        
    return mat
    
# cette fonction reçoit une matrice sous forme de liste de listes contenant des entiers : 0,1,2
# à chaque valeur est associée une couleur :
# 0 pour blanc, 1 pour bleu, 2 pour rouge
def dessin_matrice (matrice) :
    import pylab
    colors = { 1: "blue", 2:"red"  }
    for i in range(0,len(matrice)) :
        for j in range (0, len(matrice[i])) :
            if matrice [i][j] in colors : 
                pylab.plot ([i-0.5,i-0.5,i+0.5,i+0.5,i-0.5,i+0.5,i-0.5,i+0.5], 
                            [j-0.5,j+0.5,j+0.5,j-0.5,j-0.5,j+0.5,j+0.5,j-0.5], 
                        colors [ matrice[i][j] ])
    pylab.show()
    
if __name__ == "__main__" :
    matrice = construit_matrice(100)
    dessin_matrice(matrice)

, correction 2013

#coding:latin-1
import td_note_2013_novembre_2012_exoS as exoS

# question 1, exo S (1 ou 4)
def voisins_a_valeurs_nulle (matrice,i,j) :
    res = []
    if i > 0                 and matrice[i-1][j] == 0 : res.append ( (i-1,j) )
    if i < len(matrice)-1    and matrice[i+1][j] == 0 : res.append ( (i+1,j) )
    if j > 0                 and matrice[i][j-1] == 0 : res.append ( (i,  j-1) )
    if j < len(matrice[i])-1 and matrice[i][j+1] == 0 : res.append ( (i,  j+1) )
    return res
    
# question 2, exo S (1 ou 4)
def tous_voisins_a_valeurs_nulle (matrice, liste_points) :
    res = []
    for i,j in liste_points :
        res += voisins_a_valeurs_nulle (matrice, i,j) 
    return res
    
# question 3, exo S (1 ou 4)
def fonction_coloriage ( matrice, i0, j0) :
    # étage 1
    acolorier = [ ( i0, j0 ) ]
    while len (acolorier) > 0 :
        # étape 2
        for i,j in acolorier : 
            matrice [i][j] = 2
        # étape 3
        acolorier = tous_voisins_a_valeurs_nulle ( matrice, acolorier )
        # on enlève les doublons car sinon cela prend trop de temps
        d = { }
        for i,j in acolorier : d [i,j] = 0
        acolorier = [ (i,j) for i,j in d ]
        
# question 5, exo S (version 1)
def surface_coloriee (matrice) :
    surface = 0
    for line in matrice : 
        for c in line : 
            if c == 2 : surface += 1
    return surface
    
# question 5, exo S (version 4)
def fonction_coloriage_1000 ( matrice, i0, j0) :
    acolorier = [ ( i0, j0 ) ]
    nb = 0                                 # ligne ajoutée
    while len (acolorier) > 0 :
        for i,j in acolorier : 
            matrice [i][j] = 2
            nb += 1                        # ligne ajoutée
        if nb > 1000 : break               # ligne ajoutée
        acolorier = tous_voisins_a_valeurs_nulle ( matrice, acolorier )
        d = { }
        for i,j in acolorier : d [i,j] = 0
        acolorier = [ (i,j) for i,j in d ]

# question 4, exo S (1 ou 4)
matrice = exoS.construit_matrice(100)
fonction_coloriage  (matrice, 53, 53)
exoS.dessin_matrice(matrice)
print surface_coloriee (matrice) # retourne 3258

# question 5, exo S (version 4) vérification
matrice = exoS.construit_matrice(100)
fonction_coloriage_1000  (matrice, 53, 53)
exoS.dessin_matrice(matrice)
print surface_coloriee (matrice) # retourne 1002

File: td_note_2013_exoM.tex, line 4


#coding:latin-1
import exoM
fichier_zip   = exoM.import_module_or_file_from_web_site ("equipements_sportif_2011.zip")
fichier_texte = exoM.unzip_fichier (fichier_zip)
# enlever le dernier paramètre 500 pour avoir le tableau complet
colonne, intitule, variables = exoM.construit_matrice (fichier_texte, 500)  
    # colonne   : contient le nom des colonnes
    # intitule  : contient les deux premières colonnes du fichier textes avec du texte
    # variables : contient les autres colonnes avec des valeurs numériques 

File: td_note_2013_exoM.tex, line 18


import numpy
intitule  = numpy.array(intitule)  # array et non matrix
variables = numpy.array(variables) # array et non matrix

# utilisation de numpy pour sélectionner des lignes spécifiques
print intitule [ intitule[:,1] == "Chevroux", : ]  # affiche [['01102' 'Chevroux']]
print variables[ intitule[:,1] == "Chevroux", : ]  # affiche [[  82.    1.   12 ...

File: td_note_2013_exoM.tex, line 29


print tab.shape                     # si tab est une matrice ou un tableau numpy à deux dimensions,
                                    # tab.shape est un couple (nb_lignes, nb_colonnes)
a = numpy.column_stack ( ( m, e ) ) # coller deux matrices, tableaux ayant le même nombre de lignes

File: td_note_2013_exoM.tex, line 51


# crée une matrice de dimension nb_lignes x nb_colonnes initialisés à zéro
mvide = numpy.zeros ( ( nb_lignes, nb_colonnes) )

File: td_note_2013_exoM.tex, line 64


li = list ( mat [:,i] )           # convertit une colonne d'un tableau numpy en une liste
print colonne[0][i+2]             # affiche le label de la colonne i
gini = exoM.coefficient_gini (li) # retourne le coefficient de Gini
                                  # pour la liste li

, énoncé 2013

#coding:latin-1
import math, sys

# extrait les données depuis un site internet, puis les écrit à côté du programme
# ne fait rien si le fichier a déjà été téléchargé
def import_module_or_file_from_web_site (module) :
    import os
    if os.path.exists ("data\\equipement_sportifs_2011\\" + module) :
        return "data\\equipement_sportifs_2011\\" + module
    if not os.path.exists (module) :
        url = "http://www.xavierdupre.fr/enseignement/complements/" + module
        import urllib2
        if module.lower().endswith("zip") :
            f = urllib2.urlopen (url, "rb")
            t = f.read()
            f.close()
            f = open(module, "wb")
            f.write(t)
            f.close()
        else :
            f = urllib2.urlopen (url)
            t = f.read()
            f.close()
            f = open(module, "w")
            f.write(t)
            f.close()
    return module

# extrait le fichier texte contenu dans le fichier zip
# et l'enregistre à côté du programme
# ne fait rien si cela est déjà fait
def unzip_fichier (fichier_zip) :
    import zipfile, os
    file = zipfile.ZipFile (fichier_zip, "r")
    res = None
    for info in file.infolist () :
        filename = info.filename
        res = filename
        if not os.path.exists (filename) :
            data = file.read(filename)
            f = open (filename,"w")
            if sys.version.startswith("3.") :
                data = str (data, encoding="iso-8859-1")
                data = data.replace("\r","").split("\n")
                data = [ _ for _ in data if len (_) > 1 ]
                data = "\n".join(data)
            f.write (data)
            f.close()
    file.close ()
    return res
    
# construit le tableau extrait du fichier précédent
# les deux premières lignes contiennent la description des colonnes
# les autres lignes contiennent les données elles-même
# pour aller plus vite à chaque exécution, on peut limiter le nombre de lignes
# il faudra toutes les utiliser pour l'exécution final
def construit_matrice (fichier, stop_apres = -1) :
    def float_except(x) :
        try : return float(x)
        except : return -1
    f = open (fichier, "r")
    lines = [ line.replace("\n","").split("\t")[:107] \
            for line in f.readlines()[:stop_apres] ]
    f.close ()
    colonne = lines [:2]
    lines = lines [2: ]
    lines = [ line [:2] + [ float_except(x) for x in line [2:] ] \
            for line in lines if len(line)>5 ]
    intitule = [ line[:2] for line in lines ]
    lines = [ line[2:] for line in lines ]
    return colonne, intitule, lines
    
def coefficient_gini (valeurs) :
    #voir http://fr.wikipedia.org/wiki/Coefficient_de_Gini
    valeurs.sort()
    gini = 0
    s = 0
    for (i,v) in enumerate (valeurs) :
        gini += (i+1)*v
        s += v
    gini = 2*gini / (len(valeurs)*s) - (len(valeurs)+1.0)/len(valeurs)
    return gini

if __name__ == "__main__" :
    fichier_zip   = import_module_or_file_from_web_site ("equipements_sportif_2011.zip")
    fichier_texte = unzip_fichier (fichier_zip)

    # enlever le dernier paramètre 500 pour avoir le tableau complet
    colonne, intitule, variables = construit_matrice (fichier_texte, 500)  

    import numpy
    intitule  = numpy.array(intitule)
    variables = numpy.array(variables)

    # affichage des colonnes
    for i in range (len(colonne[0])) : print (i,colonne[0][i], " --- ", colonne[1][i])
        
    # utilisation de numpy pour sélectionner des lignes spécifiques
    print (intitule  [ intitule[:,1] == "Chevroux", : ])
    print (variables [ intitule[:,1] == "Chevroux", : ])

, correction 2013

#coding:latin-1
import numpy
import td_note_2013_novembre_2012_exoM as exoM

fichier_zip   = exoM.import_module_or_file_from_web_site ("equipements_sportif_2011.zip")
fichier_texte = exoM.unzip_fichier (fichier_zip)

# enlever le dernier paramètre 500 pour avoir le tableau complet
colonne, intitule, variables = exoM.construit_matrice (fichier_texte)  

import numpy
intitule  = numpy.array(intitule)
variables = numpy.array(variables)

# question 1, exo M (2 ou 3)
code_postaux = [ intitule[i,0] [:2] for i in range (intitule.shape[0] ) ]
intitule3    = numpy.column_stack ( (intitule, code_postaux) )

# question 2, exo M (2 ou 3)
comptage = {}
for i in range (intitule3.shape[0]) :
    comptage [intitule3 [i,2] ] = 0
departements = [ k for k in comptage ]
departements.sort()

# question 3, exo M (2 ou 3)
D = numpy.zeros ( (len(departements), variables.shape[1] ) )
for i in range (len (departements)) :
    d = departements [i]
    for j in range (variables.shape[1]) :
        D [i,j] = variables [ intitule3 [:,2] == d, j ].sum()
    
# question 4, exo M (2 ou 3)
E = numpy.zeros ( D.shape )
for i in range (E.shape[0]) :
    E [i,:] = D[i,:] / D[i,5]
    
# question 5, exo M (2 ou 3)
ginis = []
for j in range (E.shape[1]) :
    li = list ( E [:,j] )
    gini = exoM.coefficient_gini (li)
    ginis.append ( (gini, colonne[0][j+2]) )
ginis.sort ()
for line in ginis : print line

# les dernières lignes du tableau sont :
#(0.86910090569180598, 'Domaine skiable')
#(0.88139092467853186, 'Sports nautiques avec au moins une aire de pratique couverte')
#(0.89326137963164931, 'Domaine skiable - nombre de pistes')
#(0.9348918282098031,  'Parcours sportif avec au moins un parcours couvert')
#(0.93902978850018792, 'Domaine skiable avec au moins une piste \xe9clair\xe9e')
#(0.94625459043715754, '\xc9quipement de cyclisme avec au moins une piste couverte')
#(0.95743849241598267, 'Sports nautiques - nombre de places en tribune')
#(0.97248425032547758, 'Domaine skiable avec au moins une piste couverte')
#(0.97718065858676906, 'Parcours sportif - nombre de places en tribune')
#(0.98637386313881081, 'Terrain de golf - nombre de places en tribune')
#(0.98969072164948457, 'Domaine skiable - nombre de places en tribune')

File: td_note_2013_rattrape.tex, line 25


def lit_fichier (file) :
    """
    0 Séance 	
    1 Référence	
    2 Entité dépositaire	
    3 Elu dépositaire	
    4 Objet	
    5 Type	
    6 Rapporteur
    """
    f = open(file,"r")
    lines = f.readlines ()
    f.close ()
    lines = [ _ for _ in lines if len(_) > 0 ]
    lines = [ _.split("\t") for _ in lines ] [1:]
    lines = [ (_[0], _[4] ) for _ in lines if len(_) > 5 ]
    return lines

File: td_note_2013_rattrape.tex, line 58


import re
def extrait_montant (objet) :
    exp = re.compile ("[ (]([0-9.,]+) {0,3}euros")
    res = exp.search (objet)
    if res :
        montant = res.groups() [0]
        return montant
    else :
        print ("problème ", objet)
        return None

File: td_note_2013_rattrape.tex, line 87


exp = re.compile ("association(.*)[(]([0-9]+e)[)]")

, correction 2013

#coding:latin-1
import numpy
import td_note_2013_novembre_2012_exoM as exoM

fichier_zip   = exoM.import_module_or_file_from_web_site ("equipements_sportif_2011.zip")
fichier_texte = exoM.unzip_fichier (fichier_zip)

# enlever le dernier paramètre 500 pour avoir le tableau complet
colonne, intitule, variables = exoM.construit_matrice (fichier_texte)  

import numpy
intitule  = numpy.array(intitule)
variables = numpy.array(variables)

# question 1, exo M (2 ou 3)
code_postaux = [ intitule[i,0] [:2] for i in range (intitule.shape[0] ) ]
intitule3    = numpy.column_stack ( (intitule, code_postaux) )

# question 2, exo M (2 ou 3)
comptage = {}
for i in range (intitule3.shape[0]) :
    comptage [intitule3 [i,2] ] = 0
departements = [ k for k in comptage ]
departements.sort()

# question 3, exo M (2 ou 3)
D = numpy.zeros ( (len(departements), variables.shape[1] ) )
for i in range (len (departements)) :
    d = departements [i]
    for j in range (variables.shape[1]) :
        D [i,j] = variables [ intitule3 [:,2] == d, j ].sum()
    
# question 4, exo M (2 ou 3)
E = numpy.zeros ( D.shape )
for i in range (E.shape[0]) :
    E [i,:] = D[i,:] / D[i,5]
    
# question 5, exo M (2 ou 3)
ginis = []
for j in range (E.shape[1]) :
    li = list ( E [:,j] )
    gini = exoM.coefficient_gini (li)
    ginis.append ( (gini, colonne[0][j+2]) )
ginis.sort ()
for line in ginis : print line

# les dernières lignes du tableau sont :
#(0.86910090569180598, 'Domaine skiable')
#(0.88139092467853186, 'Sports nautiques avec au moins une aire de pratique couverte')
#(0.89326137963164931, 'Domaine skiable - nombre de pistes')
#(0.9348918282098031,  'Parcours sportif avec au moins un parcours couvert')
#(0.93902978850018792, 'Domaine skiable avec au moins une piste \xe9clair\xe9e')
#(0.94625459043715754, '\xc9quipement de cyclisme avec au moins une piste couverte')
#(0.95743849241598267, 'Sports nautiques - nombre de places en tribune')
#(0.97248425032547758, 'Domaine skiable avec au moins une piste couverte')
#(0.97718065858676906, 'Parcours sportif - nombre de places en tribune')
#(0.98637386313881081, 'Terrain de golf - nombre de places en tribune')
#(0.98969072164948457, 'Domaine skiable - nombre de places en tribune')

extrait 1 à copier pour l'énoncé de décembre 2013


def deux_recherches(element, liste_impaire, liste_paire) :
    # ....
    return position_dans_liste_impaire, position_dans_liste_paire

vérifier que tous les éléments de la liste sont bien retrouvés


l = [ 0, 2, 4, 6, 8, 100, 1000 ]
for i in l :
    print (i,recherche_dichotomique(i, l)) 

, énoncé 2014

#coding: latin-1

######### énoncé 1, exercice 1, recherche dichotomique

## question 1 

def recherche_dichotomique( element, liste_triee ):
    """
    premier code: http://www.xavierdupre.fr/blog/2013-12-01_nojs.html    
    """
    a = 0
    b = len(liste_triee)-1
    m = (a+b)//2
    while a < b :
        if liste_triee[m] == element :
            return m
        elif liste_triee[m] > element :
            b = m-1
        else :
            a = m+1
        m = (a+b)//2
    return a
    
l = [ 0, 2, 4, 6, 8, 100, 1000 ]
print (recherche_dichotomique(100, l))  # affiche 5

## question 2

def deux_recherches(element,liste_impair,liste_pair) :
    if element % 2 == 0 :
        return recherche_dichotomique(element, liste_pair), -1
    else :
        return -1, recherche_dichotomique(element, liste_impair)

lp = [ 0, 2, 4, 6, 8, 100, 1000 ]
li = [ 1, 3, 5 ]
print (deux_recherches(100, li, lp))  # affiche (5, -1)

## question 3
"""       
                            liste coupée       liste non coupée (2n)
recherche simple                1 + n                 2n
recherche dichotomique          1 + ln n             ln(2n) = 1 + ln(n)

coût équivalent
"""

## question 4 

def recherche_dichotomique( element, liste_triee ):
    a = 0
    b = len(liste_triee)-1
    m = (a+b)//2
    while a < b :
        if liste_triee[m] == element :
            return m
        elif liste_triee[m] > element :
            b = m-1
        else :
            a = m+1
        m = (a+b)//2
    if liste_triee[a] != element :  return -1       # ligne ajoutée
    else : return m                                 # ligne ajoutée
    
l = [ 0, 2, 4, 6, 8, 100, 1000 ]
for i in l :
    print (i,recherche_dichotomique(i, l))  
    # vérifier qu'on retrouve tous les éléments existant
print (recherche_dichotomique(1, l))   # affiche -1

## question  5

def deux_recherches(element,liste_impair,liste_pair) :
    i = recherche_dichotomique(element, liste_impair)
    if i == -1 : return recherche_dichotomique(element, liste_pair)
    else : return i
    
##question 6 

"""
Les logarithmes sont en base 2.

coût fonction question 2 : 1001 ( 1 + ln(n) )      = C1
coût fonction question 5 : 1000 ln(n)  + 2 ln(n)   = C2
C2 - C1 = ln(n) - 1001 > 0
    
La fonction 5 est plus rapide dans ce cas.
"""

cas où la recherche n'est plus dichotomique


def recherche_dichotomique( element, liste_triee ):
    if element not in list_triee : return -1 # ligne A
    a = 0
    b = len(liste_triee)-1
    m = (a+b)//2
    while a < b :
        if liste_triee[m] == element :
            return m
        elif liste_triee[m] > element :
            b = m-1
        else :
            a = m+1
        m = (a+b)//2
    return a

File: td_note_2014.tex, line 110


def deux_recherches(element,liste_impair,liste_pair) :
    if recherche_dichotomique(element, liste_impair) == -1 : 
       return recherche_dichotomique(element, liste_pair)
    else : return recherche_dichotomique(element, liste_impair)

, énoncé 2014

#coding: latin-1

######### énoncé 1, exercice 2 distance de Levenstein

## question 1 

def distance_edition(mot1, mot2):
    """
    première fonction retrouvée à : http://www.xavierdupre.fr/blog/2013-12-02_nojs.html
    """
    dist = { (-1,-1): 0 }
    for i,c in enumerate(mot1) :
        dist[i,-1] = dist[i-1,-1] + 1
        dist[-1,i] = dist[-1,i-1] + 1
        for j,d in enumerate(mot2) :
            opt = [ ]
            if (i-1,j) in dist :
                x = dist[i-1,j] + 1
                opt.append(x)
            if (i,j-1) in dist :
                x = dist[i,j-1] + 1
                opt.append(x)
            if (i-1,j-1) in dist :
                x = dist[i-1,j-1] + (1 if c != d else 0)
                opt.append(x)
            dist[i,j] = min(opt)
    return dist[len(mot1)-1,len(mot2)-1]

print ("****1*")
print (distance_edition("levenstein","levenshtein"))    # 1
print (distance_edition("bonbon","bonbom"))             # 1
print (distance_edition("example","exemples"))          # 2
print (distance_edition("esche","eche"))                # 1

## question 2

print ("****2*")
print (distance_edition("levenshtein","levenstein"))    # 1
print (distance_edition("bonbom","bonbon"))             # 1
print (distance_edition("exemples","example"))          # 2
print (distance_edition("eche","esche"))                # 1

## question 3

def distance_edition(mot1, mot2):
    dist = { (-1,-1): 0 }
    for i,c in enumerate(mot1) :
        dist[i,-1] = dist[i-1,-1] + 1
        dist[-1,i] = dist[-1,i-1] + 1
        for j,d in enumerate(mot2) :
            opt = [ ]
            if (i-1,j) in dist :
                x = dist[i-1,j] + 1
                opt.append(x)
            if (i,j-1) in dist :
                x = dist[i,j-1] + 1
                opt.append(x)
            if (i-1,j-1) in dist :
                if c == d : x = dist[i-1,j-1]                                       ##
                elif c in ['n','m'] and d in ['n','m'] : x = dist[i-1,j-1] + 0.5    ##
                else : x = dist[i-1,j-1] + 1                                        ## 
                opt.append(x)
            dist[i,j] = min(opt)
    return dist[len(mot1)-1,len(mot2)-1]

print ("****3*")
print (distance_edition("levenstein","levenshtein"))    # 1
print (distance_edition("bonbon","bonbom"))             # 0.5
print (distance_edition("example","exemples"))          # 2
print (distance_edition("esche","eche"))                # 1
print (distance_edition("levenshtein","levenstein"))    # 1
print (distance_edition("bonbom","bonbon"))             # 0.5
print (distance_edition("exemples","example"))          # 2
print (distance_edition("eche","esche"))                # 1

## question 4

def distance_edition(mot1, mot2):
    dist = { (-1,-1): 0 }
    for i,c in enumerate(mot1) :
        dist[i,-1] = dist[i-1,-1] + 1
        dist[-1,i] = dist[-1,i-1] + 1
        for j,d in enumerate(mot2) :
            opt = [ ]
            if (i-1,j) in dist :
                if c == "s" :  x = dist[i-1,j] + 0.5    ## 
                else : x = dist[i-1,j] + 1              ## 
                opt.append(x)
            if (i,j-1) in dist :
                if d == "s" : x = dist[i,j-1] + 0.5     ##
                else : x = dist[i,j-1] + 1              ##
                opt.append(x)
            if (i-1,j-1) in dist :
                if c == d : x = dist[i-1,j-1] 
                elif c in ['n','m'] and d in ['n','m'] : x = dist[i-1,j-1] + 0.5
                else : x = dist[i-1,j-1] + 1
                opt.append(x)
            dist[i,j] = min(opt)
    return dist[len(mot1)-1,len(mot2)-1]

print ("****4*")
print (distance_edition("levenstein","levenshtein"))    # 1
print (distance_edition("bonbon","bonbom"))             # 0.5
print (distance_edition("example","exemples"))          # 1.5
print (distance_edition("esche","eche"))                # 0.5
print (distance_edition("levenshtein","levenstein"))    # 1
print (distance_edition("bonbom","bonbon"))             # 0.5
print (distance_edition("exemples","example"))          # 1.5
print (distance_edition("eche","esche"))                # 0.5

## question 5

def distance_edition(mot1, mot2):
    dist = { (-1,-1): 0 }
    for i,c in enumerate(mot1) :
        dist[i,-1] = dist[i-1,-1] + 1
        dist[-1,i] = dist[-1,i-1] + 1
        for j,d in enumerate(mot2) :
            opt = [ ]
            if (i-1,j) in dist :
                if c == "s" :  
                    if i == len(mot1)-1 : x = dist[i-1,j] + 0.2 ##
                    else : x = dist[i-1,j] + 0.5                ##
                else : x = dist[i-1,j] + 1
                opt.append(x)
            if (i,j-1) in dist :
                if d == "s" : 
                    if j == len(mot2)-1 : x = dist[i,j-1] + 0.2 ##
                    else : x = dist[i,j-1] + 0.5                ##
                else : x = dist[i,j-1] + 1                      
                opt.append(x)
            if (i-1,j-1) in dist :
                if c == d : x = dist[i-1,j-1] 
                elif c in ['n','m'] and d in ['n','m'] : x = dist[i-1,j-1] + 0.5
                else : x = dist[i-1,j-1] + 1
                opt.append(x)
            dist[i,j] = min(opt)
    return dist[len(mot1)-1,len(mot2)-1]

print ("****5*")
print (distance_edition("levenstein","levenshtein"))    # 1
print (distance_edition("bonbon","bonbom"))             # 0.5
print (distance_edition("example","exemples"))          # 1.2
print (distance_edition("esche","eche"))                # 0.5
print (distance_edition("levenshtein","levenstein"))    # 1
print (distance_edition("bonbom","bonbon"))             # 0.5
print (distance_edition("exemples","example"))          # 1.2
print (distance_edition("eche","esche"))                # 0.5

File: td_note_2014.tex, line 176


if (i-1,j-1) in dist :
    x = dist[i-1,j-1] + (0.5 if c != d else 0)  # 1 --> 0.5

, énoncé 2014

#coding: latin-1

######### énoncé 2, exercice 3 distance de Levenstein

## question 1 

def distance_edition(mot1, mot2):
    """
    première fonction retrouvée à : http://www.xavierdupre.fr/blog/2013-12-02_nojs.html
    """
    dist = { (-1,-1): 0 }
    for i,c in enumerate(mot1) :
        dist[i,-1] = dist[i-1,-1] + 1
        dist[-1,i] = dist[-1,i-1] + 1
        for j,d in enumerate(mot2) :
            opt = [ ]
            if (i-1,j) in dist :
                x = dist[i-1,j] + 1
                opt.append(x)
            if (i,j-1) in dist :
                x = dist[i,j-1] + 1
                opt.append(x)
            if (i-1,j-1) in dist :
                x = dist[i-1,j-1] + (1 if c != d else 0)
                opt.append(x)
            dist[i,j] = min(opt)
    return dist[len(mot1)-1,len(mot2)-1]

print ("****1*")
print (distance_edition("levenstein","levenstien"))     # 2
print (distance_edition("bonbbon","bonbon"))            # 1
print (distance_edition("example","exemples"))          # 2

## question 2

print ("****2*")
print (distance_edition("levenstien","levenstein"))     # 2
print (distance_edition("bonbon","bonbbon"))            # 1
print (distance_edition("exemples","example"))          # 2

## question 3

def distance_edition(mot1, mot2):
    """
    première fonction retrouvée à : http://www.xavierdupre.fr/blog/2013-12-02_nojs.html
    """
    dist = { (-1,-1): 0 }
    for i,c in enumerate(mot1) :
        dist[i,-1] = dist[i-1,-1] + 1
        dist[-1,i] = dist[-1,i-1] + 1
        for j,d in enumerate(mot2) :
            opt = [ ]
            if (i-1,j) in dist :
                x = dist[i-1,j] + 1
                opt.append(x)
            if (i,j-1) in dist :
                x = dist[i,j-1] + 1
                opt.append(x)
            if (i-1,j-1) in dist :
                x = dist[i-1,j-1] + (1 if c != d else 0)
                opt.append(x)
            if (i-2,j-2) in dist :                          ##
                if c == mot2[j-1] and d == mot1[i-1] :      ##
                    x = dist[i-2,j-2] + 1                   ##
                    opt.append(x)                           ##
            dist[i,j] = min(opt)
    return dist[len(mot1)-1,len(mot2)-1]

print ("****3*")
print (distance_edition("levenstein","levenstien"))     # 1
print (distance_edition("bonbbon","bonbon"))            # 1
print (distance_edition("example","exemples"))          # 2
print (distance_edition("levenstien","levenstein"))     # 1
print (distance_edition("bonbon","bonbbon"))            # 1
print (distance_edition("exemples","example"))          # 2

## question 4

def distance_edition(mot1, mot2):
    """
    première fonction retrouvée à : http://www.xavierdupre.fr/blog/2013-12-02_nojs.html
    """
    dist = { (-1,-1): 0 }
    for i,c in enumerate(mot1) :
        dist[i,-1] = dist[i-1,-1] + 1
        dist[-1,i] = dist[-1,i-1] + 1
        for j,d in enumerate(mot2) :
            opt = [ ]
            if (i-1,j) in dist :
                x = dist[i-1,j] + 1
                opt.append(x)
            if (i,j-1) in dist :
                x = dist[i,j-1] + 1
                opt.append(x)
            if (i-1,j-1) in dist :
                x = dist[i-1,j-1] + (1 if c != d else 0)
                opt.append(x)
            if (i-2,j-2) in dist :                          
                if c == mot2[j-1] and d == mot1[i-1] :      
                    x = dist[i-2,j-2] + 1                   
                    opt.append(x)
            if (i-2,j-1) in dist and c == d == mot1[i-1] :  ##
                    x = dist[i-2,j-1] + 0.45                ##
                    opt.append(x)                           ##
            if (i-1,j-2) in dist and c == d == mot2[j-1] :  ##
                    x = dist[i-1,j-2] + 0.45                ##
                    opt.append(x)                           ##
            dist[i,j] = min(opt)
    return dist[len(mot1)-1,len(mot2)-1]

print ("****4*")
print (distance_edition("levenstein","levenstien"))     # 1
print (distance_edition("bonbbon","bonbon"))            # 0.45
print (distance_edition("example","exemples"))          # 2
print (distance_edition("levenstien","levenstein"))     # 1
print (distance_edition("bonbon","bonbbon"))            # 0.45
print (distance_edition("exemples","example"))          # 2

File: td_note_2014.tex, line 252


if abs(i-j)==1 and mot1[i]==mot2[j] and (mot1[i+1]==mot2[j-1] or mot1[i-1]==mot2[j+1]):

File: td_note_2014.tex, line 260


if abs(j-i)==1 and mot1[i]==mot2[j] and (mot1[i+1]==mot2[j-1] or mot1[i-1]==mot2[j+1]):
	dist[i,j] = min(opt)-1
else:
	dist[i,j]=min(opt)

vérifier que tous les éléments de la liste sont bien retrouvés


l = [ 0, 2, 4, 6, 8, 100, 1000 ]
for i in l :
    print (i,recherche_dichotomique(i, l)) 

extrait 2 à copier pour l'énoncé de décembre 2013


def deux_recherches(element, liste1, liste2) :
    # ....
    return position_dans_liste1, position_dans_liste2

, énoncé 2014

#coding: latin-1

######### énoncé 1, exercice 1, recherche dichotomique

## question 1 

def recherche_dichotomique( element, liste_triee ):
    """
    premier code: http://www.xavierdupre.fr/blog/2013-12-01_nojs.html    
    """
    a = 0
    b = len(liste_triee)-1
    m = (a+b)//2
    while a < b :
        if liste_triee[m] == element :
            return m
        elif liste_triee[m] > element :
            b = m-1
        else :
            a = m+1
        m = (a+b)//2
    return a
    
l =  [ 0, 2, 3, 5, 10, 100, 340 ]
print (recherche_dichotomique(100, l))  # affiche 5

## question 2

def recherche_dichotomique( element, liste_triee ):
    a = 0
    b = len(liste_triee)-1
    m = (a+b)//2
    while a < b :
        if liste_triee[m] == element :
            return m
        elif liste_triee[m] > element :
            b = m-1
        else :
            a = m+1
        m = (a+b)//2
    if liste_triee[a] != element :  return -1       # ligne ajoutée
    else : return m    
    
    
l = [ 0, 2, 4, 6, 8, 100, 1000 ]
for i in l :
    print (i,recherche_dichotomique(i, l))  
    # vérifier qu'on retrouve tous les éléments existant
print (recherche_dichotomique(1, l))   # affiche -1


## question 3

def deux_recherches(element,liste1,liste2) :
    return recherche_dichotomique(element, liste1) ,  \
            recherche_dichotomique(element,liste2)
            
l1 = [ 0, 2, 4, 6, 8, 100, 1000 ]
l2 = [ 1200, 3000, 4000, 5555 ]
print (deux_recherches(100,l1,l2) )    # affiche (5,-1)

## question 4 

"""
Les logarithmes sont en base 2.

cas 1 : 1000 ln(n) + 10 (ln(n) + ln(10n)) = 1020 ln(n) + 10 ln(10) = C1
cas 2 : 1010 ln(n + 10n) = 1010 ln(n) + 1010 ln(11)                = C2
delta = C2 - C1 = -10 ln(n) + 1010 ln(11) - 10 ln(10)

Conclusion : pour n petit, le cas C1 est préférable, pour les n grands, c'est le cas 2.
"""

## question 5

def deux_recherches(element,liste1,liste2) :
    if element > liste1[-1] :
        return -1, recherche_dichotomique(element, liste2) 
    else :
        return recherche_dichotomique(element,liste1), -1
            
l1 = [ 0, 2, 4, 6, 8, 100, 1000 ]
l2 = [ 1200, 3000, 4000, 5555 ]
print (deux_recherches(100,l1,l2) )    # affiche (5,-1)

File: td_note_2015.tex, line 51


suites_chemin( [ 0, 1 ], dico ) --> [ [ 0, 1, 2 ] ]
suites_chemin( [ 0, 1, 2 ], dico ) --> [  ]   # il n'y pas de suite possible

vérifier que tous les éléments de la liste sont bien retrouvés


%l = [ 0, 2, 4, 6, 8, 100, 1000 ]
%for i in l :
%    print (i,recherche_dichotomique(i, l)) 
%

File: td_note_2015.tex, line 150


dictionnaire [  i,j  ]
dictionnaire [ (i,j) ]

File: td_note_2015.tex, line 157


mot --> { 0:'', 1:'m', 2:'mo', 3:'mot' }

File: td_note_2015.tex, line 166


vertices = {  (i,j): (d1[i],d2[j]) }

File: td_note_2015.tex, line 184


edges = { (i1,j1),(i2,j2) : valeur }

File: td_note_2015.tex, line 190


edges [ (i1,j1),(i2,j2) ] = 1 si  (i2-i1 == 1 et j1 == j2) ou (j2-j1 == 1 et i1 == i2)

File: td_note_2016.tex, line 26


def rendement(x, n, r):
    # ....
    return

File: td_note_2016.tex, line 34


def decompose_mensualite(K,M,p):
    # ...
    return capital, interet

File: td_note_2016.tex, line 43


def mensualites(K,M,p):
    # ....
    return [ liste de mensualités ]

File: td_note_2016.tex, line 52


def somme_maximale(M,p,Y):
    # ....
    return K max

File: td_note_2016.tex, line 61


def economie(A,S,L,r,Y):
    # ....
    return economie

File: td_note_2016.tex, line 81


def bascule(A,S,L,r,Y,C,p):
    # ....
    return nombre d'années

File: td_note_2016.tex, line 90


def surface_max(A,L,r,Y,C,p,delay=20):
    # ....
    return surface

File: td_note_2016.tex, line 116


adele   06 64 34 22 67 --> 06 46 34 22 67  lettres 06 aa dd ee ll  
gerard  06 64 34 22 68 --> 06 64 43 22 86  lettres 06 gg ee rr aa

File: td_note_2016.tex, line 124


def transforme_numero(prenom, numero):
    # ....
    return 

File: td_note_2016.tex, line 158


Adèle   06 64 34 22 67 --> 06 60 34 24 67  lettres 06 aa dd ee ll  
Gérard  06 64 34 22 68 --> 06 64 37 22 64  lettres 06 gg ee rr aa

File: td_note_2016.tex, line 166


def transforme_numero(prenom, numero):
    # ....
		return 

File: td_note_2016.tex, line 198


def rendement(x, n, r):
    # ....
    return

File: td_note_2016.tex, line 206


def mensualites(K,M,p):
    # ....
    return [ liste de mensualités ]

File: td_note_2016.tex, line 215


def somme_maximale(M,p,Y):
    # ....
    return K max

File: td_note_2016.tex, line 224


def economie(A,S,L,r,Y):
    # ....
    return economie

File: td_note_2016.tex, line 233


def bascule(A,S,L,r,Y,C,p):
    # ....
    return nombre d'années

File: td_note_2016.tex, line 256


def A40a30(L,r,Y,C,p):
    # ....
    return surface

, correction 2012

# coding: latin-1
# question 1
def frequence_lettre (mot) :
    res = { }
    for c in mot :
        if c in res : res[c] += 1
        else : res [c] = 1
    return res
    
print frequence_lettre ("aviateur")
# affiche {'a': 2, 'e': 1, 'i': 1, 'r': 1, 'u': 1, 't': 1, 'v': 1}

# Deux autres écritures de la fonction
def frequence_lettre (mot) :
    res = { c:0 for c in mot }
    for c in mot : res[c] += 1
    return res
    
def frequence_lettre (mot) :
    res = { }
    for c in mot : 
        # la méthode get retourne res[c] si cette valeur existe, 0 sinon
        res[c] = res.get( c, 0 ) + 1
    return res
    
# question 2

def anagramme (mot1, mot2) :
    h1 = frequence_lettre(mot1)
    h2 = frequence_lettre(mot2)
    
    # il fallait éviter d'écrire la ligne suivante bien qu'elle retourne le résultat cherché :
    # return h1 == h2
    
    for c in h1 :
        if c not in h2 or h1[c] != h2[c] : return False
    # il ne faut pas oublier cette seconde partie
    for c in h2 :
        if c not in h1 : return False
    return True
    
a,b = "anagramme", "agrammane"
print anagramme (a,b), anagramme (b,a) # affiche True, True

# on vérifie que la fonctionne marche aussi dans l'autre cas
a,b = "anagramme", "agrummane"
print anagramme (a,b), anagramme (b,a) # affiche False, False

# on pouvait faire plus rapide en éliminant les cas évidents
def anagramme (mot1, mot2) :
    if len(mot1) != len(mot2) : return False
    h1 = frequence_lettre(mot1)
    h2 = frequence_lettre(mot2)
    if len(h1) != len(h2) : return False

    for c in h1 :
        if h1[c] != h2.get(c, 0) : return False
    return True

, correction 2012

# coding: latin-1

# question 1

def factorielle (n) :
    res = 1
    while n > 1 : 
        res *= n
        n -= 1
    return res
    
print factorielle (3)
    
# voici la version récursive qui n'était pas demandée :    
def factorielle_recursive (n) :
    return n*factorielle_recursive (n-1) if n > 1 else 1
        
# question 2

def f(a,b) :
    
    # f(a,b) = f(a-1,b) + f(a,b-1)
    # la formule implique de calculer toutes les valeurs f(i,j)
    # avec (i,j) dans [[0,a]] x [[0,b]]
    # un moyen afin d'éviter de trop nombreux calculs est de 
    # stocker les valeurs intermédiaires de f dans une matrice
    # il faut ensuite s'assurer que f(a-1,b) et f(a,b-1) 
    # ont déjà été calculées avant de calculer f(a,b)
    # pour cela, on parcourt la matrice dans le sens des i et j croissants
    # il ne faut pas oublier les a+1,b+1 car range (a) est égal à [ 0,1, ..., a-1 ]
    
    mat = [ [ 0 for i in range (b+1) ] for j in range (a+1) ]
    for i in range (a+1) :
        for j in range (b+1) :
                if i == 0 or j == 0 :
                    mat [i][j] = max (i,j)
                else :
                    mat [i][j] = mat [i-1][j] + mat[i][j-1]
    return mat [a][b]

# on teste pour des valeurs simples
print f(0,5) # affiche 5
print f(1,1) # affiche 2
# on vérifie en suite que cela marche pour a < b et b > a
print f (4,5)  # affiche 210
print f (5,4)  # affiche 210

# autres variantes

# la version récursive ci-dessous est juste beaucoup plus longue, elle appelle
# la fonction f_recursive autant de fois que la valeur retournée 
# par la fonction cout_recursive alors que la fonction précédente 
# effectue de l'ordre de O(a*b) calculs
def f_recursive(a,b) :
    return f_recursive(a-1,b) + f_recursive(a,b-1) if a > 0 and b > 0 else max(a,b)

def cout_recursive(a,b) :
    return cout_recursive(a-1,b) + cout_recursive(a,b-1) if a > 0 and b > 0 else 1

# une autre version non récursive
def f(a,b) :
    mat = { }
    for i in range (a+1) :
        for j in range (b+1) :
                mat [i,j] = mat [i-1,j] + mat[i,j-1] if i > 0 and j > 0 else max (i,j)
    return mat [a,b]

, correction 2012

def f_recursive(a,b, memoire) :
    if (a,b) in memoire : return memoire [a,b]
    else : 
        res = f_recursive(a-1,b, memoire) + f_recursive(a,b-1, memoire) \
                    if a > 0 and b > 0 else max(a,b)
        memoire [a,b] = res
        return res

, correction 2012

# coding: latin-1

# question 1

def somme_partielle (li, i, j) :
    r = 0
    for a in range (i,j) :
        r += li [a]
    return r
    
# question 2

def plus_grande_sous_liste (li) :
    meilleur = min(li)               # ligne A
    im,jm = -1,-1
    for i in range (0,len(li)) :
        for j in range (i+1, len(li)+1) :   # ne pas oublier +1 car sinon
                        # le dernier élément n'est jamais pris en compte
            s = somme_partielle(li, i,j)
            if s > meilleur :
                meilleur = s
                im,jm = i,j
    return li [im:jm]
    
# si li ne contient que des valeurs positives, la solution est évidemment la liste entière
# c'est pourquoi il faut tester cette fonction avec des valeurs négatives
li = [ 4,-6,7,-1,8,-50,3]
m  = plus_grande_sous_liste(li)
print(m)   # affiche [7, -1, 8]

li = [1,2,3,4,5,-98,78,9,7,7]
m  = plus_grande_sous_liste(li)
print(m)   # affiche [79, 9, 7, 7]

# autre version plus courte

def plus_grande_sous_liste (li) :
    solution = [ (somme_partielle(li,i,j), i, j) \
                    for i in range (0,len(li)) \
                    for j in range (i+1, len(li)+1) ]
    m = max(solution)
    return li [m[1]:m[2]]

, correction 2012

def plus_grande_sous_liste_n2 (li) :
    meilleur = 0
    im,jm = -1,-1
    for i in range (0,len(li)) :
        s = 0
        for j in range (i, len(li)) :
            s += li[j]
            if s > meilleur :
                meilleur = s
                im,jm = i,j+1
    return li [im:jm]
    
li = [ 4,-6,7,-1,8,-50,3]
m  = plus_grande_sous_liste_n2(li)
print(m)   # affiche [7, -1, 8]

li = [1,2,3,4,5,-98,78,9,7,7]
m  = plus_grande_sous_liste_n2(li)
print(m)   # affiche [79, 9, 7, 7]    

, correction 2012

#coding:latin-1
def plus_grande_sous_liste_rapide_r (li, i,j) :
    if i == j : return 0
    elif i+1 == j : return li[i],i,i+1
    
    milieu = (i+j)//2
    
    # on coupe le problème deux
    ma,ia,ja = plus_grande_sous_liste_rapide_r (li, i, milieu)
    mb,ib,jb = plus_grande_sous_liste_rapide_r (li, milieu, j)
    
    # pour aller encore plus vite dans un cas précis
    if ja == ib :
        total = ma+mb
        im,jm = ia,jb
    else :
        # on étudie la jonction
        im,jm = milieu,milieu+1
        meilleur = li[milieu]
        s = meilleur
        for k in range (milieu+1, j) :
            s += li[k]
            if s > meilleur :
                meilleur = s
                jm = k+1
                
        total = meilleur
        meilleur = li[milieu]
        s = meilleur
        for k in range (milieu-1, i-1, -1) :
            s += li[k]
            if s > meilleur :
                meilleur = s
                im = k
        
        total += meilleur - li[milieu]
            
    if   ma >= max(mb,total) : return ma,ia,ja
    elif mb >= max(ma,total) : return mb,ib,jb
    else : return total,im,jm
        
def plus_grande_sous_liste_rapide (li) :
    m,i,j = plus_grande_sous_liste_rapide_r (li,0,len(li))
    return li[i:j]
        
li = [ 4,-6,7,-1,8,-50,3]
m  = plus_grande_sous_liste_rapide(li)
print(m)   # affiche [7, -1, 8]

li = [1,2,3,4,5,-98,78,9,7,7]
m  = plus_grande_sous_liste_rapide(li)
print(m)   # affiche [79, 9, 7, 7]    

, correction 2012

#-*- coding: latin-1 -*-
def plus_grande_sous_liste_n (li) :
    meilleur = [ None for i in li ]
    somme    = [ None for i in li ]
    best     = None
        
    for i,el in enumerate(li):
        if i == 0 or meilleur[i-1] is None:
            meilleur[i] = i
            somme[i] = el
            if best is None or somme[i] > somme[best]:
                best = i
        else:
            if el >= 0 or somme[i-1] > -el :
                meilleur[i] = meilleur[i-1] 
                somme[i] = somme[i-1] + el
                if best is None or somme[i] > somme[best]:
                    best = i
                
    i,j = meilleur[best], best+1
    return li [i:j]
    
li = [ 4,-6,7,-1,8,-50,3]
m  = plus_grande_sous_liste_n(li)
print(m)   # affiche [7, -1, 8]

li = [1,2,3,4,5,-98,78,9,7,7]
m  = plus_grande_sous_liste_n(li)
print(m)   # affiche [79, 9, 7, 7]    

File: interro_rapide_45_minutes_2012_12.tex, line 24


s = [ random.randint(0,20) for i in range(0,10000) ]

, correction 2012

#coding:latin-1
# correction exerice 1
import random

# question 1, version 1 (version abrégée)
def ecart_moyen (s) :
    positions = [ j for j,e in enumerate(s) if e == 0 ]
    dd = [ positions[j] - positions[j-1] for j in range(1,len(positions)) ]
    # une division entière retourne 0, il faut multiplier par 1.0
    return 1.0*sum(dd) / len(dd)
    
s = [ random.randint(0,20) for i in range(0,10000) ]
print ecart_moyen(s)
    
# question 1, version 2 (version plus longue)
def ecart_moyen (s) :
    positions = [ ]
    for j in range(len(s)) :
        if s[j] == 0 : positions.append (j)
    ecart = 0
    for j in range(len(positions)-1) :
        ecart += positions[j+1] - positions[j]
    # on 
    return ecart*1.0 / (len(positions)-1)

# question 1, version 3 (version courte + astuce)
def ecart_moyen (s) :
    # moyenne des écarts = (dernière position - première position) / (nombre de positions - 1)
    positions = [ j for j,e in enumerate(s) if e == 0 ]
    return (positions [-1] - positions [0])*1.0 / (len(positions)-1)

# question 2, version 1
def tirage_sans_remise () :
    l = [ random.randint(0,20) ]
    while len(l) < 4 :
        x = random.randint(0,20)
        if x not in l : l.append (x)
    return l

def moyenne () :
    s = 0
    for i in range(0,10000) :
        l = tirage_sans_remise ()
        l.sort()
        s1 = l[0]+l[1]
        s2 = l[2]+l[3]
        if s1*2 >= s2 : s+=1
    return s*1.0/10000
    
print "v1", moyenne()

# question 2, version 2
def tirage_sans_remise () :
    l = range(0,20)
    random.shuffle(l)
    return l[:4]

def moyenne () :
    s = 0
    for i in range(0,10000) :
        l = tirage_sans_remise ()
        l.sort()
        s1 = l[0]+l[1]
        s2 = l[2]+l[3]
        if s1*2 >= s2 : s+=1
    return s*1.0/10000
    
print "v2",moyenne()

# question 3
def combinaison (N = 100) :
    # res [ n,p ]
    res = { }
    res [0,0] = res [1,0] = res[1,1] = 1.0
    for n in range (2, N) :
        res [n,0] = 1.0
        res [n,n] = 1.0
        for p in range (1,n/2+1) :
            res [n,p]   = res [n-1,p] + res[n-1,p-1]
            res [n,n-p] = res [n,p]
    return res
    
if False :  #  pour éviter des affichages trop longs
    d = combinaison (100)
    for n,p in sorted(d) :
        print "c(n=%d,p=%s)=%f" % (n,p,d[n,p])

# question 4
def ordonne (mat) :
    # on concatène toutes les lignes
    suml = [ ]
    for l in mat : suml += l
    # on trie
    suml.sort()
    # et on crée une autre matrice
    nc = len(mat[0])  #nombre de colonne
    res = [ suml[ i*nc: i*nc+nc] for i in range (0, len(mat)) ]
    return res
    
l = [[4,5], [3, 7], [1,2] ]
print ordonne(l) # affiche [[1, 2], [3, 4], [5, 7]]

File: interro_rapide_45_minutes_2012_12.tex, line 81


li = [[0, 1, 2, 4], [4, 5, 6, 8], [8, 9, 10, 12], [12, 13, 14, 16]]
random.shuffle(li)
print li  # example : [[8, 9, 10, 12], [12, 13, 14, 16], [4, 5, 6, 8], [0, 1, 2, 4]]

File: interro_rapide_45_minutes_2012_12.tex, line 92


l = ["chat", "chats", "chien", "chiens", "cheval", "chevaux" ]
def nombre_moyen_voyelles (l) :
   ...

File: interro_rapide_45_minutes_2012_12.tex, line 108


mots  = ["paris", "texas", "montmartre", "wim", "wenders", "france"]
texte = "paris texas est un film de wim wenders ce paris n'est pas en france mais au texas"]

, correction 2012

#coding:latin-1
# correction exerice 2
import random

# question 1, version 1
# l'astuce consiste à transposer la matrice
def shuffle_colonne (li) :
    tr  = [ [ li [j][i] for j in range(len(li[0])) ] for i in range(len(li))] 
    random.shuffle(tr)
    res = [ [ tr [j][i] for j in range(len(tr[0])) ] for i in range(len(tr))] 
    return res
    
li = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]
print shuffle_colonne (li)

# question 2 
def nombre_moyen_voyelle (l) :
    s = 0   # nombre total de voyelles
    ts = 0  # nombre total de lettres
    for m in l :
        ts += len(m)
        for c in m :
            if c in "aeiouy" : s += 1
    return s * 1.0 / ts

l = ["chat", "chats", "chien", "chiens", "cheval", "chevaux" ]
print "voyelle", nombre_moyen_voyelle (l)  #  0.3333

# question 3
def tirage_avec_remise () :
    l = [ random.randint(0,20) for i in range(0,4) ]
    l.sort()
    return l
    
def moyenne () :
    s = 0
    for i in range(0,10000) :
        l = tirage_avec_remise ()
        l.sort()
        s1 = l[0]+l[1]
        s2 = l[2]+l[3]
        if s1*2 >= s2 : s+=1
    return s*1.0/10000
    
print "v1", moyenne()

# question 4, version 1
def compte_pairs (mots, texte) :
    p = 0
    for m in mots :
        for mm in mots :
            t = m + " " + mm
            if t in texte :
                p += 1
    return p

mots = ["paris", "texas", "montmartre", "wim", "wenders", "france"]
texte = "paris texas est un film de wim wenders ce paris n'est pas en france mais au texas"
print compte_pairs(mots, texte)  # affiche 2

# question 4, version 2
def compte_pairs (mots, texte) :
    dec = texte.split()
    p = 0
    for i in range(1,len(dec)) :
        if dec[i-1] in mots and dec[i] in mots :
            p += 1
    return p

mots = ["paris", "texas", "montmartre", "wim", "wenders", "france"]
texte = "paris texas est un film de wim wenders ce paris n'est pas en france mais au texas"
print compte_pairs(mots, texte)  # affiche 2

File: exercice_2013_leftover.tex, line 25


l = ["par", "parti", "pas", "pars"]
t = "parpasparspasparti"

File: exercice_2013_leftover.tex, line 31


s.startswith(d) # retourne True si la chaîne de caractères s
                # commence par d
s [i:j]         # extrait la sous-chaîne de caractère entre les positions i et j (exclu)

File: exercice_2013_leftover.tex, line 49


l = ["a", "aa"]
t = "aaa"

, correction 2012

#coding:latin-1

def decoupage (mots, texte) :
    res = [ ]
    
    # si le texte est vide, le résultat l'est aussi
    if len(texte) == 0 :
        return res
    
    # on parcourt tous les mots de la liste
    for m in mots :
        if texte.startswith (m) :
            # si un mot commence la chaîne de caractères texte
            # on ajoute ce mot au résultat
            res.append (m)
            # on soustrait ce mot au texte
            texte = texte [ len(m) : ]
            # on appelle la fonction decoupage sur le reste du texte
            res += decoupage (mots, texte)
            return res
    
    # si aucun mot de la liste ne commence texte
    res.append (texte[0])
    texte = texte [ 1 : ]
    res += decoupage (mots, texte)
    return res
    
l = ["par", "parti", "pas", "pars"]
t = "parpasparspasparti"
d = decoupage (l, t)    
print d             # ['par', 'pas', 'par', 's', 'pas', 'par', 't', 'i']
print " ".join (d)  # par pas par s pas par t i

File: exercice_2013_leftover.tex, line 60


# on trie les mots par ordre décroissant de taille
l = [ (len(m), m) for m in l ]
l.sort(reverse = True)
l = [ c[1] for c in l ]
d = decoupage (l, t)    
print " ".join (d)   # par pas pars pas parti

, correction 2012

#coding:latin-1

def decoupage (mots, texte) :
    res = [ ]
    
    # on parcourt tous les mots de la liste
    while len(texte) > 0 :
        # on a besoin de cette variable pour dire si on a trouvé un mot
        # de la liste qui commence texte
        motliste = False
        for m in mots :
            if texte.startswith (m) :
                res.append (m)
                texte = texte [ len(m) : ]
                motliste = True
                break
                
        if not motliste :
            res.append (texte[0])
            texte = texte [ 1 : ]

    return res
    
l = ["par", "parti", "pas", "pars"]
t = "parpasparspasparti"
d = decoupage (l, t)    
print " ".join (d)  # par pas par s pas par t i

, correction 2012

#coding:latin-1

def decoupages (mots, texte) :
    res = [ ]
    
    if len(texte) == 0 :
        return res
    
    trouve = False
    for m in mots :
        if texte.startswith (m) :
            trouve = True
            fin = texte [ len(m) : ]
            ds  = decoupages (mots, fin)
            if len(ds) == 0 :
                # dans ce cas, cela veut dire fin est vide
                # le seul découpage possible est [ m ]
                res.append ( [ m ] )
            else :
                # dans ce cas, l'ensemble des découpages possibles 
                # est construit selon le schéma suivant :
                #    m + un découpage de ds
                for d in ds :
                    td = [ m ] + d
                    res.append ( td )
    
    if not trouve :
        # ici, on retrouve le même code que précédemment
        # mais pour un seul caractère
        m   = texte [0]
        fin = texte [ 1 : ]
        ds  = decoupages (mots, fin)
        if len(ds) == 0 :
            res.append ( [ m ] )
        else :
            for d in ds :
                td = [ m ] + d
                res.append ( td )

    return res
    
l  = ["par", "parti", "pas", "pars"]
t  = "parpasparspasparti"
ds = decoupages (l, t)    
for d in ds : print " ".join (d)

l  = ["a", "aa"]
t  = "aaa"
ds = decoupages (l, t)    
for d in ds : print " ".join (d)

File: exercice_2013_leftover.tex, line 80


par pas par s pas par t i
par pas par s pas parti
par pas pars pas par t i
par pas pars pas parti
a a a
a aa
aa a

File: exercice_2013_leftover.tex, line 92


l  = ["a", "aa", "b", "bb"]
t  = "aaabbb"
ds = decoupages (l, t)    
for d in ds : print " ".join (d)

File: exercice_2013_leftover.tex, line 102


a a a b b b
a a a b bb
a a a bb b
a aa b b b
a aa b bb
a aa bb b
aa a b b b
aa a b bb
aa a bb b

File: exercice_2013_leftover.tex, line 116


1 aaabbb
2 aabbb
3 abbb
4 bbb
5 bb
6 b
7 b
8 bbb
9 bb
10 b
11 b
12 abbb
13 bbb
14 bb
15 b
16 b

, correction 2012

#coding:latin-1

def decoupage (mots, texte) :
    res = [ ]
    
    # si le texte est vide, le résultat l'est aussi
    if len(texte) == 0 :
        return res
    
    # on parcourt tous les mots de la liste
    for m in mots :
        if texte.startswith (m) :
            # si un mot commence la chaîne de caractères texte
            # on ajoute ce mot au résultat
            res.append (m)
            # on soustrait ce mot au texte
            texte = texte [ len(m) : ]
            # on appelle la fonction decoupage sur le reste du texte
            res += decoupage (mots, texte)
            return res
    
    # si aucun mot de la liste ne commence texte
    res.append (texte[0])
    texte = texte [ 1 : ]
    res += decoupage (mots, texte)
    return res
    
l = ["par", "parti", "pas", "pars"]
t = "parpasparspasparti"
d = decoupage (l, t)    
print d             # ['par', 'pas', 'par', 's', 'pas', 'par', 't', 'i']
print " ".join (d)  # par pas par s pas par t i

File: exercice_2013_leftover.tex, line 142


1 aaabbb
2 aabbb
3 abbb
4 bbb
5 bb
6 b

File: exercice_2013_leftover.tex, line 176


a = 10.**i/3
c = 10.**(-i)/4*3
b = 1

File: exercice_2013_leftover.tex, line 189


import time, math
debut = time.clock()


y = 0
N = 1000000

for i in range (1,N+1) :
    s  = i*1.0/N
    x  = math.log(s)
    y += x

fin   = time.clock()
print "integ ",y/N
print "temps ",fin - debut

File: exercice_2013_leftover.tex, line 209


import time, math
debut = time.clock()


y = 0
N = 1000000
z = math.log(N)
for i in range (1,N+1) :

    x  = math.log(i*1.0)
    y += x
y -= z*N
fin   = time.clock()
print "integ ",y/N
print "temps ",fin - debut

File: exercice_2013_leftover.tex, line 229


import time, math
debut = time.clock()
def monlog (i) : 
    return math.log(i)
y = 0
N = 1000000
z = math.log(N)
for i in range (1,N+1) :

    x  = monlog(i*1.0)
    y += x
y -= z*N
fin   = time.clock()
print "integ ",y/N
print "temps ",fin - debut

File: exercice_2013_leftover.tex, line 249


integ -0.999992173306
temps  0.780309832669

File: exercice_2013_leftover.tex, line 256


integ -0.999992173306
temps 0.5965760959

File: exercice_2013_leftover.tex, line 263


integ -0.999992173306
temps 0.698039702544

File: exercice_2013_leftover.tex, line 281


import time, math



debut = time.clock()


y = 0
N = 1000000
z = math.log(N)
for i in range (1,N+1) :
    x  = math.log(i*1.0)
    y += x
y -= z*N
fin   = time.clock()
print "integ ",y/N
print "temps ",fin - debut

File: exercice_2013_leftover.tex, line 303


import time, math



debut = time.clock()
def monlog (i) : 
    return math.log(i)
y = 0
N = 1000000
z = math.log(N)
for i in range (1,N+1) :
    x  = monlog(i*1.0)
    y += x
y -= z*N
fin   = time.clock()
print "integ ",y/N
print "temps ",fin - debut

File: exercice_2013_leftover.tex, line 325


import time, math
memolog = { }                   
for i in range(1,N+1) :         
    memolog [i] = math.log(i)   
debut = time.clock()


y = 0
N = 1000000
z = math.log(N)
for i in range (1,N+1) :
    x  = memolog[i]             
    y += x
y -= z*N
fin   = time.clock()
print "integ ",y/N
print "temps ",fin - debut

File: exercice_2013_leftover.tex, line 347


integ -0.999992173306
temps 0.6014340817

File: exercice_2013_leftover.tex, line 354


integ -0.999992173306
temps 0.68944518564

File: exercice_2013_leftover.tex, line 361


integ -0.999992173306
temps 0.424331883008

File: exercice_2013_leftover.tex, line 387


l = ["par", "parti", "pas", "pars"]
t = "parpasparspasparti"

File: exercice_2013_leftover.tex, line 393


s.startswith(d) # retourne True si la chaîne de caractères s
                # commence par d
s [i:j]         # extrait la sous-chaîne de caractère entre les positions i et j (exclu)

File: exercice_2013_leftover.tex, line 410


a = 10.0**i/3        # ne pas changer 10.0 en 10 pour éviter 
c = 10.0**(-i)/4*3   # les problèmes de calculs avec des entiers
b = 1                # ** est l'opérateur puissance

, correction 2012

# coding: latin-1
# question 1
def frequence_lettre (mot) :
    res = { }
    for c in mot :
        if c in res : res[c] += 1
        else : res [c] = 1
    return res
    
print frequence_lettre ("aviateur")
# affiche {'a': 2, 'e': 1, 'i': 1, 'r': 1, 'u': 1, 't': 1, 'v': 1}

# Deux autres écritures de la fonction
def frequence_lettre (mot) :
    res = { c:0 for c in mot }
    for c in mot : res[c] += 1
    return res
    
def frequence_lettre (mot) :
    res = { }
    for c in mot : 
        # la méthode get retourne res[c] si cette valeur existe, 0 sinon
        res[c] = res.get( c, 0 ) + 1
    return res
    
# question 2

def anagramme (mot1, mot2) :
    h1 = frequence_lettre(mot1)
    h2 = frequence_lettre(mot2)
    
    # il fallait éviter d'écrire la ligne suivante bien qu'elle retourne le résultat cherché :
    # return h1 == h2
    
    for c in h1 :
        if c not in h2 or h1[c] != h2[c] : return False
    # il ne faut pas oublier cette seconde partie
    for c in h2 :
        if c not in h1 : return False
    return True
    
a,b = "anagramme", "agrammane"
print anagramme (a,b), anagramme (b,a) # affiche True, True

# on vérifie que la fonctionne marche aussi dans l'autre cas
a,b = "anagramme", "agrummane"
print anagramme (a,b), anagramme (b,a) # affiche False, False

# on pouvait faire plus rapide en éliminant les cas évidents
def anagramme (mot1, mot2) :
    if len(mot1) != len(mot2) : return False
    h1 = frequence_lettre(mot1)
    h2 = frequence_lettre(mot2)
    if len(h1) != len(h2) : return False

    for c in h1 :
        if h1[c] != h2.get(c, 0) : return False
    return True

programme non corrigé


def fonction_mystere(a,b) :
    am = a.split()
    bm = b.split()
    r = 0
    for c in am :
        if c in bm :
            r += 1
    return r / (len(am)-r+len(bm)
    
print ( fonction_mystere ("deux mots", "et trois mots"))

File: interro_rapide_30_minutes_2013_10.tex, line 39


  File "interro_rapide_30_minutes_2013_10_1.py", line 10
    print ( fonction_mystere ("deux mots", "et trois mots"))
        ^
SyntaxError: invalid syntax

même fonction gérant le cas des mots vides


def fonction_mystere(a,b) :
    am = a.split()
    bm = b.split()
    if len(am) == 0 and len(bm) == 0 : return 0.0
    r = 0
    for c in am :
        if c in bm :
            r += 1
    return r / (len(am)-r+len(bm))

triangle de Pascal


pascal = { }
for i in range(1,100) :                                   # A
    pascal[i,0] = 1                                       
    pascal[i,i] = 1                                       # B
    for j in range(0,i) :                                 # C
        pascal [i,j] = pascal [i-1,j-1] + pascal[i-1,j]  (ligne 10 mentionnée dans l'erreur)
print (pascal[5,4])				

File: interro_rapide_45_minutes_2013_12.tex, line 43


Traceback (most recent call last):
  File "interro_rapide_45_minutes_2013_12_1.py", line 10, in <module>
    pascal [i,j] = pascal [i-1,j-1] + pascal[i-1,j]
KeyError: (0, -1)

calcul de la somme des chiffres d'un entier positif (1)


def somme_chiffre (i) :
    return sum ( [ int(c) for c in str(i) ] )

print (somme_chiffre(199))

calcul de la somme des chiffres d'un entier positif (2)


def somme_chiffre (i) :
    s = 0
    while i > 0 :
        s += i % 10
        i //= 10
    return s

divisible par 11


def division_11 (i) :    
    spair = 0
    simpair = 0
    pos = 1  # la première position est 1
    while i > 0 :
        if pos % 2 == 0 : spair += i % 10
        else : simpair += i % 10
        i //= 10
        pos += 1
    
    diff = abs(spair - simpair)
    
    if diff == 0 : return True 
    elif diff < 11 : return False
    elif diff == 11 : return True
    else : return division_11(diff)

for i in [7,11,55,100,121,1001,3003,4000] :
    print (i,division_11(i))

suite de Fibonacci


n = 100
fibo = [ 0 ] * (n+1)                    # A
fibo[0] = 1 
for i in range(2,n) :                   # B
    fibo[i] = fibo[i-1] + fibo[i-2]     # C
print (fibo[n])  #affiche zéro          

diviseurs d'un nombre entier


def diviseur (i) :
    div = [ ]
    for d in range (1, i//2+1) :
        if i % d == 0 : div.append(d)
    return div
    
print (diviseur (11))
print (diviseur (512))

nombre parfait


def nombre_parfait (i) :
    div = diviseur(i)
    return sum(div) == 2*i

for i in range(115,125) :
    print (i, nombre_parfait(i), diviseur(i))

question 1.1 : remplacer des accents

		

File: interro_rapide_20_minutes_2014_10.tex, line 31


from math import log
s = 0
N = 100
while N > 1 :
    for i in range(1, N):
        s += log(i)
    N //= 2
print(s)

question 1.1 : remplacer des accents

		

File: interro_rapide_20_minutes_2014_10.tex, line 83


s = 0
ii = 1
N = 7
for i in range(1,N):
    ii *= 2
    for k in range(1,ii):
        s += log(k)
print(s)

File: interro_rapide_20_minutes_2014_11.tex, line 23


nbs = [ 1, 5, 4, 7 ]
for n in nbs:
    s += n

----> 3     s += n
NameError: name 's' is not defined

File: interro_rapide_20_minutes_2014_11.tex, line 35


def f(x) : return x%2
nbs = { i:f(i) for i in range(0,5) }

File: interro_rapide_20_minutes_2014_11.tex, line 42


def ma_fonction(x1,y1,x2,y2):
    d = (x1-x2)**2 +(y1-y2)**2
    print(d)
d = ma_fonction(0,0,1,1)
print(d)
-----
2
None

File: interro_rapide_20_minutes_2014_11.tex, line 55


n = 0
N = 100
for i in range(0,N):
    for k in range(0,i):
        n += N

File: interro_rapide_20_minutes_2014_11.tex, line 66


a = 3
b = "6"
a+b
a*b

File: interro_rapide_20_minutes_2014_11.tex, line 91


nbs = ( 1, 5, 4, 7 )
nbs[0] = 0

----> 2 nbs[0] = 0
TypeError: 'tuple' object does not support item assignment

File: interro_rapide_20_minutes_2014_11.tex, line 102


d = {4: 'quatre'}
c = d.get('4', None)

File: interro_rapide_20_minutes_2014_11.tex, line 109


N = 8
s = 0
while N > 0 :
    for i in range(N):
        s += 1
    N //= 2
x = (s+1)//2

File: interro_rapide_20_minutes_2014_11.tex, line 121


l = ['a', 'b', 'c']
c = l[1]

File: interro_rapide_20_minutes_2014_11.tex, line 128


def fonction(N):
    l = None
    for i in range(N):
        if l is None : l = [ ]
        l.append(i)
    return l
ma_liste = fonction(???)
ma_liste.append(-1)
----
----> 8 ma_liste.append(-1)
AttributeError: 'NoneType' object has no attribute 'append'

File: interro_rapide_20_minutes_2014_11.tex, line 171


l = [ 0, 1,2,3]
for i in range(len(l)):
    print(i)
    del l[i]
----
0
1
2
----
----> 4     del l[i]
IndexError: list assignment index out of range

File: interro_rapide_20_minutes_2014_11.tex, line 187


a = 2
for i in range(1,5):
    a += a

File: interro_rapide_20_minutes_2014_11.tex, line 198


x = 2.67
y = int ( x * 2 ) / 2

File: interro_rapide_20_minutes_2014_11.tex, line 206


def moyenne(l):
    s = 0 
    for x in l : 
        print("*")
        s += x
    return s / len(l)
def variance(l):
    return sum ( [ (x - moyenne(l))**2 for x in l  ] ) / len(l)
l = [ random.random() for i in range(0,100) ]
print(variance(l)**0.5)

File: interro_rapide_20_minutes_2014_11.tex, line 221


import random
x = random.randint(0,100)
while x != 50: x = random.randint(0,100)

File: interro_rapide_20_minutes_2015_09.tex, line 23


tab = [1, 3]
for i in range(0, len(tab)):
    print(tab[i] + tab[i+1])

File: interro_rapide_20_minutes_2015_09.tex, line 32


n = 1
if n = 1:
    y = 0
else:
    y = 1

File: interro_rapide_20_minutes_2015_09.tex, line 61


y = "a" * 3 + 1
z = 3 * "a" + 1
print(y,z)

File: interro_rapide_20_minutes_2015_09.tex, line 70


l = []
for i in range(0, 10):
    l.append([i])
print(l)

File: interro_rapide_20_minutes_2015_10.tex, line 23


import random
l = [0, 1, 2, 3, 4]
i = random.randint(0, 5)
del l[i]

File: interro_rapide_20_minutes_2015_10.tex, line 33


mat = {}
for i in range(0,3) and j in range(0,3):
    mat[i,j] = 0

File: interro_rapide_20_minutes_2015_10.tex, line 60


i = 2
if i == 2:
    i = 1
else:
    i = 2

File: interro_rapide_20_minutes_2015_10.tex, line 71


l = {{}}
for i,j in zip(range(0,3), range(0,3)):
    l[i,j] = 1

File: interro_rapide_20_minutes_2015_10.tex, line 79


----> 1 l = {{}}
      2 for i,j in zip(range(0,3), range(0,3)):
      3     l[i,j] = 1
      4 l

TypeError: unhashable type: 'dict'

File: ecrit_2006.tex, line 28


l = [ 0,1,2,3,4,6,5,8,9,10]
res = True
for i in range (1,len (l)) :
    if l[i-1] > l[i] :
        res = False 

File: ecrit_2006.tex, line 58


def somme (n) :
    return sum ( [ int (c) for c in str (n) ] )

File: ecrit_2006.tex, line 66


def somme (n) :
    l = str (n)           # il ne faut pas confondre l=str (n) avec l = "n"
    s = 0
    for c in l :          # ou   for i in range (0, len (c)) :
        s += int (c)      # ou       s += int (c [i])
    return s

File: ecrit_2006.tex, line 78


def somme (n) :
    s = 0
    while n > 0 :
        s += n % 10
        n /= 10    # ici, c'est une division entière, si vous n'êtes pas sûr :  
                   #       n = int (n/10)
    return n

File: ecrit_2006.tex, line 91


def somme (n) :
    if n <= 0 : return 0
    else : return (n % 10) + somme ( n / 10 )

File: ecrit_2006.tex, line 100


import math
def somme (n) :
    k = int (math.log (n) / math.log (10) + 1)
    s = 0
    for i in range (1,k+1) :
        d = 10 ** i   # ou encore d = int (exp ( k * log (10) ) )
        c = n / d
        e = n - c * d
        f = e / (d / 10)
        s += f
    return s

File: ecrit_2006.tex, line 128


n = 0
for i in range (0,10) :
    if (n + i) % 3 == 0 :
        n += 1

File: ecrit_2006.tex, line 177


def grenouille (n) :
    if   n == 2 : return 2
    elif n == 1 : return 1 
    else :        return grenouille (n-1) + grenouille (n-2)
print grenouille (13)

File: ecrit_2006.tex, line 191


def grenouille (fin, n = 2, u1 = 1, u2 = 2) :
    if   fin == 1   : return u1
    elif fin == 2   : return u2
    elif n   == fin : return u2
    u = u1 + u2
    return grenouille (fin, n+1, u2, u)
print grenouille (13)

File: ecrit_2006.tex, line 205


def grenouille (n) :
    if n == 1 : return 1
    u1 = 1
    u2 = 2
    for i in range (3,n+1) :
        u  = u1 + u2   # il est impossible de 
        u1 = u2        # résumer ces trois lignes
        u2 = u         # en deux
    return u2
print grenouille (13)

File: ecrit_2006.tex, line 222


def grenouille (n) :
    if n == 1 : return 1
    u = [1,2]
    for i in range (2,n) :
        u.append (u [i-1] + u [i-2])
    return u [n-1]
print grenouille (12)

File: ecrit_2006.tex, line 236


def grenouille (n) :
    if n == 1 : return 1
    u = range (0, n)  # il ne faut pas oublier de créer le tableau
                      # avec autant de cases que nécessaire
                      # ici 13
    u [0] = 1
    u [1] = 2
    for i in range (2,n) :
        u [i] = u [i-1] + u [i-2]
    return u [n-1]
print grenouille (12)

File: ecrit_2006.tex, line 261


a = "abcdefghijklmnopqrstuvwxyz"
print len (a)
d = {}
for i in range (0,len (a)) :
    d [ a [ i ] ] = i

print d ["M"]

File: ecrit_2006.tex, line 274


examen.py:14:  KeyError: 'M'

File: ecrit_2006.tex, line 288


a = "abcdefghijklmnopqrstuvwxyz"
print len (a)
d = {}
for i in range (0,len (a)) :
    d [ a [ i ] ] = i
    
print d ["m"]         ######   ligne modifiée

File: ecrit_2006.tex, line 301


a = "abcdefghijklmnopqrstuvwxyz"
a = a.upper ()        #######   ligne ajoutée
print len (a)
d = {}
for i in range (0,len (a)) :
    d [ a [ i ] ] = i
    
print d ["M"]

File: ecrit_2006.tex, line 324


def somme (tab) :
    l = tab[0]
    for i in range (1, len (tab)) :
        l += tab [i]
    return l
ens = [[0,1],[2,3]] 
print somme ( ens )   # affiche [0,1,2,3]
print ens             # affiche [ [0,1,2,3], [2,3] ]

File: ecrit_2006.tex, line 345


import copy                      ###### ligne ajoutée
def somme (tab) :
    l = copy.copy (tab[0])       ###### ligne modifiée
    for i in range (1, len (tab)) :
        l += tab [i]
    return l
ens = [[0,1],[2,3]] 
print somme ( ens )   # affiche [0,1,2,3]
print ens             # affiche [ [0,1,2,3], [2,3] ]

File: ecrit_2006.tex, line 360


def somme (tab) :
    l = []                            ###### ligne modifiée
    for i in range (0, len (tab)) :   ###### ligne modifiée
        l += tab [i]
    return l
ens = [[0,1],[2,3]] 
print somme ( ens )   # affiche [0,1,2,3]
print ens             # affiche [ [0,1,2,3], [2,3] ]

File: ecrit_2006.tex, line 382


li  = range (0,10)
sup = [0,9]
for i in sup :
    del li [i]
print li

File: ecrit_2006.tex, line 393


examen.py:44:  IndexError: list assignment index out of range

File: ecrit_2006.tex, line 406


[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

File: ecrit_2006.tex, line 410


[ 1, 2, 3, 4, 5, 6, 7, 8, 9]

File: ecrit_2006.tex, line 416


li  = range (0,10)
sup = [9,0]      ####### ligne modifiée
for i in sup :
    del li [i]
print li

File: ecrit_2006.tex, line 439


l = ["un", "deux", "trois", "quatre", "cinq"]
for i in range (0,len (l)) :
    mi = i
    for j in range (i, len (l)) :
        if l[mi] < l [j] : mi = j
    e      = l [i]
    l [mi] = l [i]
    l [i]  = e
print l

File: ecrit_2006.tex, line 455


['un', 'deux', 'deux', 'deux', 'cinq']

File: ecrit_2006.tex, line 470


l = ["un", "deux", "trois", "quatre", "cinq"]
for i in range (0,len (l)) :
    mi = i
    for j in range (i, len (l)) :
        if l[mi] < l [j] : mi = j
    e      = l [mi]       ######## ligne modifiée
    l [mi] = l [i]
    l [i]  = e
print l

File: ecrit_2006.tex, line 499


def moyenne (tab) :
    s = 0.0
    for x in tab : 
        s += x
    return s / len (tab)
    
def variance (tab) :
    s = 0.0
    for x in tab :
        t  = x - moyenne (tab)
        s += t * t
    return s / len (tab)
    
l = [ 0,1,2, 2,3,1,3,0]
print moyenne (l)
print variance (l)

File: ecrit_2006.tex, line 529


def variance (tab) :
    s = 0.0
    m = moyenne (tab)
    for x in tab :
        t  = x - m
        s += t * t
    return s / len (tab)

File: ecrit_2006.tex, line 563


class carre :
    def __init__ (self, a) :
        self.a = a
    def surface (self) :
        return self.a ** 2

class rectangle (carre) :
    def __init__ (self, a,b) :
        carre.__init__(self,a)
        self.b = b
    def surface (self) :
        return self.a * self.b

File: ecrit_2006.tex, line 582


class rectangle :
    def __init__ (self, a,b) :
        self.a = a
        self.b = b
    def surface (self) :
        return self.a * self.b

class carre (rectangle) :
    def __init__ (self, a) :
        rectangle.__init__ (self, a,a)
    def surface (self) :
        return self.a ** 2

File: ecrit_2006.tex, line 616


class carre :
    def __init__ (self, a) :
        self.a = a
    def surface (self) :
        return self.a ** 2

class rectangle (carre) :
    def __init__ (self, a,b) :
        carre.__init__(self,a)
        self.b = b
    def surface (self) :
        return self.a * self.b

class losange (carre) :
    def __init__ (self, a,theta) :
        carre.__init__(self,a)
        self.theta = theta
    def surface (self) :
        return self.a * math.cos (self.theta) * self.a * math.sin (self.theta) * 2

File: ecrit_2006.tex, line 654


x = 1.0
for i in range (0,15) :
    x = x / 10
    print i, "\t", 1.0 - x, "\t", x, "\t", x **(0.5)

File: ecrit_2006.tex, line 664


0    0.90000000000000002220     0.1              0.316227766017
1    0.98999999999999999112     0.01             0.1
2    0.99899999999999999911     0.001            0.0316227766017
3    0.99990000000000001101     0.0001           0.01
4    0.99999000000000004551     1e-05            0.00316227766017
5    0.99999899999999997124     1e-06            0.001
6    0.99999990000000005264     1e-07            0.000316227766017
7    0.99999998999999994975     1e-08            0.0001
8    0.99999999900000002828     1e-09            3.16227766017e-05
9    0.99999999989999999173     1e-10            1e-05
10   0.99999999998999999917     1e-11            3.16227766017e-06
11   0.99999999999900002212     1e-12            1e-06
12   0.99999999999989996891     1e-13            3.16227766017e-07
13   0.99999999999999000799     1e-14            1e-07
14   0.99999999999999900080     1e-15            3.16227766017e-08
15   0.99999999999999988898     1e-16            1e-08
16   1.00000000000000000000     1e-17            3.16227766017e-09
17   1.00000000000000000000     1e-18            1e-09
18   1.00000000000000000000     1e-19            3.16227766017e-10
19   1.00000000000000000000     1e-20            1e-10

File: ecrit_2006.tex, line 691


class matrice_carree_2 :
    def __init__ (self, a,b,c,d) :
        self.a, self.b, self.c, self.d = a,b,c,d
        
    def determinant (self) :
        return self.a * self.d - self.b * self.c
        
m1 = matrice_carree_2 (1.0,1e-6,1e-6,1.0)
m2 = matrice_carree_2 (1.0,1e-9,1e-9,1.0)
print m1.determinant ()
print m2.determinant ()

File: ecrit_2006.tex, line 729


def valeurs_propres (self) :
    det   = self.determinant ()
    trace = self.a + self.d
    delta = trace ** 2 - 4 * det
    l1    = 0.5 * (trace - (delta ** (0.5)) )
    l2    = 0.5 * (trace + (delta ** (0.5)) )
    return l1,l2

File: ecrit_2006.tex, line 768


0.99999999999900002212
1.00000000000000000000

File: ecrit_2006.tex, line 777


l1    = 0.5 * (trace - ((trace ** 2 - 4 * det) ** (0.5)) )
l2    = 0.5 * (trace + ((trace ** 2 - 4 * det) ** (0.5)) )

File: ecrit_2006.tex, line 785


l1 = 1,000001
l2 = 0.99999899999999997124  # égale à 1 - 1e-6

File: ecrit_2006.tex, line 793


l1 = 1
l2 = 1

File: ecrit_2006.tex, line 801


l1    = 0.5 * (trace - ((trace ** 2 - 4 * det) ** (0.5)) ) = - det ** 0.5 = -1e-9
l2    = 0.5 * (trace + ((trace ** 2 - 4 * det) ** (0.5)) ) = det ** 0.5 = 1e-9

File: ecrit_2006.tex, line 809


l1    = 1-1e-9  = 0.99999999900000002828
l2    = 1+ 1e-9 = 1.000000001

File: ecrit_2007.tex, line 28


def fonction_log2 (k) :
    n = 0
    while 2**n < k :
        n += 1
    return n

File: ecrit_2007.tex, line 38


def fonction_log2 (k) :
    for i in range (0,1000) :
        if 2**i >= k :
            return i

File: ecrit_2007.tex, line 47


def fonction_log2 (k) :
    if k <= 1 : return 0
    else : return fonction_log2 ((k+1)/2)+1

File: ecrit_2007.tex, line 63


def parcours (n) :
    i = 1
    j = 1
    while i+j < n :
        print (i,j)
        i += 1
        j -= 1
        if j < 1 :
            j = i+j
            i = 1

File: ecrit_2007.tex, line 101


(1,1)
(1,2)
(2,1)
(1,3)
(2,2)
(3,1)



File: ecrit_2007.tex, line 115


(1,4)
(2,3)
(3,2)
(4,1)
(1,5)
(2,4)
(3,3)
...

File: ecrit_2007.tex, line 130


i += 1
j -= 1

File: ecrit_2007.tex, line 137


if j < 1 :
    j = i+j
    i = 1

File: ecrit_2007.tex, line 155


def suite (n) :
    n = n ** 2 / 2 + 1
    return n
            
n = 3
for i in range (0,10) :
    n = suite (n) % 17
print n

File: ecrit_2007.tex, line 198


def ensemble_lettre (s) :
    ens = []
    for i in range (0, len (s)) :
        c = s [i]
        if c in ens :
            ens.append (c)
    return ens
        
print lettre ("baaa")

File: ecrit_2007.tex, line 225


def compte_lettre (s) :
    nombre = {}
    for c in s :
        nombre [c] += 1
    return nombre
    
print compte_lettre ( "mysteres" )

File: ecrit_2007.tex, line 237


KeyError: 'm'

File: ecrit_2007.tex, line 261


def compteur (s) :
    nombre = {}
    for c in s : nombre [c] = 0        # ligne ajoutée
    for c in s :
        nombre [c] += 1
    return nombre

File: ecrit_2007.tex, line 273


def compteur (s) :
    nombre = {}
    for c in s : 
        if c not in nombre : nombre [c] = 0       # ligne ajoutée
        nombre [c] += 1
    return nombre

File: ecrit_2007.tex, line 285


{'e': 2, 'm': 1, 's': 2, 'r': 1, 't': 1, 'y': 1}

File: ecrit_2007.tex, line 292


def compteur (s) :
    alpha = "abcdefghijklmnopqrstuvwxyz"
    nombre = [ 0 for c in alpha ]
    for c in s :
        i = alpha.index (c)
        nombre [i] += 1
    return nombre

File: ecrit_2007.tex, line 305


[0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 1, 0]

File: ecrit_2007.tex, line 313


print compteur ( "mysteres" )
print compteur ( compteur ("mysteres") )
print compteur ( [0,1,1,4,-1, (6,0), 5.5, "ch"] )
print compteur ( { 1:1, 2:2, 1:[] } )

File: ecrit_2007.tex, line 323


print compteur ( [0, [0,0] ] )

File: ecrit_2007.tex, line 340



def autre_parcours (n) :
    i = 0
    j = 0
    k = 0
    
    while k < n :
        print (k,i,j)
        if i == 0 and j == 0 :
            k += 1
        if j == 0 and i < k :
            i += 1
        elif i == k and j < k :
            j += 1
        elif j == k and i > 0 :
            i -= 1
        elif i == 0 and j > 0 :
            j -= 1

autre_parcours (3)


File: ecrit_2007.tex, line 379


def ligne_nulle (mat) :
    nb = 0
    for i in range (0, len (mat)) :
        lig = 0
        for j in range (0, len (mat [i])) :
            if mat [i][j] > 0 : lig += 1
            if lig == 0 : nb += 1
    return nb

matri = [ [ random.randint (0,1) for i in range (0,4) ] for j in range (0,20) ]
print ligne_nulle (matri)

File: ecrit_2007.tex, line 417


def ligne_nulle (mat) :
    nb = 0
    for i in range (0, len (mat)) :
        lig = 0
        for j in range (0, len (mat [i])) :
            if mat [i][j] > 0 : lig += 1
        if lig == 0 : nb += 1                      # ligne décalée vers la gauche
    return nb

File: ecrit_2007.tex, line 441


class erreur :
    def __init__ (self) :
        self.e = erreur ()
e = erreur ()

File: ecrit_2007.tex, line 451


Traceback (most recent call last):
  File "examen2007.py", line 4, in ?
    e = erreur ()
  File "examen2007.py", line 2, in __init__
    self.e = erreur ()
  File "examen2007.py", line 2, in __init__
    self.e = erreur ()
  File "examen2007.py", line 2, in __init__
    self.e = erreur ()
  ...

File: ecrit_2007.tex, line 473


class erreur :
    def __init__ (self,e) :
        self.e = e

File: ecrit_2007.tex, line 493


def base3 (n) :
    s = ""
    while n > 0 :
        r = n % 3
        # ....... à compléter
        # ....... à compléter
    return s

File: ecrit_2007.tex, line 512


def base3 (n) :
    s = ""
    while n > 0 :
        r = n % 3
        s = str (r) + s
        n = n / 3            # équivalent à n = (n-r) / 3 
                             # puisque / est une division entière
    return s

File: ecrit_2007.tex, line 534


import copy
import math
import random

class Eleve :
    def __init__ (self, note) :
        self.note = note
        
e = Eleve (0)
l = []
for i in range (0,81) :
    e.note = int (random.gauss (15, 3) + 0.5)  # tirage aélatoire et arrondi
    if e.note >= 20 : e.note = 20              # pas de note au-dessus de 20
    if e.note < 0 : e.note = 0                 # pas de note négative
    l.append (e)
    
moy = 0
var = 0

for e in l :
    moy += e.note    
moy = float (moy) / len (l)  # les notes sont entières, 
                             # il faut convertir avant de diviser
                             # pour obtenir la moyenne
for e in l :
    var += (e.note - moy) ** 2
var = math.sqrt ( float (var) ) / len (l)

print "moyenne ", moy
print "écart-type ", var

File: ecrit_2007.tex, line 570


moyenne  16.0
écart-type  0.0

File: ecrit_2007.tex, line 616


#...
e = Eleve (0)
l = []
for i in range (0,81) :
    e.note = int (random.gauss (15, 3) + 0.5)  
    if e.note >= 20 : e.note = 20              
    if e.note < 0 : e.note = 0                 
    l.append (e.note)                            # ligne modifiée
    
moy = 0
var = 0

for note in l :                                  # ligne modifiée
    moy += note                                  # ligne modifiée
moy = float (moy) / len (l)  
for note in l :                                  # ligne modifiée
    var += (note - moy) ** 2                     # ligne modifiée
var = math.sqrt ( float (var) ) / len (l)

print "moyenne ", moy
print "écart-type ", var

File: ecrit_2007.tex, line 644


moy = 0
var = 0

for note in l :												
    moy += note												
    var += note * note
moy = float (moy) / len (l)  
var = float (var) / len (l)  
var = var - moy * moy
var = math.sqrt ( float (var) ) 

print "moyenne ", moy
print "écart-type ", var

File: ecrit_2007.tex, line 680


def puiss (x, n) :
    s = 1.0
    for i in range (0,n) :
        s *= x
    return s

def log_suite (x) :
    x    = float (x-1)
    # ......
    s    = 0
    old  = -1
    n    = 1
    while abs (old - s) > 1e-10 :
        old = s
        po  = puiss (x,n) / n
        if n % 2 == 0 : po = -po
        s  += po
        n  += 1
        # ......
    return s
    
print log_suite (2)

File: ecrit_2007.tex, line 706


# ......
# ......
# ......
# ......
# ......
# ......
def log_suite (x) :
    x    = float (x-1)
    x0   = x
    s    = 0
    old  = -1
    n    = 1
    while abs (old - s) > 1e-10 :
        old = s
        po  = x / n
        if n % 2 == 0 : po = -po
        s  += po
        n  += 1
        x  *= x0
    return s
    
print log_suite (2)

File: ecrit_2007.tex, line 742


def racine_carree (k) :
    x0 = float (k)+1
    x  = float (k)
    while abs (x-x0) > 1e-10 :
        x0 = x
        x  = (k-x*x) / (2 * x) + x
    return x

File: ecrit_2007.tex, line 768


class Noeud :
    def __init__ (self, mot) :
        self.mot = mot
        self.avant = None
        self.apres = None
    def insere (self, mot) :
        if mot < self.mot :
            if self.avant == None : self.avant = Noeud (mot)
            else : self.avant.insere (mot)
        else :
            if self.apres == None : self.apres = Noeud (mot)
            else : self.apres.insere (mot)
    def affiche (self) :
        if self.avant != None : self.avant.affiche ()
        print self.mot
        if self.apres != None : self.apres.affiche ()
            
li = ["premier","deuxième","troisième","quatrième","cinquième","sixième","centième","mystère"]
r = None
for m in li :
    if r == None : r = Noeud (m)
    else : r.insere (m)
r.affiche ()

File: ecrit_2007.tex, line 799


centième
cinquième
deuxième
mystère
premier
quatrième
sixième
troisième

File: ecrit_2008.tex, line 31


def arrondi_05 (x) :
    return float (int (x * 2 + 0.5)) / 2
    
def arrondi_0125 (x) :
    return float (int (x * 8 + 0.5)) / 8
    
def arrondi (x, p) :
    return float (int (x / p + 0.5)) * p

File: ecrit_2008.tex, line 51


for a in range (0, 10) :
    for b in range (0, 10) :
        for c in range (0, 10) :
             print [a,b,c]

File: ecrit_2008.tex, line 69


a,b,c = 0,0,0
while c < 10 :
    print [a,b,c]
    a += 1
    if a == 10 :
        b += 1
        a = 0
        if b == 10 :
            c += 1
            b = 1

File: ecrit_2008.tex, line 86


l = [0,0,0]
while l [-1] < 10 :
    print l
    l [0] += 1
    i = 0
    while i < len (l)-1 and l [i] == 10 :
        l [i] = 0
        l [i+1] += 1
        i += 1

File: ecrit_2008.tex, line 112


def fibo (n) :
    if n <= 2 : return 2
    else : return fibo (n-1) + fibo (n-2)

File: ecrit_2008.tex, line 137


nb = 0  # variable globale
def fibo (n,p) :
    global nb
    if n <= 2 : 
        nb += 1
        return p # plus de récurrence 
    else : 
        nb += 2
        return fibo (n-1,p) + fibo (n-2,p)
        
for n in range (1, 20) :
    nb = 0    # remis à zéro, à chaque fois
              # nb est la mesure du coût
    print fibo(n,3)-2, nb  # nombres identiques
    # nb vérifie la récurrence de la suite c(n)
    #          c(n) = c(n-1) + c(n-2) + 2

File: ecrit_2008.tex, line 209


l = [0,1,2,3,4,5]
g = l
for i in range (0, len (l)-1) :
    g [i] = g [i+1]
print l
print g

File: ecrit_2008.tex, line 221


l = [0,1,2,3,4,5]
g = [0,1,2,3,4,5]
for i in range (0, len (l)-1) :
    g [i] = g [i+1]
print l
print g

File: ecrit_2008.tex, line 233


l = [0,1,2,3,4,5]
g = [0,1,2,3,4,5]
for i in range (0, len (l)) :
    g [i] = g [(i+1)%len (l)]
print l
print g

File: ecrit_2008.tex, line 253


[1, 2, 3, 4, 5, 5]
[1, 2, 3, 4, 5, 5]

File: ecrit_2008.tex, line 261


[0, 1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 5]

File: ecrit_2008.tex, line 269


[0, 1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 1]

File: ecrit_2008.tex, line 277


l = [0,1,2,3,4,5]
g = [0,1,2,3,4,5]
for i in range (0, len (l)) :
    g [i] = l [(i+1)%len (l)] # ligne modifiée, g devient l
print l
print g

File: ecrit_2008.tex, line 291


import copy
l = [0,1,2,3,4,5]
g = copy.copy (l) # on pourrait aussi écrire g = list (l)
                  # ou encore g = [ i for i in l ]
for i in range (0, len (l)) :
    g [i] = l [(i+1)%len (l)] 
print l
print g

File: ecrit_2008.tex, line 316


def mystere (l) :
    """cette fonction s'applique à des listes de nombres"""
    l.sort ()
    nb = 0 
    for i in range (1,len (l)) :
        if l [i-1] != l [i] : nb += 1
    return nb+1
    
l = [4,3,1,2,3,4]
print mystere (l)  # affiche 4

File: ecrit_2008.tex, line 342


[1, 2, 3, 3, 4, 4]

File: ecrit_2008.tex, line 350


import copy
def mystere (l) :
    """cette fonction s'applique à des listes de nombres"""
    l = copy.copy (l) # ligne insérée
                      # on peut écrire aussi l = list (l)
    l.sort ()
    nb = 0 
    for i in range (1,len (l)) :
        if l [i-1] != l [i] : nb += 1
    return nb+1

File: ecrit_2008.tex, line 376


class Personne :
    def __init__ (self, nom) :
        self.nom = nom
    def entete (self) :
        return ""
    def __str__ (self) :
        s = self.entete () + self.nom
        return s
        
class Homme (Personne) :
    def __init__ (self, nom) :
        Personne.__init__ (self, nom) 
    def entete (self) :
        return "M. "
        
class Femme (Personne) :
    def __init__ (self, nom) :
        Personne.__init__ (self, nom) 
    def entete (self) :
        return "Melle "
        
h = Homme ("Hector")
f = Femme ("Gertrude")
print h
print f

File: ecrit_2008.tex, line 406


class Personne :
    def __init__ (self, nom, entete) :
        self.nom = nom
        self.entete = entete
    def __str__ (self) :
        s = self.entete + self.nom
        return s

h = Personne ("Hector", "M. ")
f = Personne ("Gertrude", "Melle ")
print h
print f














File: ecrit_2008.tex, line 450


M. Hector
Melle Gertrude

File: ecrit_2008.tex, line 459


class Personne :
    def __init__ (self, nom) :
        self.nom = nom
    def entete (self) :
        return ""
    def __str__ (self) :
        s = self.entete () + self.nom
        return s
        
class Homme (Personne) :
    def __init__ (self, nom) :
        Personne.__init__ (self, nom) 
    def entete (self) :
        return "M. "
        
class Femme (Personne) :
    def __init__ (self, nom) :
        Personne.__init__ (self, nom) 
    def entete (self) :
        return "Melle "
        
class Hermaphrodite (Personne) :
    def __init__ (self, nom) :
        Personne.__init__ (self, nom) 
    def entete (self) :
        return "Melle et M. "
        
h = Homme ("Hector")
f = Femme ("Gertrude")
g = Hermaphrodite ("Marie-Jean")
print h
print f
print g

File: ecrit_2008.tex, line 497


class Personne :
    def __init__ (self, nom, entete) :
        self.nom = nom
        self.entete = entete
    def __str__ (self) :
        s = self.entete + self.nom
        return s

h = Personne ("Hector", "M. ")
f = Personne ("Gertrude", "Melle ")
g = Personne ("Marie-Jean", \
                     "Melle et M. ")
print h
print f
print g



















File: ecrit_2008.tex, line 552


def tri_entiers(l):
    """cette fonction s'applique à une liste d'entiers"""
    
    # groupe 1
    m = l [0]
    M = l [0]
    for k in range(1,len(l)):
        if l [k] < m : m = l [k]
        if l [k] > M : M = l [k]
    
    # groupe 2
    p = [0 for i in range (m,M+1) ]
    for i in range (0, len (l)) :
        p [ l [i] - m ] += 1
        
    # groupe 3
    R     = [0 for i in range (m,M+1) ]
    R [0] = p [0]
    for k in range (1, len (p)) :
        R [k] = R [k-1] + p [k]
        
    # groupe 4
    pos = 0
    for i in range (1, len (l)) :
        while R [pos] < i : pos += 1
        l [i-1] = pos + m
    l [len (l)-1] = M

File: ecrit_2008.tex, line 643


import random

def tirage (poids) :
    nb = [ 0 for p in poids ]
    while True :
        i = random.randint (0, len (poids)-1) 
        nb [i] += 1
        if nb [i] == poids [i] :
            return i

salaire = [ 10000, 5000, 3000, 2000 ]
poids   = [ int (s / 1000) for s in salaire ]
nombre  = [ 0 for s in salaire ]

for n in range (0,1000) :
    p = tirage (poids)
    nombre [p] += 1
    
for i in range (0, len (poids)) :
    print "salaire ", salaire [i], " : nb : ", nombre [i]

File: ecrit_2008.tex, line 669


salaire  10000  : nb :  0
salaire  5000  : nb :  49
salaire  3000  : nb :  301
salaire  2000  : nb :  650

File: ecrit_2008.tex, line 685


import random

def tirage (poids, nb) :
    while True :
        i = random.randint (0, len (poids)-1) 
        nb [i] += 1
        if nb [i] % poids [i]  == 0 :
            return i

salaire = [ 10000, 5000, 3000, 2000 ]
poids   = [ int (s / 1000) for s in salaire ]
nombre  = [ 0 for s in salaire ]
temp    = [ 0 for s in salaire ]

for n in range (0,1000) :
    p = tirage (poids, temp)
    nombre [p] += 1
    
for i in range (0, len (poids)) :
    print "salaire ", salaire [i], " : nb : ", nombre [i]

File: ecrit_2008.tex, line 711


salaire  10000  : nb :  90
salaire  5000  : nb :  178
salaire  3000  : nb :  303
salaire  2000  : nb :  429

File: ecrit_2008.tex, line 747


dico = { }
dico ["Jean"] = { }
dico ["Jean"] ["Matthieu"] = { }
dico ["Jean"] ["Pierre"] = { }
dico ["Jean"] ["Matthieu"] ["Thomas"] = { }
dico ["Jean"] ["Matthieu"] ["Louis"] = { }
dico ["Jean"] ["Pierre"] ["Anne"] = dico ["Jean"] ["Matthieu"] ["Thomas"]
dico ["Jean"] ["Pierre"] ["Henri"] = { }
dico ["Jean"] ["Pierre"] ["Anne"] ["Alphonse"] = { }

def print_dico (dico, niveau = 0) :
    decalage = "...." * niveau
    for d in dico :
        print decalage, d
        if len (dico [d]) > 0 : 
            print_dico (dico [d], niveau+1)
            
print_dico (dico)  # première fois
dico ["Jean"] ["Pierre"] ["Anne"] ["Bernard"] = { }  ### ligne B
print "**********"
print_dico (dico)  # seconde fois

File: ecrit_2008.tex, line 774


 Jean
.... Matthieu
........ Louis
........ Thomas
............ Alphonse
.... Pierre
........ Anne
............ Alphonse
........ Henri
**********
 Jean
.... Matthieu
........ Louis
........ Thomas
............ Bernard
............ Alphonse
.... Pierre
........ Anne
............ Bernard
............ Alphonse
........ Henri

File: ecrit_2008_rattrapage.tex, line 33


def u (n) :
    if n <= 2 : return 1
    else : return u (n-1) + u (n-2) + u (n-3)

File: ecrit_2008_rattrapage.tex, line 46


def u_non_recursif (n) :
    if n <= 2 : return 1
    u0 = 1
    u1 = 1
    u2 = 1
    i = 3
    while i <= n :
        u  = u0 + u1 + u2
        u0 = u1
        u1 = u2
        u2 = u
        i += 1
    return u

File: ecrit_2008_rattrapage.tex, line 72


def fonction (n) :
    return n + (n % 2)
    
print fonction (10)
print fonction (11)

File: ecrit_2008_rattrapage.tex, line 91


10
12

File: ecrit_2008_rattrapage.tex, line 101


def fonction3 (n) :
    k = 0
    while k < n : k += 3
    return k

File: ecrit_2008_rattrapage.tex, line 112


def fonction3 (n) :
    if   n % 3 == 0 : return n
    elif n % 3 == 1 : return n + 2
    else : return n + 1

File: ecrit_2008_rattrapage.tex, line 123


def fonction3 (n) :
    if n % 3 == 0 : return n
    else : return n + 3 - (n % 3)

File: ecrit_2008_rattrapage.tex, line 140


def division (n) :
    return n / 2
    
print division (1)
print division (0.9)

File: ecrit_2008_rattrapage.tex, line 158


0
0.45

File: ecrit_2008_rattrapage.tex, line 197


def compare_liste (p,q) :
    i = 0
    while i < len (p) and i < len (q) :
        if   p [i] < q [i] : return -1  # on peut décider
        elif p [i] > q [i] : return  1  # on peut décider
        i += 1                          # on ne peut pas décider
    # fin de la boucle, il faut décider à partir des longueurs des listes
    if   len (p) < len (q) : return -1
    elif len (p) > len (q) : return  1
    else : return 0

File: ecrit_2008_rattrapage.tex, line 214


def compare_liste (p,q) :
    i = 0
    while i < len (p) and i < len (q) :
        c = cmp (p [i], q [i])
        if c != 0 : return c            # on peut décider 
        i += 1                          # on ne peut pas décider
    # fin de la boucle, il faut décider à partir des longueurs des listes
    return cmp (len (p), len (q))

File: ecrit_2008_rattrapage.tex, line 238


l = [0,1,2,3,4,5,6,7,8,9]
i = 1
while i < len (l) :
    print l [i], l [i+1]
    i += 2

File: ecrit_2008_rattrapage.tex, line 250


1 2
3 4
5 6
7 8
9
Traceback (most recent call last):
  File "examen2008_rattrapage.py", line 43, in <module>
    print l [i], l [i+1]
IndexError: list index out of range

File: ecrit_2008_rattrapage.tex, line 285


def suite_geometrique_1 (r) :
    x = 1.0
    y = 0.0
    n = 0
    while x > 0 :
        y += x
        x *= r
        n += 1
    return y,n
    
print suite_geometrique_1 (0.5)  #affiche (2.0, 1075)

File: ecrit_2008_rattrapage.tex, line 303


def suite_geometrique_2 (r) :
    x = 1.0
    y = 0.0
    n = 0
    yold = y + 1
    while abs (yold - y) > 0 :
        yold = y
        y += x
        x *= r
        n += 1
    return y,n
    
print suite_geometrique_2 (0.5)  #affiche (2.0, 55)

File: ecrit_2008_rattrapage.tex, line 348


def hyper_cube_liste (n, m = [0,0]) :
    if n > 1 :
        m [0] = [0,0]
        m [1] = [0,0]
        m [0] = hyper_cube_liste (n-1, m [0])
        m [1] = hyper_cube_liste (n-1, m [1])
    return m
h = hyper_cube_liste (3)
print h                     # affiche [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]

File: ecrit_2008_rattrapage.tex, line 365


def hyper_cube_dico (n) :
    r = { }
    ind = [ 0 for i in range (0,n) ]
    while ind [0] <= 1 :
        cle                 = tuple (  ind ) # conversion d'une liste en tuple
        r [cle]             = 0
        ind [ len (ind)-1] += 1
        k                   = len (ind)-1
        while ind [ k ] == 2 and k > 0 :
            ind [k]    = 0
            ind [k-1] += 1
            k         -= 1
    return r
h = hyper_cube_dico (3)
print h        # affiche {(0, 1, 1): 0, (1, 1, 0): 0, (1, 0, 0): 0, (0, 0, 1): 0, 
               #          (1, 0, 1): 0, (0, 0, 0): 0, (0, 1, 0): 0, (1, 1, 1): 0}

File: ecrit_2008_rattrapage.tex, line 389


def occurrence (l,n) :
    d = ....... # choix d'un hyper_cube (n)
    .....
    return d
suite = [ 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1 ]
h = occurrence (suite, 3)
print h

File: ecrit_2008_rattrapage.tex, line 407


def occurrence (l,n) :
    d = hyper_cube_dico (n)
    for i in range (0, len (l)-n) :
        cle = tuple (l [i:i+n])
        d [cle] += 1
    return d

File: ecrit_2008_rattrapage.tex, line 421


def occurrence (l,n) :
    d = { }
    for i in range (0, len (l)-n) :
        cle = tuple (l [i:i+n])
        if cle not in d : d [cle] = 0
        d [cle] += 1
    return d

File: ecrit_2008_rattrapage.tex, line 436


def occurrence (l,n) :
    d = hyper_cube_liste (n, [0,0])         # * remarque voir plus bas
    for i in range (0, len (l)-n) :
        cle = l [i:i+n]
        t   = d                       # 
        for k in range (0,n-1) :      # point clé de la fonction : 
            t = t [ cle [k] ]         #                accès à un élément
        t [cle [ n-1] ] += 1
    return d

File: ecrit_2008_rattrapage.tex, line 454


Traceback (most recent call last):
  File "examen2008_rattrapage.py", line 166, in <module>
    h = occurrence (suite, n)
  File "examen2008_rattrapage.py", line 160, in occurrence
    t [cle [ n-1] ] += 1
TypeError: 'int' object is not iterable

File: ecrit_2008_rattrapage.tex, line 468


def fonction (l = [0,0]) :
    l [0] += 1
    return l
    
print fonction ()         # affiche [1,0] : résultat attendu
print fonction ()         # affiche [2,0] : résultat surprenant
print fonction ( [0,0])   # affiche [1,0] : résultat attendu

File: ecrit_2008_rattrapage.tex, line 483


import copy
def fonction (l = [0,0]) :
    l = copy.copy (l)
    l [0] += 1
    return l

File: ecrit_2008_rattrapage.tex, line 495


def hyper_cube_liste (n, m = [0,0]) :
    m = copy.copy (m)		
    if n > 1 :
        m [0] = [0,0]
        m [1] = [0,0]
        m [0] = hyper_cube_liste (n-1, m [0])
        m [1] = hyper_cube_liste (n-1, m [1])
    return m

File: ecrit_2009.tex, line 45


def f():
    x = 0
    print x


f()

def g():
    print x

g()

File: ecrit_2009.tex, line 61


def f():
    x = 0
    print x

x = 1
f()

def g():
    print x

g()

File: ecrit_2009.tex, line 89


Traceback (most recent call last):
  File "p1.py", line 11, in <module>
    g()
  File "p1.py", line 9, in g
    print x
NameError: global name 'x' is not defined

File: ecrit_2009.tex, line 106



a       = [ None, 0 ]
b       = [ None, 1 ]
a [0]   = b
b [0]   = a
print a [0][0] [0][0] [0][0] [1]

File: ecrit_2009.tex, line 118


import copy
a       = [ None, 0 ]
b       = [ None, 1 ]
a [0]   = copy.copy (b)
b [0]   = a
print a [0][0] [0][0] [0][0] [1]

File: ecrit_2009.tex, line 141


0
1

File: ecrit_2009.tex, line 147


a       = [ None, 0 ]
b       = [ None, 1 ]
a [0]   = b   # b et a [0] désignent la même liste
b [0]   = a   # b [0] et a désignent la même liste

File: ecrit_2009.tex, line 171


0

File: ecrit_2009.tex, line 204


import random
def somme_alea (tableau, n) :
    s = 0
    for i in range (0, n) :
        h = random.randint (0, len (tableau)) 
        s += tableau [h]
    print s / n
x = somme_alea ( range (0,100), 10)
print "x = ", x

File: ecrit_2009.tex, line 223


44
x =  None

File: ecrit_2009.tex, line 234


Traceback (most recent call last):
  File "examen2009.py", line 10, in <module>
    print somme_alea ( range (0,100), 10)
  File "examen2009.py", line 8, in somme_alea
    s += tableau [h]
IndexError: list index out of range

File: ecrit_2009.tex, line 253


44

File: ecrit_2009.tex, line 258


h = random.randint (0, len (tableau)-1)

File: ecrit_2009.tex, line 288


def moyenne_mobile (suite, m) :
    res = []
    for i in range (m, len (suite)-m) :
        s = 0
        for j in range (-m,m+1) : s += suite [i+j]
        res.append (  float (s) / (m*2+1) )
    return res

File: ecrit_2009.tex, line 301


def moyenne_mobile (suite, m) :
    res = []
    for i in range (m, len (suite)-m) :
        if i == m :
            # ... ligne à remplacer    
        else :
            # ... ligne à remplacer    
        res.append (  float (s) / (m*2+1) )
    return res

File: ecrit_2009.tex, line 333


def moyenne_mobile (suite, m) :
    res = []
    for i in range (m, len (suite)-m) :
        if i == m :
            s = sum ( suite [i-m : i+m+1] )
        else :
            s = s - suite [i-m-1] + suite [i+m]
        res.append (  float (s) / (m*2+1) )
    return res

File: ecrit_2009.tex, line 358


def fonction_mystere (tableau) :
    for i in range (0, len (tableau)) :
        if tableau [i] % 2 != 0 : continue
        pos = i
        for j in range (i+1, len (tableau)) :
            if tableau [j] % 2 != 0 : continue
            if tableau [pos] < tableau [j] : pos = j
        ech           = tableau [i]
        tableau [i]   = tableau [pos]
        tableau [pos] = ech

File: ecrit_2009.tex, line 375


if tableau [i] % 2 != 0 : continue
    if tableau [pos] < tableau [j] : pos = j

File: ecrit_2009.tex, line 381


def fonction_mystere (tableau) :
    for i in range (0, len (tableau)) :
        pos = i
        for j in range (i+1, len (tableau)) :
            if tableau [pos] < tableau [j] : pos = j
        ech           = tableau [i]
        tableau [i]   = tableau [pos]
        tableau [pos] = ech

File: ecrit_2009.tex, line 393


a = [ 0, 1, 4, 3, 5, 2 ]
print a                     # affiche [ 0, 1, 4, 3, 5, 2 ]
b = fonction_mystere (a)
print b                     # affiche [ 4, 1, 2, 3, 5, 0 ]

File: ecrit_2009.tex, line 494


class Boucle :
    def __init__ (self, a, b) :
        self.a = a
        self.b = b
    def iteration (self, i) :              # contenu d'une itération
        pass                               
    def boucle (self) :                    # opère la boucle
        for i in range (self.a, self.b) : 
            self.iteration (i)

File: ecrit_2009.tex, line 510


class Gauss (Boucle) :
    def __init__ (self, b) :
        Boucle.__init__ (self, 1, b+1)
        self.x = 0
        
    def iteration (self,i) :
        self.x += i
        
g = Gauss (10)
g.boucle ()
print g.x

File: ecrit_2009.tex, line 542


class Carre (Gauss) :
    def iteration (self,i) :
        self.x += i*i           # ligne changée
        
g = Carre (10)
g.boucle ()
print g.x

File: ecrit_2009.tex, line 554


class Boucle2 (Boucle) :
    def __init__ (self, a, b, c, d) :
        Boucle.__init__ (self, a, b)    
        self.c = c
        self.d = d
    def iteration (self, i, j) :
        pass
    def boucle (self) :
        for j in range (self.c, self.d) : 
            for i in range (self.a, self.b) : 
                self.iteration (i,j)
                
class Gauss2 (Boucle2) :
    def __init__ (self, a, b) :
        Boucle2.__init__ (self, 1, a+1, 1, b+1)
        self.x = 0
    def iteration (self, i,j) :
        self.x += i+j                

File: ecrit_2009.tex, line 577


class Boucle2 (Boucle) :
    def __init__ (self, a, b, c, d) :
        Boucle.__init__ (self, a, b)    
        self.c = c
        self.d = d
    def iteration (self, i) :
        pass
    def boucle (self) :
        for j in range (self.c, self.d) : 
            self.j = j
            for i in range (self.a, self.b) : 
                self.iteration (i)
                
class Gauss2 (Boucle2) :
    def __init__ (self, a, b) :
        Boucle2.__init__ (self, 1, a+1, 1, b+1)
        self.x = 0
    def iteration (self, i) :
        self.x += self.j+i

File: ecrit_2009.tex, line 601


class Boucle2 (Boucle) :
    def __init__ (self, a, b, c, d) :
        Boucle.__init__ (self, a, b)    
        self.c = c
        self.d = d
    def iteration (self, i) :
        pass
    def boucle (self) :
        for j in range (self.c, self.d) : 
            self.j = j
            Boucle.boucle (self)  # suppression d'une boucle
                                  # caché dans la classe Boucle

File: ecrit_2009.tex, line 618


class Boucle2 (Boucle) :
    def __init__ (self, a, b, c, d) :
        Boucle.__init__ (self, a, b)    
        self.c = c
        self.d = d
        
    def iteration (self, i) :
        for j in range (self.c, self.d) :
            self.iteration2 (i,j)
            
    def iteration2 (self, i,j) :
        pass
        
                        
class Gauss2 (Boucle2) :
    def __init__ (self, a, b) :
        Boucle2.__init__ (self, 1, a+1, 1, b+1)
        self.x = 0
    def iteration2 (self, i, j) :
        self.x += j+i

File: ecrit_2009.tex, line 644


class Boucle2 (Boucle) :
    def __init__ (self, a, b, c, d) :
        Boucle.__init__ (self, a, b)    
        self.c = c
        self.d = d
    def iteration (self, i, j) :
        pass
    def boucle (self) :
        ab = self.b - self.a
        cd = self.d - self.c
        n  = ab * cd
        for k in range (0, n) :
            i = k % ab + self.a
            j = k / ab + self.c
            self.iteration (i,j)

File: ecrit_2010.tex, line 46


l = []
for i in range (0, 4) :
    c = []
    for j in range (0, i) : c += [ j ]  # ou c.append (j)
    l += [ c ]                          # ou l.append (c)

for c in l : print c

File: ecrit_2010.tex, line 58


l = [1,4,1,5,9]
d = { }
for u in l :
    if u in d : d [u] += 1
    else : d [u] = 1
        
print d

File: ecrit_2010.tex, line 76


[]
[0]
[0, 1]
[0, 1, 2]

File: ecrit_2010.tex, line 85


{1: 2, 4: 1, 5: 1, 9: 1}

File: ecrit_2010.tex, line 109


n = 10
l = [i for i in (0,n)]
l[9]

File: ecrit_2010.tex, line 117


  File "ecrit.py", line 3, in <module>
    l[9]
IndexError: list index out of range

File: ecrit_2010.tex, line 129


d = {'un': 1, 'deux': 4}
print deux


File: ecrit_2010.tex, line 137


  File "ecrit.py", line 2, in <module>
    print deux
NameError: name 'deux' is not defined

File: ecrit_2010.tex, line 149


l = [ "mot", "second" ]
print l(0)


File: ecrit_2010.tex, line 157


  File "ecrit.py", line 2, in <module>
    print l(0)
TypeError: 'list' object is not callable

File: ecrit_2010.tex, line 171


l = [4, 2, 1, 3]
ll = l.sort()
print ll[0]

File: ecrit_2010.tex, line 179


  File "ecrit.py", line 2, in <module>
	  print ll[0]
TypeError: 'NoneType' object is unsubscriptable

File: ecrit_2010.tex, line 194


n = 10
l = [i for i in (0,n)]
print l                    # affiche [0, 10]

File: ecrit_2010.tex, line 200


l = [i for i in range (0,n)]

File: ecrit_2010.tex, line 210


l = [4, 2, 1, 3]
ll = list (l)
ll.sort()
print ll[0]

File: ecrit_2010.tex, line 219


l = [4, 2, 1, 3]
print min(l)

File: ecrit_2010.tex, line 240


i = random.randint (0,n) # tire aléatoirement un nombre entier entre 0 et n inclus

l.sort ()                # trie la liste l quel que soit son contenu

File: ecrit_2010.tex, line 248


l = [4,5,3,7,4]
l.sort ()
print l             # affiche [3, 4, 4, 5, 7]

File: ecrit_2010.tex, line 256


l = [ (1,2), (0,10), (4,3), (5,0), (0,9) ]
l.sort ()
print l             # affiche [(0, 9), (0, 10), (1, 2), (4, 3), (5, 0)]

File: ecrit_2010.tex, line 264


def permutation_aleatoire (l) :
    ....
    return ...
    
print permutation_aleatoire ([1,2,3,4])   # affiche [3,1,4,2]

File: ecrit_2010.tex, line 281


tab = ["zéro", "un", "deux"] # tableau à trier
pos = [ (tab [i],i) for i in range (0, len (tab)) ] # tableau de couples
pos.sort () # tri
print pos # affiche [('deux', 2), ('un', 1), ('zéro', 0)]

File: ecrit_2010.tex, line 290


from random import randint

def permutation (liste) :
    alea        = [ randint (0,len (liste)) for i in liste ]
    couple      = [ (r,l) for r,l in zip (alea,liste) ]
    couple.sort ()
    permutation = [ l[1] for l in couple ]
    return permutation

liste = [ i*2 for i in range (0,10) ]
permu = permutation (liste)
print liste  # affiche [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
print permu  # affiche [2, 6, 16, 10, 8, 14, 0, 12, 18, 4]

File: ecrit_2010.tex, line 308


from random import randint
import copy

def permutation (liste) :
    li = copy.copy (liste)
    for i in xrange (0, len (liste)) :
        n = randint (0, len (liste)-1)
        m = randint (0, len (liste)-1)
        s = li [n]
        li [n] = li [m]
        li [m] = s
    return li

File: ecrit_2010.tex, line 325


from random import randint
import copy

def permutation (liste) :
    li = copy.copy (liste)
    for i in xrange (0, len (liste)) :
        n = i
        m = randint (0, len (liste)-1)
        s = li [n]
        li [n] = li [m]
        li [m] = s
    return li

File: ecrit_2010.tex, line 342


from random import randint
import copy

def permutation (liste) :
    li = [ ]
    n  = len (liste)
    for i in xrange (0, n) :
        m = randint (0, len (liste)-1)
        li.append (liste [m])
        del liste [m]          # on supprime l'élément tiré au hasard
    return li

File: ecrit_2010.tex, line 358


from random import randint
import copy

def permutation (liste) :
    li = [ ]
    n  = len (liste)
    for i in xrange (0, n) :
        m = randint (0, len (liste)-1)
        if liste [m] not in li : 
            li.append (liste [m])
    return li

File: ecrit_2010.tex, line 391


def nom_csp (csp) :                      # csp est un entier compris entre 1 et 4
    if   csp == 1  : return "cat. A"           
    elif csp == 2  : return "cat. B"
    elif csp == 3  : return "cat. C"
    else           : return "cat. D"

File: ecrit_2010.tex, line 405


def nom_csp (csp) :                      # csp est un entier compris entre 1 et 4
    if csp <= 2  : 
        if csp == 1 : return "cat. A"           
        else        : return "cat. B"                
    else :
        if csp == 3 : return "cat. C"
        else        : return "cat. D"

File: ecrit_2010.tex, line 450


def nom_csp (csp) :
    if   csp == 3  : return "cat. C"           
    elif csp == 1  : return "cat. A"
    elif csp == 2  : return "cat. B"
    else           : return "cat. D"

File: ecrit_2010.tex, line 513


def calculeN (I,J) :  # I et J sont des entiers comme par exemple I=3 et J=5
    
    nombre = [ [0 for i in range (0, J) ] for i in range (0, I) ]
      # nombre est alors égal à [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
        
    for i in range (0, I) : 
        nombre [i][0] = 1
        
    for j in range (0, I) : 
        nombre [0][j] = 1
        
    for i in range (1, I) : 
        for j in range (1, J) :
            nombre [i][j] = nombre [i-1][j] + nombre [i][j-1] 
            
    return nombre

nombre = calculeN (3,5)
for l in nombre : print l

File: ecrit_2010.tex, line 536


[1, 1, 1, 0, 0]
[1, 2, 3, 3, 3]
[1, 3, 6, 9, 12]

File: ecrit_2010.tex, line 572


for j in range (0, I) :   # il faut écrire range (0, J)
    nombre [0][j] = 1

File: ecrit_2010.tex, line 578


[1, 1, 1, 1, 1]
[1, 2, 3, 4, 5]
[1, 3, 6, 10, 15]

File: ecrit_2010.tex, line 589


def calculeN (I,J) : 
    
    nombre = [ [0 for i in range (0, J) ] for i in range (0, I) ]
        
    for i in range (0, I) : 
        nombre [i][0] = 1
        
    for j in range (1, J) : 
        nombre [0][j] = 1
    nombre [0][1:5] = [2,] * (J-1)  ##### ligne ajoutée
        
    for i in range (1, I) : 
        for j in range (1, J) :
            nombre [i][j] = nombre [i-1][j] + nombre [i][j-1] 
            
    return nombre

nombre = calculeN (3,5)
for l in nombre : print l

File: ecrit_2010.tex, line 612


[1, 2, 2, 2, 2]
[1, 3, 5, 7, 9]
[1, 4, 9, 16, 25]

File: ecrit_2010.tex, line 641


def generation_ensemble (n, s, s1, s2) :
    l     = [ ]
    alpha = s * s2 / s1
    beta  = s2 * (1.0 - s**2) ** 0.5
    for i in range (0, n) :
        x     = random.gauss (0,s1)
        u     = random.gauss (0,1.0)
        y     = alpha * x + beta * u
        l [i] = [ [x,y] ]              # ligne 26
    return l

File: ecrit_2010.tex, line 656


Traceback (most recent call last):
  File "examen2010.py", line 62, in <module>
    points       = generation_ensemble (50000, 1., 2., 6., 0.5)
  File "examen2010.py", line 26, in generation_ensemble
    l [i] = [ [x,y] ]
IndexError: list assignment index out of range

File: ecrit_2010.tex, line 671


def generation_ensemble2 (n, s, s1, s2) :
    l = [ ]
    a = s * 100
    for i in range (0, n) :
        x  = random.gauss (0,s1)
        if (i % 100) <= a :           # le symbole % désigne le modulo:  
                                      # i % 100 est le reste de la division de i par 100
            y = x * s2 / s1
        else :
            y = random.gauss (0,s2)
        l += [ [x,y] ]
    return l

File: ecrit_2011.tex, line 54


def remplissage (mat, x , y) :        # ligne 1
    dico = { (x,y):0 }                # ligne 2
    while len (dico) > 0 :            # ligne 3
        point        = dico.popitem ()# retourne un élément du dictionnaire et le supprime
        x,y          = point [0]      # ligne 5
        mat [x][y]   = 1              # ligne 6
        dico [x-1,y] = 0              # ligne 7
        dico [x+1,y] = 0              # ligne 8
        dico [x,y-1] = 0              # ligne 9
        dico [x,y+1] = 0              # ligne 10

File: ecrit_2011.tex, line 69


...
118 41 13
118 40 13
118 34 8
118 34 7
118 41 13
118 40 13
118 34 8
118 34 7
118 41 13
...

File: ecrit_2011.tex, line 97


def remplissage (mat, x , y) :        # 
    dico = { (x,y):0 }                # 
    while len (dico) > 0 :            # 
        point        = dico.popitem ()# 
        x,y          = point [0]      # 
        if mat [x][y] == 1 : continue # ligne ajoutée
        mat [x][y]   = 1              # 
        dico [x-1,y] = 0              # 
        dico [x+1,y] = 0              # 
        dico [x,y-1] = 0              # 
        dico [x,y+1] = 0              # 

File: ecrit_2011.tex, line 113


def remplissage (mat, x , y) :        # 
    dico = { (x,y):0 }                # 
    while len (dico) > 0 :            # 
        point        = dico.popitem ()# 
        x,y          = point [0]      # 
        mat [x][y]   = 1              # 
        if mat[x-1][y] == 0 : dico [x-1,y] = 0  # 
        if mat[x+1][y] == 0 : dico [x+1,y] = 0  # 
        if mat[x][y-1] == 0 : dico [x,y-1] = 0  # 
        if mat[x][y+1] == 0 : dico [x,y+1] = 0  # 

File: ecrit_2011.tex, line 128


def remplissage (mat, x , y) :         
    int compte = 0                       # ligne ajoutée
    dico = { (x,y):0 }                 
    while len (dico) > 0 :             
        point        = dico.popitem () 
        x,y          = point [0]       
        if mat [x][y] == 1 : continue 
        mat [x][y]   = 1               
        dico [x-1,y] = 0               
        dico [x+1,y] = 0               
        dico [x,y-1] = 0               
        dico [x,y+1] = 0               
        compte += 1                      # ligne ajoutée
    return comte                         # ligne ajoutée

File: ecrit_2011.tex, line 165


def resolution_simple (objets, sac) :
    objets.sort (reverse = True)
    solution = []
    for o in objets :
        ...
    return solution

File: ecrit_2011.tex, line 192


def resolution (objets, sac) :
    if len (objets) == 1 :
        if objets [0] <= sac :  return [ objets [0] ]
        else :                  return []
        
    reduit  = objets [1:]
    s1      = resolution (reduit, sac)
    s2      = resolution (reduit, sac - objets [0])   # ligne B
    
    t1      = sum(s1)
    t2      = sum(s2) + objets [0]                    # ligne C
    
    if   sac >= t1 and (t1 >= t2 or t2 > sac) : return s1
    elif sac >= t2 and (t2 >= t1 or t1 > sac) : return [ objets [0], ] + s2
        
obj = [2,4,7,10]
sac = 15
print "solution ",resolution (obj, sac) # ligne A

File: ecrit_2011.tex, line 215


solution 
Traceback (most recent call last):
  File "examen2011.py", line A, in <module>
    print "solution ",resolution (obj, sac)
  File "examen2011.py", line B, in resolution
    s2      = resolution (reduit, sac - objets [0])
  File "examen2011.py", line C, in resolution
    t2      = sum(s2) + objets [0]
TypeError: 'NoneType' object is not iterable

File: ecrit_2011.tex, line 241


def resolution_simple (objets, sac) :
    objets.sort (reverse = True)
    solution = []
    for o in objets :
        if sum(solution) + o <= sac :   # ligne ajoutée
            solution.append (o)         # ligne ajoutée
    return solution

File: ecrit_2011.tex, line 260


t2      = sum(s2) + objets [0]
TypeError: 'NoneType' object is not iterable

File: ecrit_2011.tex, line 278


s2      = resolution (reduit, sac - objets [0])   # ligne B

File: ecrit_2011.tex, line 284


if   sac >= t1 and (t1 >= t2 or t2 > sac) : return s1
elif sac >= t2 and (t2 >= t1 or t1 > sac) : return [ objets [0], ] + s2

File: ecrit_2011.tex, line 291


if   sac >= t1 and (t1 >= t2 or t2 > sac) : return s1
elif sac >= t2 and (t2 >= t1 or t1 > sac) : return [ objets [0], ] + s2
else : return []     # ligne ajoutée

File: ecrit_2007_rattrapage.tex, line 32


l2 = [ ( l [i], i ) for i in range (0, len (l)) ]
l2.sort ()
print l2 [0][1]  # affiche la position du plus petit élément 
                 # dans le tableau initial

File: ecrit_2007_rattrapage.tex, line 50


def ensemble_lettre (s) :
	  ens = []
	  for i in range (0, len (s)) :
	      c = s [i]
	      if c in ens :
	          ens.append (c)
	  return ens
      
print lettre ("baaa")

File: ecrit_2007_rattrapage.tex, line 75


def ensemble_lettre (s) :
    ens = []
    for i in range (0, len (s)) :
        c = s [i]
        if c not in ens :
            ens.append (c)
    return ens

File: ecrit_2007_rattrapage.tex, line 98


def autre_parcours (n) :
    i = 0
    j = 0
    k = 0
    
    while k < n :
        print (k,i,j)
        if i == 0 and j == 0 :
            k += 1
        if j == 0 and i < k :
            i += 1
        elif i == k and j < k :
            j += 1
        elif j == k and i > 0 :
            i -= 1
        elif i == 0 and j > 0 :
            j -= 1

autre_parcours (3)

File: ecrit_2007_rattrapage.tex, line 127


(0, 0, 0)
(1, 1, 0)
(1, 1, 1)
(1, 0, 1)
(1, 0, 0)
(2, 1, 0)
(2, 2, 0)
(2, 2, 1)
(2, 2, 2)
(2, 1, 2)
(2, 0, 2)
(2, 0, 1)
(2, 0, 0)

File: ecrit_2007_rattrapage.tex, line 165


k = [10,14,15,-1,6]
l = []
for i in range (0,len (k)) :
    l.append ( k [ len (k) - i ] )

File: ecrit_2007_rattrapage.tex, line 180


k = [10,14,15,-1,6]
l = []
for i in range (0,len (k)) :
    l.append ( k [ len (k) - i-1 ] )  # -1 a été ajouté

File: ecrit_2007_rattrapage.tex, line 203


def puiss (x, n) :
    s = 1.0
    for i in range (0,n) :
        s *= x
    return s

def log_suite (x) :
    x    = float (x-1)
    # ......
    s    = 0
    old  = -1
    n    = 1
    while abs (old - s) > 1e-10 :
        old = s
        po  = puiss (x,n) / n
        if n % 2 == 0 : po = -po
        s  += po
        n  += 1
        # ......
    return s
    
print log_suite (2)

File: ecrit_2007_rattrapage.tex, line 231


# ......
# ......
# ......
# ......
# ......
# ......
def log_suite (x) :
    x    = float (x-1)
    x0   = x
    s    = 0
    old  = -1
    n    = 1
    while abs (old - s) > 1e-10 :
        old = s
        po  = x / n
        if n % 2 == 0 : po = -po
        s  += po
        n  += 1
        x  *= x0
    return s
    
print log_suite (2)

File: ecrit_2007_rattrapage.tex, line 269


def racine_carree (k) :
    x0 = float (k)+1
    x  = float (k)
    while abs (x-x0) > 1e-10 :
        x0 = x
        x  = (k-x*x) / (2 * x) + x
    return x

File: ecrit_2007_rattrapage.tex, line 339


class Noeud :
    def __init__ (self, mot) :
        self.mot = mot
        self.avant = None
        self.apres = None
    def insere (self, mot) :
        if mot < self.mot :
            if self.avant == None : self.avant = Noeud (mot)
            else : self.avant.insere (mot)
        else :
            if self.apres == None : self.apres = Noeud (mot)
            else : self.apres.insere (mot)
    def affiche (self) :
        if self.avant != None : self.avant.affiche ()
        print self.mot
        if self.apres != None : self.apres.affiche ()
            
li = ["premier","deuxième","troisième","quatrième", \
      "cinquième","sixième","centième","mystère"]
r = None
for m in li :
    if r == None : r = Noeud (m)
    else : r.insere (m)
r.affiche ()

File: ecrit_2007_rattrapage.tex, line 372


centième
cinquième
deuxième
mystère
premier
quatrième
sixième
troisième

File: ecrit_2007_rattrapage2.tex, line 32


s = 0
for i in range (1,101) :
   s = i + 100-i+1
s = s / 2

File: ecrit_2007_rattrapage2.tex, line 56


def fusion (l1,l2) :
  i,j = 0,0
  r = []

  while len (r) < len (l1) + len (l2) :
    if i < len (l1) and (j >= len (l2) or l1[i] < l2 [j]) :
      r.append (l1 [i])
      i += 1
    else :
      r.append (l2 [j])
      j += 1
      
  return r

File: ecrit_2007_rattrapage2.tex, line 101


class Noeud : 
  def __init__ (self) :
    self.n1 = None
    self.n2 = None

root = Noeud ()
root.n1 = Noeud ()
root.n2 = Noeud ()
root.n1.n1 = Noeud ()
root.n1.n2 = root

File: ecrit_2007_rattrapage2.tex, line 128


def compte_noeud (self, l = []) :
    if self not in l :
        l.append (self)
        if self.n1 != None : self.n1.compte_noeud (l)
        if self.n2 != None : self.n2.compte_noeud (l)
    return len (l)

File: ecrit_2007_rattrapage2.tex, line 150


%

File: ecrit_2009_rattrapage.tex, line 42


def numero_simple (nbimpair, nbpair) :
    im = [..... for i in range (1, nbimpair+1) ]
    pa = [..... for i in range (1, nbpair  +1) ]
    return im,pa

File: ecrit_2009_rattrapage.tex, line 51


def numerotation (longueur, debut, moy) :
    res = []
    for li in range (0, len (longueur)) :
        if len (res) == 0 : x1 = debut
        else :              x1 = res [-1][1]+2
        
        nb = longueur [li] / moy                  # c'est une division entière
                                                  # ligne importante
                                                  # pour la dernière question
        x2 = x1 + nb*2
        res.append ( (x1,x2) )
        debut = x2 + 2
    return res
    
def numero_deux (impair, pair) :
    moypair   = sum (pair)   / len (pair)         # vaut 25
    moyimpair = sum (impair) / len (impair)       # vaut 41
    im        = numerotation (impair, 1, moyimpair)
    pa        = numerotation (pair,   2, moypair)
    return im,pa
    
impair = [20,70,35]
pair   = [20,20,40,35,10]    
im,pa  = numero_deux (impair, pair)
print im
print pa

File: ecrit_2009_rattrapage.tex, line 83


[(1, 1), (3, 5), (7, 7)]
[(2, 2), (4, 4), (6, 8), (10, 12), (14, 14)]

File: ecrit_2009_rattrapage.tex, line 108


a = [ None, [0] ]
b = [ None, [0] ]
c = [ None, [0] ]

a [0] = b
b [0] = c
c [0] = a

x = a
for i in range (0, 9) :
    x [1][0] += 1
    x = x [0]
    
print "a [1][0] =", a [1][0]
print "b [1][0] =", b [1][0]
print "c [1][0] =", c [1][0]

File: ecrit_2009_rattrapage.tex, line 131


a = [ None, [0] ]
b = [ None, [0] ]
c = [ None, [0] ]

a [0] = b
b [0] = c
c [0] = a

import copy             # ligne ajoutée
a = copy.copy (a)       # ligne ajoutée

x = a
for i in range (0, 9) :
    x [1][0] += 1
    x = x [0]
    
print "a [1][0] =", a [1][0]
print "b [1][0] =", b [1][0]
print "c [1][0] =", c [1][0]

File: ecrit_2009_rattrapage.tex, line 157


a = [ None, [0] ]
b = [ None, [0] ]
c = [ None, [0] ]

a [0] = b
b [0] = c
c [0] = a

import copy             	
a = copy.deepcopy (a)     # ligne modifiée

x = a
for i in range (0, 9) :
    x [1][0] += 1
    x = x [0]
    
print "a [1][0] =", a [1][0]
print "b [1][0] =", b [1][0]
print "c [1][0] =", c [1][0]

File: ellipse_fin_exo.tex, line 4


i = random.randint (0,n) # tire aléatoirement un nombre entier entre 0 et n inclus

l.sort ()                # trie la liste l quel que soit son contenu

File: ellipse_fin_exo.tex, line 12


def permutation_aleatoire (l) :
    ....
    return ...
    
print permutation_aleatoire ([1,2,3,4])   # affiche [3,1,4,2]

File: ellipse_fin_exo.tex, line 29


tab = ["zéro", "un", "deux"] # tableau à trier
pos = [ (tab [i],i) for i in range (0, len (tab)) ] # tableau de couples
pos.sort () # tri
print pos # affiche [('deux', 2), ('un', 1), ('zéro', 0)]

File: ellipse_fin_exo.tex, line 38


from random import randint

def permutation (liste) :
    alea        = [ randint (0,len (liste)) for i in liste ]
    couple      = [ (r,l) for r,l in zip (alea,liste) ]
    couple.sort ()
    permutation = [ l[1] for l in couple ]
    return permutation

liste = [ i*2 for i in range (0,10) ]
permu = permutation (liste)
print liste  # affiche [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
print permu  # affiche [2, 6, 16, 10, 8, 14, 0, 12, 18, 4]

File: conseil_ecrire_programme.tex, line 46

    
def somme_double (liste) :
    return 1.0 * sum(liste)

def test_somme_double () :
    y = somme_double([ 1 ]) / 2
    if y == 0 : raise Exception ("valeur > 0 attendue")
        
if __name__ == "__main__" :
    test_somme_double()

File: conseil_ecrire_programme.tex, line 60

    
Traceback (most recent call last):
  File "conseil.py", line 10, in <module>
    test_somme_double()
  File "conseil.py", line 7, in test_somme_double
    if y == 0 : raise Exception ("valeur > 0 attendue")
Exception: valeur > 0 attendue

File: resume_utile.tex, line 25


import sys
print (sys.version)

File: resume_utile.tex, line 43


def fonction () :
     """fonction de 
     démonstration"""
     return 0
help (fonction)    # affiche fonction de 
                   # démonstration 

File: resume_utile.tex, line 66


va = <valeur>

File: resume_utile.tex, line 83


t = ()        # tuple vide
t = (2, "e")  # tuple de deux éléments
print (t[0])  # affiche le premier élément

File: resume_utile.tex, line 108


t [i:j]  # correspond à un sous-ensemble allant des indices i à j exclu
t [:j]   #  = t[0:j]
t [i:]   # = t [i: len (t)]

File: resume_utile.tex, line 116


st = "langage python"
st = 'langage python'           # idem
st = 'un guillement "'          # chaîne contenant un guillement
st = "un guillement \""         # chaîne contenant un guillement, il faut ajouter \
                                #     pour ne pas confondre avec l'autre guillement
st = st.upper ()                # mise en lettres majuscules
i  = st.find ("PYTHON")         # on cherche "PYTHON" dans st
print (i)                       # affiche 8  Version 3.x, écrire print (i),
                                #    pour la version 2.x, écrire print i
print (st.count ("PYTHON"))     # affiche 1  Version 3.x : idem print (...)
print (st.count ("PYTHON", 9))  # affiche 0  Version 3.x : idem print (...)

File: resume_utile.tex, line 189


x = 0.123456789
print ("%1.2f" % x)    # donne 0.12
s = "%2.2e %s" % (3.14159, "est une approximation de pi")
print (s)              # Version 2.x : print s

File: resume_utile.tex, line 203


a = [1,2]
b = a

File: resume_utile.tex, line 210


a = [1,2]
import copy
b = copy.copy (a)

File: resume_utile.tex, line 218


a = [1,2]
import copy
b = copy.deepcopy (a)

File: resume_utile.tex, line 231


x = [4,5]               # création d'une liste composée de deux entiers
x = ["un",1,"deux",2]   # création d'une liste composée deux chaînes de caractères
                        # et de deux entiers, l'ordre d'écriture est important
x = [3,]                # création d'une liste d'un élément, sans la virgule, 
                        # le résultat reste une liste
x = [ ]                 # crée une liste vide
x = list ()             # crée une liste vide

File: resume_utile.tex, line 368


x = range(0,5)                      # liste des entiers de 0 à 5 exclu
                                    # Version 3.x : range retourne un itérateur, il faut écrire
                                    #     x = list(range(0,5))
y = [ i for i in x if i % 2 == 0]   # sélection des éléments pairs
print (y)                           # affiche [0,2,4]		  Version 2.x : écrire print y
z = [ i+j for i in x for j in x]    # construit tous les nombres i+j possibles
print (z)                           # affiche [0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 
                                    # 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]

File: resume_utile.tex, line 385


x = { "cle1":"valeur1", "cle2":"valeur2" }
print (x ["cle1"])        # affiche valeur1  Version 2.x : écrire print ...
x [(0,1)]  = "clé tuple"  # ajoute une nouvelle valeur dont la clé est (0,1)
                          #   les parenthèses sont superflues
y = { }                   # crée un dictionnaire vide
z = dict ()               # crée aussi un dictionnaire vide

File: resume_utile.tex, line 490


import numpy
a = numpy.array ( [0,1] )

File: resume_utile.tex, line 503


if x < 5 :
    x = x*2
    ...

File: resume_utile.tex, line 511


if x < 5 :
    x = x*2
    ...
else :
    x = x*3
    ...

File: resume_utile.tex, line 522


if x < 5 :  x=x*2
else :      x=x*3

File: resume_utile.tex, line 529


if   x < 5 :  x = x*2
elif x > 5 :  x = x*3
else       :  x = x*6

File: resume_utile.tex, line 537


if 5 < x and x < 10 :     # peut être écrit : if 5 < x < 10 :
    ...

File: resume_utile.tex, line 546


while condition :
    # lignes décalées
    # contenu de la boucle

File: resume_utile.tex, line 554


for i in range(0,n) :             # parcourt tous les entiers de 0 à n-1 inclus   
for i in xrange(0,n) :            # même chose mais en plus rapide  
                                  # Version 3.x : la fonction xrange n'existe plus, 
                                  #               et range équivaut à xrange
for i in range(n,0,-1) :          # parcourt tous les entiers de n à 1 inclus 
                                  #                  dans le sens décroissant   
for i in range(2,1000,3) :        # parcourt tous les entiers de 2 à 1000 de 3 en 3
                                  #                                     (2,5,8,...)
for e in li :                     # parcourt tous les éléments de la liste li
for cle,valeur in di.items () :   # parcourt tous les éléments du dictionnaire di

File: resume_utile.tex, line 573


l = [ 4, 5, 6 ]
s = 0
for i in range(0,len(l)) : 
    s += l[i]

File: resume_utile.tex, line 581


l = [ 4, 5, 6 ]
s = 0
for i,x in enumerate(l) :
    s += x

File: resume_utile.tex, line 591


l = [ 4, 5, 6 ]
g = [ 3,10,11 ]
s = 0
for i in range(0,len(l)) : 
    s += l[i] + g[i]

File: resume_utile.tex, line 600


l = [ 4, 5, 6 ]
g = [ 3,10,11 ]
s = 0
for x,y in zip(l,g) :
    s += x + y

File: resume_utile.tex, line 614


def fonction (x) : return x % 2
li  = [ 3,4,5]
li2 = map (fonction, li)
print (list(li2))           # affiche [ 1, 0, 1 ]

File: resume_utile.tex, line 623


def fonction (x) :
    if x % 2 == 0 : yield x
li  = [ 3,4,5]
li2 = map (fonction, li)
print (list(li2))           # affiche [ 4 ]

File: resume_utile.tex, line 636


with random_matrix(1000,1000) as mat :
    #   appelle mat.__enter__()
    ...
    #   appelle mat.__exit__()

File: resume_utile.tex, line 652


def exemple_fonction (p1, p2, p3) :
    # code de la fonction
    return r1, r2

a,b = exemple_fonction (1,2,3)   # exemple d'appel de la fonction

File: resume_utile.tex, line 662


def exemple_fonction (p1, p2 = 4, p3 = 7) :
    # code de la fonction
    return r1, r2

a,b = exemple_fonction (1)         # = exemple_fonction (1,4,7)
a,b = exemple_fonction (1,2,3)     # = exemple_fonction (1,2,3)
a,b = exemple_fonction (1,2)       # = exemple_fonction (1,2,7)
a,b = exemple_fonction (1,p3 = 2)  # = exemple_fonction (1,4,2)

File: resume_utile.tex, line 675


def exemple_fonction (p1, p2 = 4, p3) :
    # code de la fonction
    return r1, r2
# affiche le message d'erreur : SyntaxError: non-default argument follows default argument

File: resume_utile.tex, line 684


def exemple_fonction (p1) :
    p1 = 3
a = 1
exemple_fonction (a)
print (a)  # affiche 1

File: resume_utile.tex, line 694


def exemple_fonction (p1) :
    p1[0] = 3
a = [1]
exemple_fonction (a)
print (a)  # affiche [3]    Version 2.x : print ...

File: resume_utile.tex, line 707


def fonction (x) : return x % 2
li  = [ 3,4,5]
li2 = map (fonction, li)
print (list(li2))           # affiche [ 1, 0, 1 ]

File: resume_utile.tex, line 716


li  = [ 3,4,5]
li2 = map (lambda x : x%2, li)
print (list(li2))                 # affiche [ 1, 0, 1 ]

File: resume_utile.tex, line 724


li  = [ 3,4,5]
k   = 2
li2 = map (lambda x,y=k : x%k, li)
print (list(li2))                 # affiche [ 1, 0, 1 ]

File: resume_utile.tex, line 736


def iterate_double_on_list(l) :
    for x in l :
        yield x*2
print (iterate_double_on_list( [4,5,6]))
     # affiche <generator object iterate_double_on_list at 0x025196C0>

File: resume_utile.tex, line 746


for x in iterate_double_on_list( [4,5,6]) :
    print (x)

File: resume_utile.tex, line 762


class ma_classe :
    def __init__ (self, att1, att2, att3) :
        self.att1 = att1
        self.att2 = att2
        self.att3 = att3
        self.att4 = att1 * att2 * att3
        
a = ma_classe (-1,1,2) # déclare une variable de type ma_classe
print (a.att1)  # affiche -1       
print (a.att2)  # affiche 3        Version 2.x : print ...
print (a.att3)  # affiche 4
print (a.att4)  # affiche -12

File: resume_utile.tex, line 779


class ma_classe :
    def __init__ (self, att1, att2, att3) :
        self.att1 = att1
        self.att2 = att2
        self.att3 = att3
        self.att4 = self.calcule4 ()
        
    def calcule4 (self) :
        return self.att1 * self.att2 * self.att3
        
a = ma_classe (-1,1,2) # déclare une variable de type ma_classe
print (a.att1)           # affiche -1
print (a.att2)           # affiche 3
print (a.att3)           # affiche 4
print (a.att4)           # affiche -12

File: resume_utile.tex, line 804


class ma_classe :
    def __init__ (self, att1, att2, att3) :
        self.att1 = att1                    # attribut
        self.att2 = att2                    # attribut
        self.att3 = att3                    # attribut
        self.att4 = att1 * att2 * att3      # attribut

    def calcule (self,x) :                   # méthode
        return self.att1 * self.att2 * self.att3 * x
				
a = ma_classe (1,2,3)
print (a.att1)                 # affiche 1 
print (a.__dict__ ["att1"])    # affiche aussi 1, ligne équivalente à la précédente
print (a.calcule(2))           # appel d'une méthode

File: resume_utile.tex, line 826


class ma_classe :
    def __init__ (self, att1, att2, att3) :
		    # ...

    @staticmethod
    def calcule_static (x,y) :         # méthode statique
        return x * y
				
print (ma_classe.calcule_static(2,3))  # appel d'une méthode statique

File: resume_utile.tex, line 844


class ma_classe :
    def __init__ (self, att1, att2, att3) :
        self.att1 = att1
        self.att2 = att2
        self.att3 = att3
        self.att4 = att1 * att2 * att3
        
    def __add__ (self, a) :
         return ma_classe (self.att1 + a.att1, self.att2 + a.att2, \
                       self.att3 + a.att3, self.att4 + a.att4)

a = ma_classe (1,2,3)
b = ma_classe (4,5,6)
c = a + b              # n'a de sens que si l'opérateur __add__ a été redéfini

File: resume_utile.tex, line 868


class ma_classe :
    def __init__ (self, att1, att2, att3) :
        self.att1 = att1
        self.att2 = att2
        self.att3 = att3
        self.att4 = att1 * att2 * att3

a = ma_classe (1,2,3)
b = a
b.att1 = -16
print (a.att1)  # affiche -16
print (b.att1)  # affiche -16

File: resume_utile.tex, line 885


class ma_classe :
    def __init__ (self, att1, att2, att3) :
        self.att1 = att1
        self.att2 = att2
        self.att3 = att3
        self.att4 = att1 * att2 * att3

a = ma_classe (1,2,3)
import copy
b = copy.copy (a)
b.att1 = -16
print (a.att1)  # affiche 1
print (b.att1)  # affiche -16

File: resume_utile.tex, line 910


class ma_classe :
    def __init__ (self, att1, att2, att3) :
        self.att1 = att1
        self.att2 = att2
        self.att3 = att3
        self.att4 = att1 * att2 * att3

class ma_classe2 (ma_classe) :      # héritage simple
    pass                            # pour dire que la classe est vide

File: resume_utile.tex, line 928


class ma_classe :
    def __init__ (self, att1) :
        self.att1 = att1
        self.att2 = self.calcul ()

    def calcul (self) :
        return self.att1 ** 2

class ma_classe2 (ma_classe) :
    def calcul (self) :
        # dans cette méthode, on change le comportement
        # de la méthode calcul tout en se servant de celui 
        # de la classe mère
        return ma_classe.calcul (self) * self.att1

a = ma_classe (2)
b = ma_classe2 (2)
print (a.att2)   # affiche 4  = 2 * 2
print (b.att2)   # affiche 8  = (2*2) * 2

File: resume_utile.tex, line 955


def makebold(fn):
    def wrapped():
        return "<b>" + fn() + "</b>"
    return wrapped

def makeitalic(fn):
    def wrapped():
        return "<i>" + fn() + "</i>"
    return wrapped

@makebold
@makeitalic
def hello():
    return "hello world"

print (hello()) ## returns <b><i>hello world</i></b>

File: resume_utile.tex, line 976


class C(object):
    def __init__ (self) :
        self._p = 1
    @property
    def p(self):
        return self._p
    @p.setter
    def p(self, val):
        self._p = val * 2
        
obj = C()
print (obj.p)  # utilise p_get, affiche 1
obj.p = 5      # utilise p_set
print (obj.p)  # utilise p_get affiche 10

File: resume_utile.tex, line 1003


f = open ("nom-fichier", "w") # ouverture en mode écriture "w" ou écriture ajout "a"

f.write (  s )                # écriture de la chaîne de caractères  s 
f.write (  s2 )               # écriture de la chaîne de caractères  s2
...

f.close ()  # fermeture

File: resume_utile.tex, line 1022


with open ("nom-fichier", "w") as f : 
    f.write (  s )                
    f.write (  s2 )               

File: resume_utile.tex, line 1029


with open ("nom-fichier", "w", encoding = "utf8") as f : 
    f.write (  s )                
    f.write (  s2 )               

File: resume_utile.tex, line 1039


f = open ("essai.txt", "r")   # ouverture du fichier en mode lecture
l = f.readlines ()            # lecture de toutes les lignes, 
                              #   elles sont placées dans une liste
f.close ()                    # fermeture du fichier

for s in l : print (s)        # on affiche les lignes à l'écran

File: resume_utile.tex, line 1053


f = open ("essai.txt", "r")     # ouverture du fichier en mode lecture
l = f.readlines ()              # lecture de toutes les lignes, 
                                #   elles sont placées dans une liste placées dans une liste
f.close ()                      # fermeture du fichier

l_net = []                      # contiendra la liste nettoyée des lignes du fichier
for s in l : 
    s2 = s.replace ("\n", "")   # on supprime le code de fin de ligne \n 
    s2 = s2.replace ("\r", "")  # on supprime le code de fin de ligne \r 
                                #                   (Windows uniquement)
	  s2 = s2.strip("\r\n")       # cette ligne est équivalente aux deux précédentes
    l_net.append (s2)           # on ajoute le résultat à la liste nettoyée

File: resume_utile.tex, line 1072


nom  ; prénom ; livre
Hugo  ; Victor  ; Les misérables
Kessel ; Joseph  ; Le lion
Woolf ; Virginia  ; Mrs Dalloway
Calvino ; Italo  ; Le baron perché

File: resume_utile.tex, line 1082


f = open ("essai.txt", "r")     # ouverture du fichier en mode lecture
l = f.readlines ()              # lecture de toutes les lignes, placées dans une liste
f.close ()                      # fermeture du fichier

for s in l : 
    s2 = s.replace ("\n", "")   # on supprime le code de fin de ligne \n 
    s2 = s2.replace ("\r", "")  # on supprime le code de fin de ligne \r (Windows uniquement)
    case = s2.split (";")
    if len (case) >= 3 :
        print (case [1], " ", case [0], " a écrit ", case [2])
				      # Version 2.x : print ...

File: resume_utile.tex, line 1102


# définition du module geometrie.py

def carre (x) :
    return x ** 2
    
class point :
    def __init__ (self,x,y) :
        self.x, self.y = x,y
        
    def norme (self) :
        return (self.x ** 2 + self.y ** 2) ** 0.5

File: resume_utile.tex, line 1120


import geometrie
print (geometrie.carre (1.5))
p = geometrie.point (1,2)

File: resume_utile.tex, line 1127


import geometrie as GEO  # on donne un pseudonyme au module geometrie
print (GEO.carre (1.5))
p = GEO.point (1,2)

File: resume_utile.tex, line 1134


from  geometrie import * 
print (carre (1.5))
p = point (1,2)

File: resume_utile.tex, line 1144


if __name__ == "__main__" :
    # quelques instructions ici

File: resume_utile.tex, line 1160


def inverse (x):
    y = 1.0 / x
    return y
b = inverse (0)
print (b)

File: resume_utile.tex, line 1170


Traceback (most recent call last):
  File "cours.py", line 2, in ?
    y = 1.0 / x
ZeroDivisionError: float division

File: resume_utile.tex, line 1179


def inverse (x):
    y = 1.0 / x
    return y
try :
    b = inverse (0)  # déclenche une exception
    print (b)
except :
    print ("le programme a déclenché une erreur")

File: resume_utile.tex, line 1192


def inverse (x):
    y = 1.0 / x
    return y
try :
    print (inverse (2))
    print (inverse (0))
except Exception as exc:
    print ("exception de type ", exc.__class__)
         # affiche exception de type  exceptions.ZeroDivisionError
    print ("message ", exc)
         # affiche le message associé à l'exception

File: resume_utile.tex, line 1208


def inverse (x):
    y = 1.0 / x
    return y
try :
    print ((-2.1) ** 3.1)
    print (inverse (2))
    print (inverse (0))
except ZeroDivisionError:
    print ("division par zéro")
except Exception as exc:
    print ("erreur insoupçonnée : ", exc.__class__)
    print ("message ", exc)

File: resume_utile.tex, line 1225


class AucunChiffre (Exception) :
    """chaîne de caractères contenant
    aussi autre chose que des chiffres"""

    def __init__(self, s, f = "") :
        Exception.__init__(self, s)
        self.s = s
        self.f = f

    def __str__(self) :
        return """exception AucunChiffre, lancée depuis la fonction """ + self.f + \
        " avec le paramètre " + self.s

def conversion (s) :
    """conversion d'une chaîne de caractères en entier"""
    if not s.isdigit () :
        raise AucunChiffre, (s, "conversion")
    return int (s)

try :
    s = "123a"
    i = conversion (s)
    print (s, " = ", i)
except AucunChiffre as exc :
    print (AucunChiffre.__doc__, " : ", exc)
    print ("fonction : ", exc.f)

File: resume_utile.tex, line 1264


s = "abcdefghijklmnopqrstuvwxyz"
print (s [4])    # affiche "e"
print (s [4:6])  # affiche "ef"

File: resume_utile.tex, line 1276


l  = [ un, deux, trois, quatre ]
up = []
for i in range (0, len (l)) :
    up.append ( l [i].upper () )

File: resume_utile.tex, line 1295


l  = [ "un", "deux", "trois", "quatre" ]
up = []
for i in range (0, len (l)) :
    up.append ( l [i].upper () )

File: resume_utile.tex, line 1304


l  = [ "un", "deux", "trois", "quatre" ]
up = []
for m in l :
    up.append ( m.upper () )

File: resume_utile.tex, line 1322


l = [ "un", "deux", "trois", "quatre" ]
s = ""
for m in l :
    s += m # concaténation des mots en une seule chaîne de caractères

File: resume_utile.tex, line 1336


a = calcul1 (3)
b = calcul2 (a)
c = calcul3 (b) # c résultat souhaité et affiché

File: resume_utile.tex, line 1346


def calcul1(x) :
    return x+3
y = calcul1(4)
print (y)            # affiche None
                     # car la fonction calcul1 ne retourne pas de résultat, elle l'affiche

File: resume_utile.tex, line 1356


def calcul1(x) : print (x+3)
def calcul2(x) : return calcul1(x) + 5
y = calcul2(4)     # affiche l'erreur
                   # ported operand type(s) for +: 'NoneType' and 'int'

File: resume_utile.tex, line 1399

    
def somme_double (liste) :
    return 1.0 * sum(liste)

def test_somme_double () :
    y = somme_double([ 1 ]) / 2
    if y == 0 : raise Exception ("valeur > 0 attendue")
        
if __name__ == "__main__" :
    test_somme_double()

File: resume_utile.tex, line 1413

    
Traceback (most recent call last):
  File "conseil.py", line 10, in <module>
    test_somme_double()
  File "conseil.py", line 7, in test_somme_double
    if y == 0 : raise Exception ("valeur > 0 attendue")
Exception: valeur > 0 attendue

File: chapn_tools.tex, line 41


def run () :
    files = [".\\genchm.py", ".\\genhelp.py", "os", "sys"]
    res   = genhelp.genhelp (files)
    print res  # ['genchm.html', 'genhelp.html', 'os.html', 'sys.html']   
    genchm (res, "GenHelp")
    
if __name__ == "__main__" :
    # écrit des informations relatives à l'exécution de la fonction
    # run () dans le fichier profile.txt
    import profile
    profile.run ('run()', "profile.txt")  
 
    # récupère les informations stockées dans profile.txt
    # et construit le nombre de passages dans chaque
    # fonction et les temps d'exécution moyen                                      
    import pstats
    p = pstats.Stats('profile.txt')
    p.strip_dirs().sort_stats(-1).print_stats()

File: chapn_tools.tex, line 62


Mon May 12 22:38:02 2008    profile.txt

         77 function calls in 5.557 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        5    0.000    0.000    0.000    0.000 :0(append)
        4    0.000    0.000    0.000    0.000 :0(close)
        2    0.000    0.000    0.000    0.000 :0(len)
        4    0.003    0.001    0.003    0.001 :0(open)
       16    0.000    0.000    0.000    0.000 :0(replace)
        1    0.001    0.001    0.001    0.001 :0(setprofile)
        2    0.000    0.000    0.000    0.000 :0(split)
        5    5.551    1.110    5.551    1.110 :0(system)
        4    0.000    0.000    0.000    0.000 :0(write)
        1    0.000    0.000    5.556    5.556 <string>:1(<module>)
        1    0.000    0.000    2.562    2.562 genchm.py:102(genchm)
        1    0.000    0.000    0.001    0.001 genchm.py:11(genhhp)
        1    0.000    0.000    5.556    5.556 genchm.py:113(run)
        1    0.000    0.000    0.001    0.001 genchm.py:42(gen_premierepage)
       13    0.000    0.000    0.000    0.000 genchm.py:54(genhh_input)
        1    0.000    0.000    0.001    0.001 genchm.py:61(genhhc)
        8    0.000    0.000    0.000    0.000 genchm.py:7(g)
        1    0.000    0.000    0.001    0.001 genchm.py:83(genhhk)
        4    0.000    0.000    2.993    0.748 genhelp.py:17(generate_help_file)
        1    0.000    0.000    2.994    2.994 genhelp.py:26(genhelp)
        0    0.000             0.000          profile:0(profiler)
        1    0.000    0.000    5.557    5.557 profile:0(run())

File: chapn_tools.tex, line 117


>>> addition ( [1,2], [3,-1])
[4, 1]

File: chapn_tools.tex, line 124


def _test():
    import doctest
    print doctest.testmod()

File: chapn_tools.tex, line 130


File "testdoc1.py", line 6, in __main__.addition
Failed example:
    addition ( [1,2], [3,-1])
Expected:
    [4,  1]
Got:
    [4, 1]
**********************************************************************
1 items had failures:
   1 of   2 in __main__.addition
***Test Failed*** 1 failures.

exemple de test avec \codesindex{doctest

# coding: latin-1
def addition (l1, l2):
    """cette fonction additionne deux listes
    >>> addition ( [], [])
    []
    >>> addition ( [1,2], [3,-1])
    [4, 1]
    """
    res = []
    for i in range (0, len (l1)) :
        res.append ( l1 [i] + l2 [i] )
    return res

def _test():
    import doctest
    doctest.testmod()

if __name__ == "__main__":
    _test()

File: chapn_tools.tex, line 148


Traceback (most recent call last):
    ...
Exception: listes de tailles différentes

exemple de test plus complet avec \codesindex{doctest

# coding: latin-1
def addition (l1, l2):
    """cette fonction additionne deux listes
    >>> addition ( [], [])
    []
    >>> addition ( [1,2], [3,-1])
    [4, 1]
    >>> addition ( [1], [3,-1])
    Traceback (most recent call last):
        ...
    Exception: listes de tailles différentes
    """
    if len (l1) != len (l2) :
        raise Exception ("listes de tailles différentes")
    res = []
    for i in range (0, len (l1)) :
        res.append ( l1 [i] + l2 [i] )
    return res

def _test():
    import doctest
    doctest.testmod()

if __name__ == "__main__":
    _test()

module à tester

# coding: latin-1
def addition (l1, l2):
    """cette fonction additionne deux listes"""
    if len (l1) != len (l2) :
        raise Exception ("listes de tailles différentes")    
    res = []
    for i in range (0, len (l1)) :
        res.append ( l1 [i] + l2 [i] )
    return res

liste de tests avec \codesindex{unittest

# coding: latin-1
import unittest
from testunit1 import *

class TestCase_for_addition (unittest.TestCase):
    
    def test_addition_vide (self) :
        """test_addition_vide : on vérifie que l'addtion de deux listes retourne une liste vide"""
        assert [] == addition ( [], [] )
        
    def test_addition (self) :
        """test_addition : test de [1,2] + [3,-1] != [4,1]"""
        l1 = [1,2]
        l2 = [3,-1]
        l  = addition (l1, l2)
        assert l [0] == 4 and l [1] == 1
        
    def test_exception (self) :
        """test_exception : on vérifie que l'addition 
        de deux listes de tailles différentes génère une exception"""
        l1 = [1]
        l2 = [3,-1]
        try :
            l  = addition (l1, l2)  # la fonction doit lancer une exception
            assert False            # si elle ne le fait pas, alors le test a achoué
        except Exception, e :
            # on vérifie que l'exception générée n'est pas due à l'instruction assert False
            assert str (e.__class__ .__name__) != "AssertionError"
            # on vérifie ici que le message de l'exception est celui attendu
            assert str (e) == "listes de tailles différentes"

if __name__ == "__main__" :
    # on lance les tests
    unittest.main ()                       

File: chapn_tools.tex, line 187


======================================================================
ERROR: test_addition : test de [1,2] + [3,-1] != [4,1]
----------------------------------------------------------------------
Traceback (most recent call last):
  File "testunit2.py", line 16, in test_addition
    assert l [0] == 4 and l [1] == 1
IndexError: list index out of range

File: chapn_tools.tex, line 197


======================================================================
FAIL: on vérifie que l'addition de deux listes de tailles différentes génère une exception
----------------------------------------------------------------------
Traceback (most recent call last):
  File "testunit2.py", line 27, in test_exception
    assert str (e.__class__ .__name__) != "AssertionError"
AssertionError

exécution de tests unitaires répartis sur plusieurs fichiers

# coding: latin-1
import unittest
import os

def get_test_file () :
    """retourne la liste de tous les fichiers *.py commençant par test_"""
    li = os.listdir (".")
    li = [ l for l in li if "test_" in l and ".py" in l and \
                            ".pyc" not in l and ".pyd" not in l]
    return li

def import_files (li) :
    """pour un fichier test_*.py, cherche les classes Test...
    et crée une suite de test pour ses méthodes commençant 
    par test..., retourne la suite de test"""
    allsuite = []
    for l in li :
        fi = l.replace (".py", "")
        mo = __import__ (fi)
        cl = dir (mo)
        for c in cl :
            if len (c) < 5 or c [:4] != "Test" : continue
            # classe de test c
            testsuite = unittest.TestSuite ()
            exec compile ("di = dir (mo." + c + ")", "", "exec")
            for d in di :
                if len (d) < 5 or d [:4] != "test" : continue
                # method d.c
                exec compile ("t = mo." + c + "(\"" + d + "\")", "", "exec")
                testsuite.addTest (t)
        allsuite.append ((testsuite, l))

    return allsuite

def main () :
    """crée puis lance les suites de textes définis dans 
    des programmes test_*.py"""
    li      = get_test_file ()
    suite   = import_files (li)
    runner  = unittest.TextTestRunner()
    for s in suite :
        print "running test for ", s [1]
        runner.run (s [0])
    
if __name__ == "__main__" :
    main ()

File: chapn_tools.tex, line 221


# coding: cp1252
import glob
import shutil
def copie_repertoire (rep1, rep2) :
    """copie tous les fichiers d'un répertoire rep1 vers un autre rep2"""
    li = glob.glob (rep1 + "/*.*")
    for l in li :
        to = l.replace (rep1, rep2)  # nom du fichier copié (on remplace rep1 par rep2)
        shutil.copy (l, to)
copie_repertoire ("c:/original", "c:/backup")

File: chapn_tools.tex, line 235


c:\python25\python.exe synchro.py c:/original c:/backup

File: chapn_tools.tex, line 247


interpréteur_python programme_python argument1 argument2 ...

lancer un programme \pythons en ligne de commande

# coding: latin-1
import glob
import shutil
def copie_repertoire (rep1, rep2) :
    """copie tous les fichiers d'un répertoire rep1 vers un autre rep2"""
    li = glob.glob (rep1 + "/*.*")
    for l in li :
        to = l.replace (rep1, rep2)  # nom du fichier copié 
                                     # (on remplace rep1 par rep2)
        shutil.copy (l, to)
        
import sys
                      # sys.argv [0] --> nom du programme (ici, synchro.py)
rep1 = sys.argv [1]   # récupération du premier paramètre
rep2 = sys.argv [2]   # récupération du second paramètre
copie_repertoire (rep1, rep2)

File: chapn_tools.tex, line 265


c:\python25\python.exe c:\batch\synchro.py "c:\Program Files\source" "c:\Program Files\backup"

File: chapn_tools.tex, line 276


os.system ("scite -open:fichier.txt")

File: chapn_tools.tex, line 282


import subprocess
args = ["scite.exe", "-open:fichier.txt"]
proc = subprocess.Popen(args)
retcode = proc.wait()            # on attend la fin de l'exécution
if retcode!=0:
    # ici, traiter les erreurs

File: chapn_tools.tex, line 293


import subprocess
args = ["scite.exe", "-open:fichier.txt", ">>output.txt"]
proc = subprocess.Popen(args)

File: chapn_tools.tex, line 457


cd "répertoire d'installation de SVN\bin"
svnadmin create c:\svnrepository

File: chapn_tools.tex, line 472


ping 127.0.0.1

File: chapn_tools.tex, line 480


http://127.0.0.1:81/

File: chapn_tools.tex, line 517


c:\python25\python c:\python25\lib\pydoc.py random
c:\python25\python c:\python25\lib\pydoc.py .\mon_programme.py

File: chapn_tools.tex, line 522


import os
os.system (r"c:\python25\python c:\python25\lib\pydoc.py .\mon_programme.py")

génération automatique de l'aide

# coding: latin-1
"""genhelp.py : génération automatique de l'aide dans le répertoire d'exécution"""
import os
import sys
python_path = r"c:\python25\python"          # constante
pydoc_path  = r"c:\python25\lib\pydoc.py"    # constante

class ClassExemple :
    """classe vide, exemple d'aide"""
    def __init__ (self) :
        """constructeur"""
        pass
    def methode (self) :
        """unique méthode"""
        return 1

def generate_help_file (f, pyt = python_path, pyd = pydoc_path) :
    """génère l'aide associée à un fichier ou un module
    le nom de ce fichier peut apparaître sans son extension ou alors
    précédé de .\\ ou avec son chemin complet
    pyt est le répertoire de python
    pyd est l'emplacement de pydoc.py"""
    s = "call " + pyt + " " + pyd + " -w " + f
    os.system (s)
    
def replace_firstpage (file, page) :
    """la génération de l'aide chm s'arrête avant la fin si le lien <a href=".">index</a>
    est laissé dans les pages générées par pydoc, on le remplace par une page
    comme index.html"""
    f = open (file, "r")
    li = f.readlines ()
    f.close ()
    f = open (file, "w")
    for l in li :
        f.write (l.replace ("""<a href=".">index</a>""", page))
    f.close ()
    
def genhelp (files, pyt = python_path, pyd = pydoc_path, firstpage = "index.html") :
    """génère l'aide associée à des fichiers ou des modules,
    un fichier se distingue d'un module par son extension,
    retourne la liste des fichiers générés,
    pyt est le répertoire de python
    pyd est l'emplacement de pydoc.py
    firstpage voir fonction replace_firstpage"""
    res = []
    for f in files :
        print "génération de l'aide de ", f
        if ".py" in f : # fichier
            generate_help_file (f, pyt, pyd)
            g    = f.split ("\\")  # ne garde que le nom de fichier et non son chemin
            page = g [ len (g)-1].replace (".py", ".html")
        else :          # module
            generate_help_file (f, pyt, pyd)
            page = f + ".html"
        res.append (page)
        replace_firstpage (page, firstpage)
    return res

if __name__ == "__main__" :
    import sys
    import os

    files = [".\\genchm.py", ".\\genhelp.py", "os", "sys"]
    res   = genhelp (files)
    print res  # ['genchm.html', 'genhelp.html', 'os.html', 'sys.html']

exemple de fichier \textit{hpp

[OPTIONS]
Compatibility=1.1 
Full-text search=Yes
Contents file=help.hhc    # fichier table des matières
Default Window=main
Default topic=index.html  # page par défaut, première page à apparaître
Index file=help.hhk       # fichier index
Language=0x40C French
Binary TOC=YES
Create CHI file=No
Title="GenHelp"           # titre

[WINDOWS]                 # définition de la page principale, elle reprend des éléments cités ci-dessus
main="GenHelp", "help.hhc", "help.hhk" , "index.html", "index.html",,,,,0x23520,,0x387e,,,,,,,,0

[FILES]                   # ici commence la liste des fichiers à insérer dans le projet
genchm.html
genhelp.html
os.html
sys.html
index.html

File: chapn_tools.tex, line 568


<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><HTML><HEAD></HEAD><BODY>

File: chapn_tools.tex, line 572


</BODY></HTML>

File: chapn_tools.tex, line 576


<LI><OBJECT type="text/sitemap">
<param name="Name" value="intitule">
<param name="Local" value="page HTML correspondante">
<param name="ImageNumber" value="11"></OBJECT>

exemple de fichier \textit{hhk

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><HTML><HEAD></HEAD><BODY>
<OBJECT type="text/site properties">param name="GenHelp" value="right">OBJECT>
<UL>
    <LI><OBJECT type="text/sitemap">
        <param name="Name" value="GenHelp">
        <param name="Local" value="index.html">
        <param name="ImageNumber" value="11"></OBJECT>
    <UL>
        <LI><OBJECT type="text/sitemap">
            <param name="Name" value="genchm">
            <param name="Local" value="genchm.html">
            <param name="ImageNumber" value="11"></OBJECT>
        <LI><OBJECT type="text/sitemap">
            <param name="Name" value="genhelp">
            <param name="Local" value="genhelp.html">
            <param name="ImageNumber" value="11"></OBJECT>
        <LI><OBJECT type="text/sitemap">
            <param name="Name" value="os">
            <param name="Local" value="os.html">
            <param name="ImageNumber" value="11"></OBJECT>
        <LI><OBJECT type="text/sitemap">
            <param name="Name" value="sys">
            <param name="Local" value="sys.html">
            <param name="ImageNumber" value="11"></OBJECT>
        <LI><OBJECT type="text/sitemap">
            <param name="Name" value="index">
            <param name="Local" value="index.html">
            <param name="ImageNumber" value="11"></OBJECT>
    </UL>
</UL>
</BODY></HTML>

génération automatique d'un fichier \textit{chm

# coding: latin-1
"""genchm.py : génération automatique du fichier d'aide chm"""
import genhelp
import os
htmlworkshop_path = "\"c:\\Program Files\\HTML Help Workshop\\hhc.exe\""

def g (s) :
    """ajoute des guillements autour d'une chaîne de caractères"""
    return "\"" + s + "\""
    
def genhhp (files, premierepage, titre, \
            hhp = "help.hhp", hhc = "help.hhc", hhk = "help.hhk") :
    """génère le fichier hpp définissant le fichier d'aide chm,
    files est la liste des fichiers HTML
    premierepage est la page à afficher en premier
    titre est le titre de l'aide"""
    proj = """[OPTIONS]
Compatibility=1.1
Full-text search=Yes
Contents file=""" + hhc + """
Default Window=main
Default topic=""" + premierepage + """
Index file=""" + hhk + """
Language=0x40C French
Binary TOC=YES
Create CHI file=No
Title=""" + g (titre) + """

[WINDOWS]
main=""" + g (titre) + """, """ + g (hhc) + """, """ + g (hhk) + """ , """ + \
        g (premierepage) + """, """ + g (premierepage) + """,,,,,0x23520,,0x387e,,,,,,,,0

[FILES]
"""
    for f in files :
        proj += f + "\n"
        
    f = open (hhp, "w")
    f.write (proj)
    f.close ()
    
def gen_premierepage (files, titre, res = "index.html") :
    """génère la première page de l'aide au format HTML"""
    s = """<HTML><head><title>""" + titre + """</title></head><BODY>\n"""
    s += "<H1>" + titre + "</H1>\n"
    for f in files :
        s += "<A HREF=\"" + f + "\">" + f.replace (".html", "") + "</A><BR>\n"
    s += "</BODY></HTML>\n"
    
    f = open (res, "w")
    f.write (s)
    f.close ()
    
def genhh_input (entree, page, link = True) :
    """retourne la chaîne de caractères associée à une entrée de la table des matières"""
    res = """<LI><OBJECT type="text/sitemap"><param name="Name" value=\"""" + entree + """\">"""
    if link : res += """<param name="Local" value=\"""" + page + """\">"""
    res += """<param name="ImageNumber" value="11"></OBJECT>\n"""
    return res
    
def genhhc (files, premierepage, titre, hhc = "help.hhc") :
    """génère le fichier hhc, même paramètre que pour hhp"""
    res ="""<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><HTML><HEAD></HEAD><BODY>
        <OBJECT type="text/site properties">
        <param name=""" + g (titre) + """ value="right">
        </OBJECT>
        <UL>"""
    res += genhh_input (titre, premierepage, False)
    res += "<UL>\n"
    res += genhh_input ("modules", premierepage, False)
    res += "<UL>\n"
    for f in files :
        res += genhh_input (f.replace (".html", ""), f)
    res += "</UL>\n"
    res += "</UL>\n"
    res += "</UL>\n"
    res += "</BODY></HTML>\n"
    
    f = open (hhc, "w")
    f.write (res)
    f.close ()

def genhhk (files, premierepage, titre, hhk = "help.hhk") :
    """génère le fichier hhk, même paramètre que pour hhp"""
    res ="""<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><HTML><HEAD></HEAD><BODY>
        <OBJECT type="text/site properties">
        <param name=""" + g (titre) + """ value="right">
        </OBJECT>
        <UL>"""
    res += genhh_input (titre, premierepage)
    res += "<UL>\n"
    for f in files :
        res += genhh_input (f.replace (".html", ""), f)
    res += "</UL>\n"
    res += "</UL>\n"
    res += "</BODY></HTML>\n"
    
    f = open (hhk, "w")
    f.write (res)
    f.close ()

def genchm (files, titre, \
            hhp = "help.hhp", hhc = "help.hhc", hhk = "help.hhk") :
    """génère le fichier d'aide complet"""
    premierepage = "index.html"                     # génère la page de garde
    gen_premierepage (files, titre, premierepage)   
    files.append (premierepage) 
    genhhp (files, premierepage, titre)             # génère le fichier hhp
    genhhc (files, premierepage, titre)             # génère le fichier hhc
    genhhk (files, premierepage, titre)             # génère le fichier hhk
    os.system (htmlworkshop_path + " " + hhp)       # appelle HTML WorkShop en ligne de commande

if __name__ == "__main__" :
    files = [".\\genchm.py", ".\\genhelp.py", "os", "sys"]
    res   = genhelp.genhelp (files)
    print res  # ['genchm.html', 'genhelp.html', 'os.html', 'sys.html']   
    genchm (res, "GenHelp")

File: chapn_tools.tex, line 625


[Setup]                                    ; nom de la section 
AppName=HalPython                          ; nom de l'application à installer
AppVerName=HalPython 1.5.1162              ; numéro de version
AppPublisher=Xavier Dupré                  ; auteur
AppPublisherURL=http://www.xavierdupre.fr/ ; site web
AppSupportURL=http://www.xavierdupre.fr/   ; site web, support
AppUpdatesURL=http://www.xavierdupre.fr/   ; site web, mise à jour
DefaultDirName={pf}/HalPython              ; emplacement par défaut sur la machine utilisateur
                                           ; le code {pf} signife le répertoire \textit{Program Files}
DefaultGroupName=HalPython                 ; nom par défaut du sous menu dans 
                                           ;                            Démarrer / Tous les programmes
OutputDir=c:                               ; répertoire où sera écrit l'installateur
OutputBaseFilename=setup_HalPython_py25    ; nom de l'installateur ou setup
Compression=lzma                           ; type de compression, ne pas changer 
SolidCompression=yes                       ; type de compression, ne pas changer
VersionInfoVersion=1.0.0                   ; version, ne pas changer

File: chapn_tools.tex, line 648


[Files]
Source: "chemin_concepteur"; DestDir: "chemin_utilisateur"  ;
Source: "..\hal_dll.dll"; DestDir: "{app}\hal_python"       ; autre exemple

File: chapn_tools.tex, line 660


[Run]
Filename: "{win}\system32\msiexec.exe"; Parameters: "/i ""{app}\python-2.5.2.msi"" /qr ALLUSERS=1"; 
Filename: "{cmd}"; Parameters: "/c del python-2.5.2.msi"; WorkingDir: "{app}";

File: chapn_tools.tex, line 671


[Icons]
; liens vers diverses applications
Name: "{group}\PyScripter"; Filename: "{app}\PyScripter.exe"; WorkingDir: "{app}"
Name: "{group}\PyScripter Help"; Filename: "{app}\pyscripter.chm"; WorkingDir: "{app}"
Name: "{group}\Help"; Filename: "{app}\hal_python.chm"; WorkingDir: "{app}"
Name: "{group}\smallest sample with PyScripter"; Filename: "{app}\small_sample.bat"; WorkingDir: "{app}"

; hyperlien ou url vers un site
Name: "{group}\Website"; Filename: "{app}\hal_python.url"

; lien vers le désinstalleur créé automatiquement par InnoSetup
Name: "{group}\uninstall"; Filename: "{uninstallexe}"; WorkingDir: "{app}"  

File: chapn_tools.tex, line 688


[InternetShortcut]
URL=http://www.xavierdupre.fr/hal_python/hal_python_help_html/index.html

File: chapn_tools.tex, line 695


[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; 
    Flags: checkedonce

File: chapn_tools.tex, line 705


[Registry]
Root: HKLM; Subkey: "SOFTWARE\HalPython\InstallPath"; ValueType: string; ValueName: ""; 
      ValueData: "{app}"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\HalPython\Version"; ValueType: string; 
     ValueName: ""; ValueData: "1.5.1162"; Flags: uninsdeletekey

construction d'un installateur

; section non commentée
[Setup]
AppName=HalPython
AppVerName=HalPython 1.5.1162
AppPublisher=Xavier Dupré
AppPublisherURL=http://www.xavierdupre.fr/hal_python/hal_python_help_html/index.html
AppSupportURL=http://www.xavierdupre.fr/hal_python/hal_python_help_html/index.html
AppUpdatesURL=http://www.xavierdupre.fr/hal_python/hal_python_help_html/index.html
DefaultDirName={pf}/HalPython
DefaultGroupName=HalPython
OutputDir=D:\Dupre\_data\site\hal_python\executable
OutputBaseFilename=setup_HalPython_py25
Compression=lzma
SolidCompression=yes
VersionInfoVersion=1.0.0

[Code]

; cette fonction retourne le chemin d'installation de Python 2.5
; le résultat est vide si celui-ci n'a pas été installé
; le chemin est celui stocké dans la clé de registre 
;           HKLM\Software\Python\PythonCore\2.5\InstallPath
function GetPythonPath(Param: String): String;
begin
  Result := '';
  Result := ExpandConstant('{reg:HKLM\Software\Python\PythonCore\2.5\InstallPath,|}');
  if Result <> '' then
    Result := Result + '\pythonw.exe';
end;

; cette fonction retourne {win}\system32\msiexec.exe
; si Python 2.5 a été installé, vide sinon
function GetPythonPathExec(Param: String): String;
begin
  Result := GetPythonPath () ;
  if Result <> '' then
    Result := ExpandConstant('{win}\system32\msiexec.exe') ;
end;

; clés de registre
; mémorise le répertoire d'installation
; et le numéro de version
[Registry]
Root: HKLM; Subkey: "SOFTWARE\HalPython\InstallPath"; ValueType: string; ValueName: ""; 
        ValueData: "{app}"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\HalPython\Version"; ValueType: string; ValueName: ""; 
        ValueData: "1.5.1162"; Flags: uninsdeletekey

; icône sur le bureau
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; 
     Flags: checkedonce

; fichiers
[Files]
; le module en question
Source: "..\hal_dll.dll"; DestDir: "{app}\hal_python";
Source: "..\hal_dll_ext.dll"; DestDir: "{app}\hal_python";
Source: "..\hal_dll_model.dll"; DestDir: "{app}\hal_python";
Source: "..\hal_python.dll"; DestDir: "{app}\hal_python";
Source: "..\wxwindows_old.dll"; DestDir: "{app}\hal_python";
Source: "..\boost_python.dll"; DestDir: "{app}\hal_python";
Source: "..\_graphviz_draw.exe"; DestDir: "{app}\hal_python";
Source: "..\_hal_script.exe"; DestDir: "{app}\hal_python";
Source: "..\hal_python.py"; DestDir: "{app}\hal_python";
Source: "..\install\__init__.py"; DestDir: "{app}\hal_python";
Source: "..\install\setup.py"; DestDir: "{app}";
Source: "..\_test\temp\hal_python.chm"; DestDir: "{app}";

; les fichiers annexes
Source: "hal_python.url"; DestDir: "{app}";    URL de l'application
Source: "pyscripter.chm"; DestDir: "{app}";    aide de l'éditeur PyScripter
Source: "PyScripter.exe"; DestDir: "{app}";    éditeur PyScripter
Source: "python-2.5.2.msi"; DestDir: "{app}";  installateur Python 2.5
Source: "sample.bat"; DestDir: "{app}";        fichier de commande
Source: "sample.py"; DestDir: "{app}";         exemple de programme

; création des icônes
[Icons]
Name: "{group}\PyScripter"; Filename: "{app}\PyScripter.exe"; WorkingDir: "{app}"
Name: "{group}\PyScripter Help"; Filename: "{app}\pyscripter.chm"; WorkingDir: "{app}"
Name: "{group}\Help"; Filename: "{app}\hal_python.chm"; WorkingDir: "{app}"
Name: "{group}\smallest sample with PyScripter"; Filename: "{app}\small_sample.bat"; WorkingDir: "{app}"
Name: "{group}\Website"; Filename: "{app}\hal_python.url"
Name: "{group}\uninstall"; Filename: "{uninstallexe}"; WorkingDir: "{app}"

[Run]
; installe Python 2.5 si GetPythonPathExec retourne un résultat non vide
; passe à l'instruction suivante sinon
Filename: "{code:GetPythonPathExec}"; Parameters: "/i ""{app}\python-2.5.2.msi"" /qr ALLUSERS=1"; 
          StatusMsg: "Installing Python 2.5..."; Flags: skipifdoesntexist
          
; installe le module  si GetPythonPath retourne un résultat non vide
; passe à l'instruction suivante sinon
; exécute en fait l'insttruction python setup.py install
Filename: "{code:GetPythonPath}"; Parameters:"setup.py install"; WorkingDir: "{app}"; 
          StatusMsg: "Installing HalPython for Python 2.5..."

; supprime l'installation de Python 2.5
Filename: "{cmd}"; Parameters: "/c del python-2.5.2.msi"; WorkingDir: "{app}";

File: chapn_tools.tex, line 730


PyScripter.exe sample.py

construction d'un installateur de mise à jour

; section non commentée
[Setup]
AppName=HalPython
AppVerName=HalPython 1.5.1162
AppPublisher=Xavier Dupré
AppPublisherURL=http://www.xavierdupre.fr/hal_python/hal_python_help_html/index.html
AppSupportURL=http://www.xavierdupre.fr/hal_python/hal_python_help_html/index.html
AppUpdatesURL=http://www.xavierdupre.fr/hal_python/hal_python_help_html/index.html
DefaultDirName={pf}/HalPython
DefaultGroupName=HalPython
OutputDir=D:\Dupre\_data\site\hal_python\executable
OutputBaseFilename=setup_HalPython_update_py25
Compression=lzma
SolidCompression=yes
VersionInfoVersion=1.0.0

[Code]
function GetPythonPath(Param: String): String;
begin
  Result := '';
  Result := ExpandConstant('{reg:HKLM\Software\Python\PythonCore\2.5\InstallPath,|}');
  if Result <> '' then
    Result := Result + '\pythonw.exe';
end;

function GetHalPythonPath(Param: String): String;
begin
  Result := '';
  Result := ExpandConstant ('{reg:HKLM\Software\HalPython\InstallPath,|}') ;
end;

function InitializeSetup(): Boolean;
begin
  Result := True ;
  MsgBox (GetPythonPath (''), mbConfirmation, MB_OK) ;
  MsgBox (GetHalPythonPath (''), mbConfirmation, MB_OK) ;
  if GetPythonPath ('') = '' then begin
    MsgBox('Python 2.5 has not been installed. You should download 
            the complete Setup with Python 2.5 included instead of updating.', mbError, MB_OK) ;
    Result := False ;
  end else if GetHalPythonPath ('') = '' then begin
    MsgBox('HalPython for Python 2.5 has not been installed. 
            You should download the complete Setup with Python 2.5 included instead of updating.', 
            mbError, MB_OK) ;
    Result := False ;
  end
end;

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; 
      Flags: checkedonce

[Files]
Source: "..\hal_dll.dll"; DestDir: "{app}\hal_python";
Source: "..\hal_dll_ext.dll"; DestDir: "{app}\hal_python";
Source: "..\hal_dll_model.dll"; DestDir: "{app}\hal_python";
Source: "..\hal_python.dll"; DestDir: "{app}\hal_python";
Source: "..\wxwindows_old.dll"; DestDir: "{app}\hal_python";
Source: "..\boost_python.dll"; DestDir: "{app}\hal_python";
Source: "..\_graphviz_draw.exe"; DestDir: "{app}\hal_python";
Source: "..\_hal_script.exe"; DestDir: "{app}\hal_python";
Source: "..\hal_python.py"; DestDir: "{app}\hal_python";
Source: "..\install\__init__.py"; DestDir: "{app}\hal_python";
Source: "..\install\setup.py"; DestDir: "{app}";
Source: "hal_python.url"; DestDir: "{app}";
Source: "small_sample.bat"; DestDir: "{app}";
Source: "sample.py"; DestDir: "{app}";
Source: "..\_test\temp\hal_python.chm"; DestDir: "{app}";

[Registry]
Root: HKLM; Subkey: "SOFTWARE\HalPython\InstallPath"; ValueType: string; ValueName: ""; 
      ValueData: "{app}"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\HalPython\Version"; ValueType: string; ValueName: ""; 
      ValueData: "1.5.1162"; Flags: uninsdeletekey

[Icons]
Name: "{group}\PyScripter"; Filename: "{app}\PyScripter.exe"; WorkingDir: "{app}"
Name: "{group}\PyScripter Help"; Filename: "{app}\pyscripter.chm"; WorkingDir: "{app}"
Name: "{group}\Help"; Filename: "{app}\hal_python.chm"; WorkingDir: "{app}"
Name: "{group}\smallest sample with PyScripter"; Filename: "{app}\small_sample.bat"; WorkingDir: "{app}"
Name: "{group}\Website"; Filename: "{app}\hal_python.url"
Name: "{group}\uninstall"; Filename: "{uninstallexe}"; WorkingDir: "{app}"

[Run]
Filename: "{code:GetPythonPath}"; Parameters:"setup.py install"; WorkingDir: "{app}"; 
     StatusMsg: "Installing HalPython for Python 2.5..."

File: chapn_tools.tex, line 747


[Code]
function GetLnkSciTE(Param:String): String;
begin
    Result := CreateShellLink(ExpandConstant('{app}\SciTE sample.lnk'), 
                              'Opens SciTE with a sample', 
                              ExpandConstant('{app}\wscite\scite.exe'), 
                              ExpandConstant('"{app}\sample.py"'), 
                              ExpandConstant('{app}'),
                              '', 
                              0, 
                              SW_SHOWNORMAL);
end;

[Icons]
Name: "{group}\smallest sample with SciTE"; Filename: "{code:GetLnkSciTE}"; WorkingDir: "{app}"

File: chapn_tools.tex, line 769


def replace_string (file, s1, s2) :
    f = open (file, "r")
    li = f.readlines ()
    f.close ()
    f = open (file, "w")
    for l in li :
        s = l.replace (s1, s2)
        f.write (s)
    f.close ()

if __name__ == "__main__" :
    import sys
    file = sys.argv [1]  # fichier à modifier
    s1   = sys.argv [2]  # chaîne à remplacer
    s2   = sys.argv [3]  # nouvelle chaîne
    replace_string (file, s1, s2)

File: chapn_tools.tex, line 790

    
[Code]
; retourne le chemin du programme pythonw.exe
function GetPythonPathW(Param: String): String;
begin
  Result := '';
  Result := ExpandConstant('{reg:HKLM\Software\Python\PythonCore\2.5\InstallPath,|}');
  if Result <> '' then
    Result := Result + '\pythonw';
end;

; construit les paramètres de la ligne de commande
; "c:\Program Files\HalPython\replace_conf.py" "=pythonw" "=c:\python25\pythonw"
function GetReplaceConf(Param:String):String;
begin
    Result := ExpandConstant ('"{app}\replace_conf.py"')
    Result := Result + ' ' + ExpandConstant ('"{app}\wscite\python.properties"')
    Result := Result + ' "=pythonw"'
    Result := Result + ' "=' + GetPythonPathW ('') + '"' ;
end;

[Run]
; exécution de la ligne de commande
Filename: "{code:GetPythonPath}"; Parameters:"{code:GetReplaceConf}"; WorkingDir: "{app}"; 

File: chapn_tools.tex, line 818

 
c:\python25\pythonw "c:\Program Files\HalPython\replace_conf.py" "=pythonw" "=c:\python25\pythonw"

File: chapn_tools.tex, line 855


C:
cd c:\TEMP\moin-1.6.3
C:\Python25\python setup.py install --record=install.log

File: chapn_tools.tex, line 864


cd C:\
md Moin
md Moin\mywiki
md Moin\mywiki\data
md Moin\mywiki\underlay
cd c:\Python25\share\moin
xcopy data       C:\Moin\mywiki\data /E
xcopy underlay   C:\Moin\mywiki\underlay /E
copy  config\*.* C:\Moin\mywiki\*.*
copy  server\*.* C:\Moin\mywiki\*.*

File: chapn_tools.tex, line 892


#!/usr/env/bin python

File: chapn_tools.tex, line 897


#!c:/Python25/python.exe

File: chapn_tools.tex, line 912


data_dir = r'C:\Moin\mywiki\data'
data_underlay_dir = r'C:\Moin\mywiki\underlay'

File: chapn_tools.tex, line 919


actions_excluded = ['DeletePage', 'RenamePage', ]

File: chapn_tools.tex, line 925


superuser = [u"admin", ]

File: chapn_tools.tex, line 931


acl_rights_before = u"admin:read,write,delete,revert,admin"

File: chapn_tools.tex, line 940


sitename = u'NomSite'
page_front_page = u"FirstPage"

File: chapn_tools.tex, line 948


language_default = 'fr'

File: chapn_tools.tex, line 986


acl_rights_default = u"dupre:read,write,delete,revert,admin All:read"            

File: chapn_tools.tex, line 1008


theme_default = 'modern'

File: chapn_tools.tex, line 1040

            
<<TableOfContents(2)>>

= Titre 1 =

http://www.xavierdupre.fr/mywiki/XavierDupre

== Titre 1 niveau 2 ==
= Titre 2 =
  
Affichage d'une liste :
  * élément 1
  * élément 2
  * élement 3 : sous liste
     * sous élément 1
     * sous élément 2
  * dernier élément de la première liste

''italique''    '''gras''' __souligné__

une ligne

----            

File: chapn_tools.tex, line 1079


http://www.xavierdupre.fr/mywiki/XavierDupre
[[http://www.xavierdupre.fr/mywiki/XavierDupre|wiki de Xavier Dupré]]

File: chapn_tools.tex, line 1095


#acl dupre:read,write

File: chapn_tools.tex, line 1109


<Directory "C:/Program Files/Apache Software Foundation/Apache2.2/python_cgi">
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Allow from all
</Directory>

Alias /pycgih "C:/Program Files/Apache Software Foundation/Apache2.2/python_cgi"   
ScriptAlias /pycgi "C:/Program Files/Apache Software Foundation/Apache2.2/python_cgi"   

File: chapn_tools.tex, line 1124


#!c:/Python25/python.exe
# ligne 1 : emplacement de python (obligatoire)
# ligne 2 : la page ne contiendra que du texte
print "Content-Type: text/plain\n\n"
# premier message au navigateur
print "premier message\n"

File: chapn_tools.tex, line 1135


<html><body>
<h1> Lien vers un script CGI écrit en Python </h1>
<a href="/pycgi/hello.cgi">hello.cgi</a>
</body></html>

File: chapn_tools.tex, line 1144


http://localhost/pycgih/index.html

File: chapn_tools.tex, line 1159


print "Content-Type: text/html\n\n"

File: chapn_tools.tex, line 1166


#!c:/Python25/python.exe
# coding: cp1252
print "Content-Type: text/html\n\n"
# premier message au navigateur,
# les passages à la ligne \n sont sans effet à l'affichage
print "<html><body>\n"
print "<b>premier message en gras</b>\n"
print "</body></html>"

File: chapn_tools.tex, line 1187


#!c:/Python25/python.exe
# coding: cp1252
print "Content-Type: text/html\n\n"
print "<html><body>\n"
try:
    print "<b>premier message en gras</b>\n"
    print "<br>déclenchement d'une erreur (instruction inconnue)<br>"
    stop
except:
    import sys
    import traceback
    print "<pre>"
    traceback.print_exc(file=sys.stdout)
    print "</pre>"
print "</body></html>"

File: chapn_tools.tex, line 1207


Traceback (most recent call last):
  File "C:/Program Files/Apache Software Foundation/Apache2.2/python_cgi/hello4.cgi", line 8, in 
    stop
NameError: name 'stop' is not defined

File: chapn_tools.tex, line 1221


<balise>  ....  </balise>

File: chapn_tools.tex, line 1228


<html>
<head>
.... entête de la page, n'est pas affiché, il est possible d'y définir
.... des feuilles de styles pour un affichage amélioré
.... ou la définition de nouvelles balises
.... la ligne 
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
.... permet de définir un jeu de caractères incluant les accents français
</head>
<body>
.... contenu de la page
</body>
</html>

File: chapn_tools.tex, line 1300


http://URL?param1=valeur1¶m2=valeur2&...

File: chapn_tools.tex, line 1307


#!c:/Python25/python.exe
# coding: cp1252
print "Content-Type: text/html\n\n"
print "<html><body>\n"
import cgi
par = cgi.FieldStorage()
if len (par) == 0 :
    print "<b> aucun paramètre à cette page </b>"
else :
    print "<b>liste des paramètres </b><br>"
    print """<table border="1">"""
    for p in par :
        print "<tr>"
        name  = str (p)
        value = par.getvalue (name)
        print "<td>", name, "</td><td>", value, "</td>"
        print "</tr>"
    print "</table>"
print "</body></html>"

File: chapn_tools.tex, line 1332


http://localhost/pycgi/pyform.cgi

File: chapn_tools.tex, line 1337


http://localhost/pycgi/pyform.cgi?nom=dupre&prenom=xavier

File: chapn_tools.tex, line 1351


#!c:/Python25/python.exe
# coding: cp1252
print "Content-Type: text/html\n\n"
print "<html><body>\n"
def print_form () :
    # création du formulaire avec deux champs nom et et prenom
    print """
    <FORM action="/pycgi/pyform.cgi" method=post>
    <P>
    <LABEL for="nom">Nom : </LABEL> <INPUT type="text" name="nom"><BR>
    <LABEL for="prenom">Prénom : </LABEL> <INPUT type="text" name="prenom"><BR>
    <INPUT type=submit value="Envoyer"> <INPUT type=reset value="Annuler">
    </P>
    </FORM>
    """
    
import cgi
par = cgi.FieldStorage ()
if len (par) == 0 :
    # s'il n'y a aucun paramètre, on affiche le formulaire
    print_form ()
else :
    # sinon, cela signifie que le formulaire a rappelé le script CGI
    # avec des paramètres et le traitement suit une direction différente
    # ici, cela consiste à afficher les informations reçues en gras
    nom = par.getvalue ("nom")
    prenom = par.getvalue ("prenom")
    print "Votre nom est <b>", nom, "</b> et votre prénom <b>", prenom, "</b>"
print "</html></body>\n"

File: chapn_tools.tex, line 1423


SELECT codepays
FROM PAYS 
WHERE pays = 'France'

File: chapn_tools.tex, line 1431


SELECT num,nom,prenom
FROM ELEVE
WHERE codepays IN ( 
                    SELECT codepays
                    FROM PAYS 
                    WHERE pays = 'France'
                  )

File: chapn_tools.tex, line 1476


SELECT nom,prenom,AVG(note) FROM ELEVE,NOTE
WHERE num = nume and 
      numm IN ( SELECT num FROM MATIERES WHERE matiere = 'français' ) 
GROUP BY nume

File: chapn_tools.tex, line 1490


CREATE TABLE ELEVE (
     num integer primary key,
     nom varchar (30),
     prenom varchar (30),
     date date,
     adresse varchar (100),
     codepays integer,
     classe integer)

création d'une table avec \codesindex{sqlite3

import sqlite3 as SQL
cx = SQL.connect("madatabase.db3")
cur = cx.cursor()

cur.execute ("""
CREATE TABLE ELEVE (
     num integer primary key,
     nom varchar (30),
     prenom varchar (30),
     date date,
     adresse varchar (100),
     codepays integer,
     classe integer)
""")

File: chapn_tools.tex, line 1509


cur.execute ("CREATE TABLE NOTE (nume integer, numm integer, note double)")
cur.execute ("CREATE TABLE MATIERES (num integer, matiere varchar (30))")
cur.execute ("CREATE TABLE PAYS (codepays integer, pays varchar (30))")

insertion de valeurs dans une table \codesindex{sqlite3

import sqlite3 as SQL
cx = SQL.connect("madatabase.db3")
cur = cx.cursor()

cur.execute ("""
CREATE TABLE ELEVE (
     num integer primary key,
     nom varchar (30),
     prenom varchar (30),
     date date,
     adresse varchar (100),
     codepays integer,
     classe integer)
""")

File: chapn_tools.tex, line 1520


import sqlite3 as SQL
cx = SQL.connect("madatabase.db3")
cur = cx.cursor()
cur.execute("select * from ELEVE")
for row in cur.fetchall(): print row

File: chapn_tools.tex, line 1529


(1, u'dupre', u'xavier', u'11/08/1975', u'---- paris', 33, 19)
(2, u'dupre', u'gilles', u'24/12/1946', u'---- charleville', 33, 56)

File: chapn_tools.tex, line 1537


cur.execute ("INSERT INTO PAYS (codepays, pays) VALUES (33, 'France')")
cur.execute ("INSERT INTO PAYS (codepays, pays) VALUES (44, 'Royaume-Uni')")
cur.execute ("INSERT INTO MATIERES (matiere, num) VALUES ('français', 1)")
cur.execute ("INSERT INTO MATIERES (matiere, num) VALUES ('mathématiques', 2)")
cx.commit ()

File: chapn_tools.tex, line 1547


note = [(1, 1, 12), (1, 1, 14), (1, 2, 16), (1, 2, 8), (1, 2, 12), \
        (2, 1, 8),  (2, 1, 9),  (2, 2, 11), (2, 2, 8), (2, 2, 12)]
for n in note :
    req = "INSERT INTO NOTE (nume,numm,note) VALUES " + str (n)
	  cur.execute (req)
cx.commit ()

File: chapn_tools.tex, line 1558


req = """
SELECT nom,prenom,AVG(note) FROM ELEVE,NOTE
WHERE num = nume and 
      numm IN ( SELECT num FROM MATIERES WHERE matiere = 'français' ) 
GROUP BY nume
"""
cur.execute (req)
for row in cur.fetchall(): print row

File: chapn_tools.tex, line 1570


(u'dupre', u'xavier', 13.0)
(u'dupre', u'gilles', 8.5)

File: chapn_tools.tex, line 1577


req = """
SELECT nom,prenom,AVG(note) FROM ELEVE,NOTE
WHERE num = nume and 
      numm IN ( SELECT num FROM MATIERES WHERE matiere = 'français' ) 
GROUP BY nume
HAVING AVG(note) >= 10
"""
cur.execute (req)
for row in cur.fetchall(): print row

File: chapn_tools.tex, line 1634


CREATE DATABASE datatest ;

connexion ODBC, création d'une table

import odbc
cx = odbc.odbc("mysqlperso")
cur = cx.cursor()

cur.execute ("""
CREATE TABLE ELEVE (
     num integer primary key,
     nom varchar (30),
     prenom varchar (30),
     date date,
     adresse varchar (100),
     codepays integer,
     classe integer)
""")

connexion ODBC, ajout de données

import odbc
cx = odbc.odbc("mysqlperso")
cur = cx.cursor()

cur.execute ("""INSERT INTO ELEVE (num, nom, prenom, date, adresse, codepays, classe)
                VALUES (1, 'dupre', 'xavier', '1975-08-11', '---- paris', 33, 19) ;""")
cur.execute ("""INSERT INTO ELEVE (num, nom, prenom, date, adresse, codepays, classe)
                VALUES (2, 'dupre', 'gilles', '1946-12-24', '---- charleville', 33, 56) ;""")
cx.commit ()

File: chapn_tools.tex, line 1709


import odbc 
cx = odbc.odbc("mysqlperso")
cur = cx.cursor()
cur.execute ("SELECT * from ELEVE") 
for row in cur.fetchall () :
    print row

File: chapn_tools.tex, line 1721


print [ str (r) for r in row ]

File: chapn_tools.tex, line 1737


import odbc
cx = odbc.odbc("odbc_sql_server")

File: chapn_tools.tex, line 1744


dbi.operation-error: [Microsoft][ODBC SQL Server Driver][SQL Server]Login failed for user ''. 
The user is not associated with a trusted SQL Server connection. in LOGIN

File: chapn_tools.tex, line 1751


import odbc
cx = odbc.odbc("odbc_sql_server/login/password")

File: chapn_tools.tex, line 1757


cx = odbc.odbc("DSN=odbc_sql_server;UID=login;PWD=password")

File: chapn_tools.tex, line 1766


cd c:\Program Files\Apache Software Foundation\Apache2.2\bin
httpd -k stop
httpd

File: chapn_tools.tex, line 1840


import odbc 
cx = odbc.odbc("mysqlperso")

cur = cx.cursor()
cur.execute ("SELECT * from ELEVE") 
for row in cur.fetchall () :
    print row
cur.close ()


File: chapn_tools.tex, line 1855


import MySQLdb
cx  = MySQLdb.connect('localhost','root', \
        'admin', 'datatest')
cur = cx.cursor()
cur.execute ("select * from ELEVE" )
for row in cur.fetchall() :
    print row
cur.close()
cx.close() 

File: chapn_tools.tex, line 1874


import win32com.client
connexion = win32com.client.gencache.EnsureDispatch('ADODB.Connection')
connexion.Open("Provider='SQLOLEDB';Data Source='localhost';Initial Catalog='datatest';User ID='root';Password='admin';")
recordset = connexion.Execute('select * from client')[0]
while not recordset.EOF:
    for i in recordset.Fields : print i,
    print "<br>\n"
    recordset.MoveNext()
connexion.Close()      

extraction du texte d'un fichier \textit{pdf

from pdftools.pdffile import PDFDocument
from pdftools.pdftext import Text

def contents_to_text (contents):
    for item in contents:
        if isinstance (item, type ([])):
            for i in contents_to_text (item):
                yield i
        elif isinstance (item, Text):
            yield item.text

doc = PDFDocument ("declaration.pdf")
n_pages = doc.count_pages ()
text = []

for n_page in range (1, (n_pages+1)):
    print "Page", n_page
    page = doc.read_page (n_page)
    contents = page.read_contents ().contents
    text.extend (contents_to_text (contents))

print "".join (text)

f = open ("ok.txt", "w")
f.write ("".join (text))
f.close ()

graphiques avec GNUPlot

# coding: latin-1

import sys
import os

default_path     = r"C:\Program Files\gp423win32\gnuplot\bin\pgnuplot.exe"
default_temp_dir = "tempgnuplot"
imagenumber      = 0

def execute_script_gnuplot (scr) :
    global default_temp_dir
    global imagenumber
    global default_path

    if not os.path.exists (default_temp_dir) : os.mkdir (default_temp_dir)

    # avant
    scr          = "set term png\n" + scr
    image        = default_temp_dir + ("/image_%05d.png" % imagenumber)
    imagenumber += 1
    scr          = "set out \"" + image + "\"\n" + scr

    # après
    scr += "show out\n"
    scr += "exit\n"

    name = default_temp_dir + "/gnuscript.txt"
    f    = open (name, "w")
    f.write (scr)
    f.close ()

    line = default_path + " " + name
    os.system (line)

    return image

def build_script_gnuplot (series, seriesname, title = None, \
                     xlabel = None, ylabel = None, histo = False) :
    global default_temp_dir
    global default_path

    if not os.path.exists (default_temp_dir) : os.mkdir (default_temp_dir)
    scr = ""

    if xlabel != None : scr += "set xlabel \"" + xlabel + "\"\n"
    if ylabel != None : scr += "set ylabel \"" + ylabel + "\"\n"
    if title  != None : scr += "set title \"" + title + "\"\n"

    scr += "set grid\n"
    if histo : scr += "set style data histograms\n"
    else : scr += "set style data lines\n"
    scr += "plot "

    id = 0
    for s,lab in zip (series, seriesname) :
        name = default_temp_dir + "/series%d.txt" % (id)
        id  += 1
        f    = open (name, "w")
        for l in s :
            if histo : f.write ("%f\n" % (l [1]))
            else : f.write ("%f\t%f\n" % (l [0], l [1]))
        f.close ()
        scr += "\"" + name + "\" title \"" + lab + "\", "
    scr = scr [:len (scr)-2]
    scr += "\n"

    return execute_script_gnuplot (scr)


if __name__ == "__main__" :
    print "chemin pour gnuplot ", default_path

    series = [ [], [] ]
    for i in range (0, 100) :
        x = float (i) / 100
        y = x ** 0.5
        z = 1.0 - y
        series [0].append ( (x,y) )
        series [1].append ( (x,z) )

    image = build_script_gnuplot (series, ["serie 1", "serie 2"], \
                        xlabel="abscisses", ylabel="ordonnées", histo = False)
    print "image ", image
    image = build_script_gnuplot (series, ["serie 1", "serie 2"], \
                        xlabel="abscisses", ylabel="ordonnées", histo = True)
    print "image ", image

graphiques avec MatPlotLib

#coding:latin-1
def GraphOHLC (title, dates, ohlc, file, size = (800,400), t1 = 0, t2 = -1) :
    """dessine une série financière avec matplotlib
    - title est une titre
    - dates est une liste de date
    - ohlc est une liste de dictionnaire avec les clés 
                      ("Open", "High", "Low", "Close", "Volume")
    - file est un nom de fichier, le graphe y sera sauvegardé
    - size est la taille désirée pour le graphique
    - t1 est l'indice de la première date du graphique
    - t2 est l'indice de la dernière date du graphique
    """
    
    # on coupe la série si besoin
    if t2 == -1 : t2 = len (dates)
    dates = dates [t1:t2]
    ohlc = ohlc [t1:t2]
    
    import pylab
    
    # on crée les labels pour les abscisses
    # sans afficher toutes les dates car elles deviennent illisibles sinon
    # on en affiche que 10
    ind  = pylab.arange (len (dates))
    lab  = ["" for i in ind]
    for i in range (0,len (dates),len(dates)/10) : lab [i] = dates [i]

    # on crée la figure
    fig  = pylab.figure (figsize=(size [0]/100, size [1]/100))
    ax   = fig.add_subplot(111)
    
    # la première série à tracer est celle des volumes sous forme d'histogramme
    for i in range (0, len (ohlc)) :
        oh = ohlc [i]
        
        # l'histogramme est vert si c'est un jour de hausse
        # rouge si c'est un jour de baisse
        if i == 0 : co = (0.5,0.5,0.5)
        elif ohlc [i]["Close"] > ohlc [i-1]["Close"] : co = (0.0,1.0,0.0)
        else : co = (1.0,0.0,0.0)
        if len (dates) > 300 : 
            pylab.plot ( [i, i], [0, oh ["Volume"]], "k", color = co)
        elif len (dates) > 100 : 
            pylab.plot ( [i, i], [0, oh ["Volume"]], "k", \
                                         linewidth = 2.0, color = co)
        else : 
            pylab.plot ( [i, i], [0, oh ["Volume"]], "k", \
                                          linewidth = 4.0, color = co)
        
    # on écrit la légende du volume
    v = [0.0 for i in ind]
    pylab.plot (ind, v, "c.")
    pylab.ylabel ("volume")
        
    # on construit un second axe au graphique pour la série des prix
    ymin, ymax = pylab.ylim()
    pylab.ylim (ymin, ymax*3)
    pylab.xticks (ind, lab, fontsize = "small", rotation = 13  )
    ax2 = pylab.twinx()
    
    # puis un dessine les prix sur le graphique selon le même schéma, 
    # la même série de points
    # (i-0.5, Open) (i,Open) (i,Low) (i,High) (i,Close) (i+0.5,Close)
    for i in range (0, len (dates)) :
        oh = ohlc [i]
        co = (0.0,0.0,1.0)
        pylab.plot ([i-0.5, i], [oh["Open"],  oh["Open"]],  "k", \
                                      linewidth = 1.0, color = co)
        pylab.plot ([i, i],     [oh["Low"],   oh["High"]],  "k", \
                                      linewidth = 1.0, color = co)
        pylab.plot ([i, i+0.5], [oh["Close"], oh["Close"]], "k", \
                                      linewidth = 1.0, color = co)

    # on termine par le titres, la légende du second axe et celles des abscisses
    pylab.title   (title)
    pylab.ylabel  ("euros")
    pylab.xticks  (ind, lab, fontsize = "small", rotation = 13)
    pylab.xlabel  ("dates")
    # il ne reste plus qu'à sauver la figure
    pylab.savefig (file, orientation='paysage')

File: chapn_tools.tex, line 1957


Listen 81

File: chapn_tools.tex, line 1972


LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so

<Location /svn/>
    DAV svn
    SVNListParentPath on 
    SVNParentPath "c:/svnrepository/"
    SVNPathAuthz on
    #AuthzSVNAccessFile "C:/Program Files/Apache Software Foundation/Apache2.2/bin/apachesvnauth 
    AuthName "Subversion Repositories" 
    AuthType Basic
    AuthBasicProvider file
    AuthUserFile "C:/Program Files/Apache Software Foundation/Apache2.2/bin/apachesvnpasswd"
    require valid-user
</Location>

File: chapn_tools.tex, line 1992


cd C:\Program Files\Apache Software Foundation\Apache2.2\bin
htpasswd.exe -c apachesvnpasswd utilisateur

File: chapn_tools.tex, line 2012


ScriptAlias /mywiki "C:/Moin/mywiki/moin.cgi"    
Alias /moin_static163 "C:/Python25/share/moin/htdocs"

File: chapn_tools.tex, line 2019


<Directory "C:/Python25/share/moin/htdocs">
    Order deny,allow
    Allow from all
</Directory>
<Directory "C:/Moin/mywiki">
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Allow from all
</Directory>

File: chapn_tools.tex, line 2033


#!c:/python25/python.exe

File: chapn_tools.tex, line 2037


#!/usr/bin/python

File: chapn_tools.tex, line 2042


ScriptInterpreterSource registry
<Directory "C:/Python25">            # il faut également une section
    AllowOverride None               # comme celle-ci définie
    Options ExecCGI                  # pour le répertoire contenant
    Order allow,deny                 # le script CGI
    Allow from all                   #
</Directory>
AddType application/x-httpd-py .py
AddHandler cgi-script .py
Action application/x-httpd-py "C:/python25/python.exe"

File: chapn_tools.tex, line 2069


netstat -ao

File: chapn_tools.tex, line 2075


httpd -k uninstall -n ApacheSecond                  # on désinstalle le service s'il existait
httpd -f "new_conf.conf" -n ApacheSecond -k install # on installe à nouveau le service
httpd -n ApacheSecond -k start                      # on démarre Apache

File: chapn_tools.tex, line 2089


(OS 10048)Only one usage of each socket address (protocol/network address/port) is normally permitted.  : make_sock: could not bind to address 0.0.0.0:8084
no listening sockets available, shutting down
Unable to open logs

File: chapn_tools.tex, line 2106


<Directory "C:/Python25">
    AllowOverride None
    Options ExecCGI
    Order allow,deny
    Allow from all
</Directory>
<Directory "C:/_home/query-intent/projects/common_tools/cgi/">
    AllowOverride None
    Options FollowSymLinks ExecCGI
    Order allow,deny
    Allow from all
</Directory>

File: chapn_tools.tex, line 2123


<IfModule mime_module>
    TypesConfig conf/mime.types
    AddType application/x-httpd-py .py
    AddHandler cgi-script .py
</IfModule>
Action application/x-httpd-py "C:/python25/python.exe"

File: chapn_tools.tex, line 2134


ScriptAlias /py/ "C:/script_cgi_python/"

File: chapn_tools.tex, line 2140


header = """Content-type: text/html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>"""

footer = """</body></html>"""

print header
print "<b>Script CGI</b><br>\n"
print footer

File: chapn_tools.tex, line 2160


http://localhost:80/py/script.py

calcul d'une intégrale

# coding: cp1252
import math

n = 2000
a = -2.0
b = 3.0
h = (b-a)/n

sum = 0
for i in xrange (1,n):
    x = a + h * i
    sum += h * x * math.cos (x)

print "intégrale : ", sum

import scipy.integrate as integral            # on importe le module d'intégration
def fff(x): return x * math.cos (x)           # on définit la fonction à intégrer				
sum = integral.quad (fff, a,b, args=()) [0]   # on appelle la fonction d'intégration
print "intégrale avec scipy : ", sum          # on affiche le résultat

File: integrale.tex, line 47


import scipy.integrate as integral             # on importe le module d'intégration
def fff(x): return x * math.cos (x)            # on définit la fonction à intégrer				
sum = integral.quad (fff, a,b, args=()) [0]    # on appelle la fonction d'intégration
print "intégrale avec scipy : ", sum           # on affiche le résultat

File: integrale.tex, line 56


intégrale :  -1.96640795695
intégrale avec scipy :  -1.96908048953

File: tri.tex, line 13


x = [1,3,2,5,8,4,9,0,7,6] 
x.sort ()
print x

tri par sélection

# coding: cp1252
import random

def construit_suite(n):
    """construit une liste de n nombres entiers compris entre 0 et 99"""
    l = []
    for i in range(0,n):
        l.append (random.randint(0,100))
    return l

def tri_selection(l):
    """ tri une liste l, tri par sélection"""
    # première boucle, répétition des étapes A et B
    for i in range(0,len(l)):

        # recherche du maximum, on suppose pour commencer
        # qu'il est à la position 0
        pos = 0
        # boucle de l'étape A
        for j in range(1,len(l)-i):
            if l [pos] < l [j]: pos = j

        # échange de l'étape B
        # la position du maximum est conservé dans la variable pos
        # on fait l'échange avec l'élément à la position len(l)-i-1
        k       = len(l)-i-1
        ech     = l [k]
        l [k]   = l [pos]
        l [pos] = ech

l = construit_suite(8)          # création d'une suite aléatoirement
print "liste non triée :\t",l   # affichage
tri_selection (l)               # tri
print "liste triée     :\t",l   # affichage

tri fusion

# coding: cp1252
import random

def construit_suite(n):
    """construit une liste de n nombres entiers compris entre 0 et 99"""
    l = []
    for i in range(0,n):
        l.append (random.randint(0,100))
    return l

def fusion_liste (l1,l2):
    """fusionne deux listes l1 et l2 triées par ordre croissant
    de sorte que la liste résultante soit également triée"""
    i,j,k = 0,0,0
    fin   = len (l1) + len (l2)
    l = []
    while k < fin :
        if j >= len (l2) or (i < len (l1) and l1 [i] < l2 [j]) :
            l.append (l1 [i])
            k += 1
            i += 1
        else :
            l.append (l2 [j])
            k += 1
            j += 1
    return l

def tri_fusion(l):
    """ tri une liste l par fusion"""
    if len (l) <= 1 : return None # on élimine le cas simple
    n = 1
    while n < len (l) :
        for i in xrange (0, len (l), 2*n):
            a  = i
            m  = min (len (l), a + n)
            b  = min (len (l), a + 2 * n)
            if m < b:
                t        = fusion_liste (l [a:m], l [m:b])
                l [a:b] = t
        n *= 2
        
l = construit_suite(13)          # création d'une suite aléatoirement
print l [0:3]
print "liste non triée :\t",l    # affichage
tri_fusion (l)                   # tri
print "liste triée     :\t",l    # affichage

tri par insertion

# coding: cp1252
import random

def construit_suite(n):
    """construit une liste de n nombres entiers compris entre 0 et 99"""
    l = []
    for i in range(0,n):
        l.append (random.randint(0,100))
    return l

def recherche_dichotomique (l,x):
    """cherche l'élément x dans la liste l, la liste l est
    supposée être triée par ordre croissant"""
    a = 0
    b = len(l)-1
    while a <= b :
        m = (a+b) // 2
        r = cmp (x, l[m])
        if r == 0 : return m
        elif r == -1 : b = m-1
        else : a = m + 1
    return a

def tri_insertion(l):
    """ tri une liste l par insertion dichotomique, on suppose que l est non vide"""
    lt = []
    for x in l :
        if len (lt) == 0 : 
            lt.append (x)
            continue
        m = recherche_dichotomique (lt, x)
        lt.insert (m, x)
    l [0:len (l)] = lt


l = construit_suite(13)         # création d'une suite aléatoirement
print l [0:3]
print "liste non triée :\t",l   # affichage
tri_insertion (l)               # tri
print "liste triée     :\t",l   # affichage

tri d'entiers

# coding: cp1252
import random

def construit_suite(n):
    """construit une liste de n nombres entiers compris entre 0 et 99"""
    l = []
    for i in range(0,n):
        l.append (random.randint(0,10))
    return l

def tri_entiers(l):
    """ tri une liste l, les éléments à trier sont entiers"""
    # première boucle, minimum, maximum
    m = l [0]
    M = l [0]
    for k in range(1,len(l)):
        if l [k] < m : m = l [k]
        if l [k] > M : M = l [k]
    
    # calcul du nombre d'occurrences
    p = [0 for i in range (m,M+1) ]
    for i in range (0, len (l)) :
        p [ l [i] - m ] += 1
        
    # fonction de répartition
    P = [0 for i in range (m,M+1) ]
    P [0] = p [0]
    for k in range (1, len (p)) :
        P [k] = P [k-1] + p [k]
        
    # tri
    pos = 0
    for i in range (1, len (l)) :
        while P [pos] < i : pos += 1
        l [i-1] = pos + m
    l [len (l)-1] = M


l = construit_suite(8)          # création d'une suite aléatoirement
print "liste non triée :\t",l   # affichage
tri_entiers (l)                 # tri
print "liste triée     :\t",l   # affichage

File: chap2_precis.tex, line 26


MsgBox "première partie" & _
       "seconde partie\n" & _
       "troisième partie"

File: chap2_precis.tex, line 64


Dim a As Integer
Dim s As String
Dim v As Variant

File: chap2_precis.tex, line 81


' mois est un tableau de chaînes de caractères
' dont les indices vont de 0 à 12 inclus
Dim Mois(12) As String

' Matrice est un tableau à deux dimensions d'entiers
Dim Matrice(3, 4) As Integer

' Matrice2 est un tableau de réels à deux dimensions pour lesquels
' les indices désirés sont explicitement spécifiés
Dim Matrice2(1 To 5,  4 To 9,  3 To 5) As Double

' accès à un paramètre
Dim t(3 To 6) As Integer
t(3) = 4

File: chap2_precis.tex, line 105


3 + 4         ' vaut 7
31 Mod 5      ' vaut 1
2^4           ' vaut 16
"un" & "deux" ' vaut undeux

File: chap2_precis.tex, line 115


((3 < 4) And (5 < 6)) Or (2 > 1)

File: chap2_precis.tex, line 123


s = "première ligne" & vbCrLf & "seconde ligne"

File: chap2_precis.tex, line 140


Dim s As String
Dim a As Double
s = Str (3.14)
a = Val ("3.14")

File: chap2_precis.tex, line 155


Type Contacts
    Nom As String
    Prenom As String
    Age As Integer
End Type

Sub procedure ()
    Dim ct As Contacts
    ct.Nom = "Microsoft"
    ct.Prenom = "VBA"
    ct.Age = 10     ' environ
End Sub

File: chap2_precis.tex, line 174


Type Contacts
    Nom As String
    Prenom As String
    Age As Integer
End Type

Sub essai()
    Dim ct As Contacts
    With ct
        .Nom = "Microsoft"
        .Prenom = "VBA"
        .Age = 10
    End With
End Sub

File: chap2_precis.tex, line 212


Public nom As String

Sub essai()
    nom = "inconnu"
End Sub

File: chap2_precis.tex, line 222


Dim c As New ClassNom
c.nom = "eeee"
c.essai

File: chap2_precis.tex, line 231


Private Sub Class_initialize()
    ' code du constructeur
End Sub

Private Sub Class_Terminate()
    ' code du destructeur
End Sub

File: chap2_precis.tex, line 246


MsgBox "message"

File: chap2_precis.tex, line 260


Reponse = MsgBox ("Voulez-vous continuer ?", vbYesNo)

File: chap2_precis.tex, line 269


Dim Message As String
Message = InputBox("intitulé de la question", "nom de la boîte de dialogue", _
                                  "réponse par défaut")

File: chap2_precis.tex, line 286


If condition Then
    ' faire..
End If

File: chap2_precis.tex, line 294


If condition Then   ' faire

File: chap2_precis.tex, line 300


If condition Then
    ' faire..
Else
    ' sinon faire...
End If

File: chap2_precis.tex, line 310


If condition1 Then
    ' faire..
ElseIf condition2 Then
    ' faire...
Else
    ' sinon faire...
End If

File: chap2_precis.tex, line 325


Dim NiveauEau As Integer
Dim Mention As String
NiveauEau = 10
Select Case NiveauEau
    Case 0
        Mention = "sec"
    Case 1 To 5
        Mention = "presque sec"
    Case 6 To 10
        Mention = "normal"
    Case 11 To 15
        Mention = "trop d'eau"
    Case 16 To 19
        Mention = "inondations"
    Case Else
        Mention = "on déménage"
End Select

File: chap2_precis.tex, line 350


Dim s as Integer
Dim i as Integer ' déclarer la variable de la boucle
s = 0
For i = 1 To 10
    s = s + 1
Next i           ' passer au i suivant

File: chap2_precis.tex, line 361


Dim s as Integer
Dim i as Integer ' déclarer la variable de la boucle
s = 0
For i = 1 To 10 Step 2  ' i = 1 3 5 ... 9
    s = s + 1
Next i           ' passer au i suivant

File: chap2_precis.tex, line 375


Dim s as Integer
Dim i as Integer ' déclarer la variable de la boucle
s = 0
i = 1
While i <= 10 
    s = s + 1
    i = i + 1
Wend

File: chap2_precis.tex, line 391


Dim s as Integer
Dim i as Integer ' déclarer la variable de la boucle
s = 0
i = 1
Do While i <= 10 
    s = s + 1
    i = i + 1
Loop

File: chap2_precis.tex, line 406


Dim s as Integer
Dim i as Integer ' déclarer la variable de la boucle
s = 0
i = 1
Do 
    s = s + 1
    i = i + 1
Loop While i <= 10 

File: chap2_precis.tex, line 427


Sub exemple_procedure ()
   ' code de la procédure
End Sub

File: chap2_precis.tex, line 435


Sub exemple_procedure (ByVal param1 As Long)
   ' code de la procédure
End Sub
Sub main ()
    ' appel de la procédure
    exemple_procedure 3
End Sub

File: chap2_precis.tex, line 449


Function exemple_fonction () As Integer
   ' code de la procédure
   ...
   ' retourner le résultat
   exemple_fonction =
End Function

File: chap2_precis.tex, line 467


Sub proc ()
   Static i As Integer
End Sub

File: chap2_precis.tex, line 486


Function exemple_fonction (ByVal s As String, ByRef v As Variant) As Long
    ' ...
End Function

File: chap2_precis.tex, line 505


Dim nom_tres_tres_long As String
Dim s As String
Set s = nom_tres_tres_long
' par la suite, s et nom_tres_tres_long désignent la même variable

File: chap2_precis.tex, line 547


Sub proc ()
	On Error Goto erreur
	  '
	  ' code susceptible de produire une erreur
	  '
	Exit Sub
erreur:
	'
	' en cas d'erreur
	'	
End Sub

File: chap2_precis.tex, line 572


Dim intFile As Integer
Dim filename as String
Dim s as String
intFile = 1                            ' ou intFile = FreeFile
filename = "c:\file.txt"               ' nom du fichier
s = "contenu du fichier"               ' chaîne à enregistrer dans le fichier
Open filename For OutPut As intFile    ' ouverture du fichier
Print intFile, s                       ' écriture dans le fichier
Close intFile                          ' fermeture du fichier

File: chap2_precis.tex, line 592


Dim sLine as String
Dim intFile As Integer
intFile = 1                             ' ou intFile = FreeFile
Open sNomeFile For Input As intFile     ' ouverture en mode lecture

Do While Not EOF(1)                     ' tant qu'on n'a pas atteint la fin du fichier
    Line Input intFile, sLine           ' on lit une ligne et on place le contenu dans sLine
Loop
Close intFile                           ' on ferme le fichier

File: td_black_scholes.tex, line 88


MsgBox "boîte à message"

File: td_black_scholes.tex, line 96


Dim r As Double

File: td_black_scholes.tex, line 101


r = Worksheets("Sheet1").Cells(4, 1).Value

File: td_black_scholes.tex, line 121


Function Simulation(ByVal r As Double, ByVal sigma As Double, ByVal x0 As Double, _
            ByVal dt As Double, ByVal T As Long) As Variant
            
    '  code de la fonction            
   
    ' Lorsqu'on connaît le résultat de la fonction, on écrit
    Simulation = résultat
   
End Function

File: td_black_scholes.tex, line 136


Dim n as Long
n = T / dt + 1

File: td_black_scholes.tex, line 143


Dim res() As Double
ReDim res(n)
res (0) = x0

File: td_black_scholes.tex, line 150


Dim w As Double
w = Rnd     ' nombre aléatoire de loi uniforme [0,1]
w = Application.WorksheetFunction.NormSInv(w) * dt ^ 0.5

File: td_black_scholes.tex, line 159


For i = 1 To nb
   res (i) = res(i-1) * ... à compléter
Next i

File: td_black_scholes.tex, line 166


Simulation = res

File: td_black_scholes.tex, line 175


Dim solution As Variant
solution = Simulation(r, sigma, x0, dt, T)

File: td_black_scholes.tex, line 181


Dim nb as Long
nb = UBound (solution)

File: td_black_scholes.tex, line 187


For i = 0 To nb
    Worksheets("Sheet1").Cells(7 + i, 1) = ... ' temps t
    Worksheets("Sheet1").Cells(7 + i, 2) = ... ' Y_t
Next i

File: td_black_scholes.tex, line 225


Dim plage As Range
Set plage = Worksheets("Sheet1").Range(_
                   Worksheets("Sheet1").Cells(7, 1), _
                   Worksheets("Sheet1").Cells(8, 2) _
               )

File: td_black_scholes.tex, line 236


Dim graphe_in As ChartObject
Dim graphe As Chart
Set graphe_in = Worksheets("Sheet1").ChartObjects.Add(100, 30, 400, 250)
Set graphe = graphe_in.Chart

File: td_black_scholes.tex, line 244


graphe.ChartType = xlXYScatterLines

File: td_black_scholes.tex, line 249


graphe.SetSourceData plage, xlColumns

File: td_black_scholes.tex, line 254


graphe.HasTitle = True
graphe.ChartTitle.Text = "Black Scholes"

File: td_black_scholes.tex, line 260


graphe.Axes(xlValue, xlPrimary).HasTitle = True
graphe.Axes(xlValue, xlPrimary).AxisTitle.Text = "Xt"

graphe.Axes(xlCategory, xlPrimary).HasTitle = True
graphe.Axes(xlCategory, xlPrimary).AxisTitle.Text = "temps (jour)"

File: td_black_scholes.tex, line 269


graphe.SeriesCollection(1).Name = "Courbe1"
graphe.SeriesCollection(1).Border.Color = RGB(0, 0, 255)
graphe.SeriesCollection(1).MarkerStyle = xlMarkerStyleNone

File: td_black_scholes.tex, line 277


Dim serie
Set serie = graphe.SeriesCollection.NewSeries
serie.XValues = Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(7, 1), _
                    Worksheets("Sheet1").Cells(7 + nb, 1))
serie.Values = Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(7, 1 + i), _
                    Worksheets("Sheet1").Cells(7 + nb, 1 + i))
serie.Name = "nouvelle série"

File: td_black_scholes_cor.tex, line 11



' il est préférable de mettre cette ligne en haut du fichier
' afin de préciser à VBA qu'il ne doit rien faire de manière
' implicite comme utiliser une variable non déclarée
Option Explicit


'
' cette fonction prend 5 paramètres qui permettent de simuler
' l'équation stochastique de Black Scholes
'
' elle retourne un tableau de réels
'
'
Function Simulation(ByVal r As Double, ByVal sigma As Double, ByVal x0 As Double, _
            ByVal dt As Double, ByVal T As Long) As Variant


    Dim res() As Double
    Dim X As Double
    Dim i As Long
    Dim w As Double
    Dim nb As Long
    
    nb = T / dt + 1
    
    ReDim res(nb)
    X = x0
    res(0) = X
    
    For i = 1 To nb
        w = Rnd
        w = Application.WorksheetFunction.NormSInv(w) * dt
        X = X * (1 + r * dt + sigma * w)
        res(i) = X
    Next i
    
    Simulation = res
    
End Function



'
' définition de la macro Simulation_macro
'
Sub Simulation_macro()

    Dim r As Double
    Dim sigma As Double
    Dim x0 As Double
    Dim dt As Double
    Dim T As Double
    
    ' on récupère les informations depuis la feuille Excel
    r = Worksheets("Sheet1").Cells(4, 1).Value
    sigma = Worksheets("Sheet1").Cells(4, 2).Value
    x0 = Worksheets("Sheet1").Cells(4, 3).Value
    dt = Worksheets("Sheet1").Cells(4, 4).Value
    T = Worksheets("Sheet1").Cells(4, 5).Value
    
    ' on appelle la fonction simulation 5 fois
    Dim i As Long
    Dim marche(5) As Variant
    For i = 1 To 5
        marche(i) = Simulation(r, sigma, x0, dt, T)
    Next i
    
    ' on trace la courbe avec r = 0
    Dim non_stochastique As Variant
    non_stochastique = Simulation(r, 0, x0, dt, T)
    
    ' on récupère le nombre de points dans une solution
    Dim nb As Long
    nb = UBound(non_stochastique)
    
    
    ' on recopie les valeurs de temps et le résultats de la fonction Simulation
    Dim k As Long
    For i = 0 To nb
        Worksheets("Sheet1").Cells(7 + i, 1) = dt * i
        For k = 1 To 5
            Worksheets("Sheet1").Cells(7 + i, 1 + k) = marche(k)(i)
        Next k
    Next i
    
    ' on recopie la solution non stochastique
    k = 6
    For i = 0 To nb
        Worksheets("Sheet1").Cells(7 + i, 1 + k) = non_stochastique(i)
    Next i
    
    
    ' on met une légende
    Worksheets("Sheet1").Cells(6, 1) = "temps"
    Worksheets("Sheet1").Cells(6, 7) = "non stochastique"
    For k = 1 To 5
        Worksheets("Sheet1").Cells(6, 1 + k) = "Simulation " & k
    Next k
    
    
    '
    ' deuxième partie
    ' on crée le graphique s'il n'existe pas
    '
    
    Dim nb_graphe As Long
    
    ' on compte le nombre de graphes de la feuille Sheet1
    nb_graphe = Worksheets("Sheet1").ChartObjects.Count
    
    If nb_graphe = 0 Then
        ' s'il n'y a pas alors...
    
        Dim plage As Range
        
        ' on récupère les données liées à la feuille (2 colonnes)
        Set plage = Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(7, 1), _
                           Worksheets("Sheet1").Cells(7 + nb, 2))
        
        ' on crée un graphe
        Dim graphe_in As ChartObject
        Dim graphe As Chart
        Set graphe_in = Worksheets("Sheet1").ChartObjects.Add(100, 30, 400, 250)
        Set graphe = graphe_in.Chart
        
        ' on spécifie son type
        graphe.ChartType = xlXYScatterLines
        
        ' on lui dit quelles sont les données à dessiner,
        ' le second paramètres précise qu'elles sont organisées en colonnes
        graphe.SetSourceData plage, xlColumns
        
        ' on lui met un titre
        graphe.HasTitle = True
        graphe.ChartTitle.Text = "Black Scholes"
        
        ' on met un titre sur l'axe des Y
        graphe.Axes(xlValue, xlPrimary).HasTitle = True
        graphe.Axes(xlValue, xlPrimary).AxisTitle.Text = "Xt"
        
        ' on met un titre sur l'axe des X
        graphe.Axes(xlCategory, xlPrimary).HasTitle = True
        graphe.Axes(xlCategory, xlPrimary).AxisTitle.Text = "temps (jour)"
        
        ' on modifie le nom de la première série
        graphe.SeriesCollection(1).Name = "Courbe1"
        graphe.SeriesCollection(1).Border.Color = RGB(0, 0, 255)
        graphe.SeriesCollection(1).MarkerStyle = xlMarkerStyleNone
        
        ' on ajoute les séries suivantes
        Dim serie As Series
        For i = 2 To 5
            Set serie = graphe.SeriesCollection.NewSeries
            serie.XValues = Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(7, 1), _
                           Worksheets("Sheet1").Cells(7 + nb, 1))
            serie.Values = Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(7, 1 + i), _
                           Worksheets("Sheet1").Cells(7 + nb, 1 + i))
            serie.Name = "Courbe" & i
            serie.Border.Color = RGB(0, 0, 255)
            serie.MarkerStyle = xlMarkerStyleNone
        Next i
        
        ' on ajoute la solution non stochastique
        i = 6
        Set serie = graphe.SeriesCollection.NewSeries
        serie.XValues = Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(7, 1), _
                            Worksheets("Sheet1").Cells(7 + nb, 1))
        serie.Values = Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(7, 1 + i), _
                            Worksheets("Sheet1").Cells(7 + nb, 1 + i))
        serie.Name = "non stochastique" & i
        serie.Border.Color = RGB(255, 0, 0)
        serie.MarkerStyle = xlMarkerStyleNone
        serie.Border.Weight = xlMedium
    
    End If
    
End Sub


File: td_maths_couple.tex, line 53


' on crée un document Word
Dim word As Object
Set word = CreateObject("Word.Application")
word.Documents.Add

' on met en forme
word.Selection.Font.Size = 16
word.Selection.Font.Bold = True
  
' écriture d'un petit texte dans ce nouveau document et on va deux fois à la ligne
word.Selection.TypeText "Organisation de la classe vendredi prochain" _
            & vbCrLf & vbCrLf

' vbCrLf insère un paragraphe dans le document Word
' le symbole & permet de concaténer plusieurs chaînes de caractères

' on ajoute le tableau dans le document word
word.Selection.Paste

' on change la mise en forme
word.Selection.Font.Size = 12
word.Selection.Font.Bold = False

' on écrit un petit message de fin
word.Selection.TypeText vbCrLf & vbCrLf & "Bon courage et à vendredi" _
   & vbCrLf & vbCrLf & "Votre professeur de mathématiques"

File: td_maths_couple.tex, line 85


' on imprime le document dans un fichier posscript
' l'imprimante doit être installée sur votre ordinateur
word.ActivePrinter = "HP LaserJet 5P/5MP PostScript"
word.PrintOut Filename:="c:\vendredi.doc", PrintToFile:=True, _
           OutputFileName:="c:\vendredi.ps"

' Fermeture de ce document :
word.ActiveDocument.Close
Set word = Nothing

File: td_maths_couple.tex, line 101


Shell ("C:\texmf\miktex\bin\epstopdf.exe c:\vendredi.ps")

File: td_maths_couple.tex, line 107


Dim s As String
s = Chr(34)
Shell (s & "C:\Program Files\Ghostgum\gs8.60\bin\gswin32c" & s & _
    " -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=" & _
    "c:\vendredi.pdf d:\vendredi.ps")

File: td_maths_couple.tex, line 120


Dim look As Object
Set look = CreateObject("Outlook.Application")
Dim email As Object
Set email = look.CreateItem(olMailItem)
email.to = ...
email.Body = "organisation de la séance de vendredi, voir pièce jointe"
email.Subject = "cours de maths"
email.Attachments.Add "c:\vendredi.pdf"
email.Send

File: td_maths_couple.tex, line 138


Sub procedure_protege_contre_les_erreurs ()

    On Error Goto Marqueur1 
    
       ' s'il se produit une erreur dans ces lignes,
       ' le programme va directement à la ligne qui
       ' comment par Marqueur1

    On Error Goto Marqueur2
    
       ' s'il se produit une erreur dans ces lignes,
       ' le programme va directement à la ligne qui
       ' comment par Marqueur2
       
       ' la procédure s'arrête ici
       Exit Sub

Marqueur1 :

    ' on affiche un message d'erreur
    MsgBox "Une erreur s'est produite dans la première partie."
    Exit Sub
   
Marqueur2 :

    ' on affiche un message d'erreur
    MsgBox "Une erreur s'est produite dans la seconde partie."
    Exit Sub
   
End Sub

File: td_maths_couple_cor.tex, line 12


'
'  convertit un fichier file1.ps en un fichier file2.pdf
'
Function conversionPDF(ByVal file1 As String, ByVal file2 As String) As String
    
    ' les guillemets
    Dim s As String
    s = Chr(34)
    
    ' version Ghostcript 8.53
    On Error GoTo solution2:
    Shell (s & "C:\Program Files\Ghostgum\gs8.53\bin\gswin32c" & s & _
               " -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=" & _
               file2 & " " & file1)
    conversionPDF = file2
    Exit Function
    
solution2:

    ' version Ghostcript 8.60
    On Error GoTo solution3:
    Shell (s & "C:\Program Files\gs\gs8.60\bin\gswin32c.exe" & s & _
               " -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=" & _
               file2 & " " & file1)
    conversionPDF = file2
    Exit Function
    
solution3:
    
    ' version Miktex, il faut que Miktex soit installé
    ' http://miktex.org/
    MsgBox "miktex"
    On Error GoTo pasdesolution
    Shell (s & "C:\texmf\miktex\bin\epstopdf.exe" & s & " " & file1)
    conversionPDF = file2
    Exit Function
    
pasdesolution:
    conversionPDF = ""
    
End Function

'
' macro
'
Sub SeanceVendredi()

    ' recopie des données pour les trier ailleurs
    Range("A2:B13").Select
    Selection.Copy
    Range("E2").Select
    ActiveSheet.Paste
    
    ' on sélectionne la zone à trier et on trie
    Range("E2:F13").Select
    Selection.Sort Key1:=Range("F2"), Order1:=xlAscending, Header:=xlNo, _
                        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
                        
    ' on forme les couples
    ' le plus fort avec le moins fort
    Dim i As Long  ' position du premier
    Dim j As Long  ' position du dernier
    Dim k As Long  ' position du couple
    Dim m1 As String
    Dim m2 As String
    
    i = 2
    j = 13
    k = 15
    
    While i < j
        Cells(k, 2) = Cells(i, 5)
        Cells(k, 3) = Cells(j, 5)
        
        ' on fait aussi la somme des notes du groupe
        Cells(k, 4) = Cells(i, 6).Value + Cells(j, 6).Value
        
        k = k + 1
        i = i + 1
        j = j - 1
    Wend
    
    '
    ' on crée un document Word à envoyer aux élèves
    '
    
    ' on copie la sélection
    Range("B15:D20").Select
    Selection.Copy
    
    ' on crée un document Word
    Dim word As Object
    Set word = CreateObject("Word.Application")
    word.Documents.Add
    
    ' on met en forme
    word.Selection.Font.Size = 16
    word.Selection.Font.Bold = True
  
    ' écriture d'un petit texte dans ce nouveau document et on va deux fois à la ligne
    word.Selection.TypeText "Organisation de la classe vendredi prochain" & vbCrLf & vbCrLf
    
    ' on ajoute le tableau dans le document word
    word.Selection.Paste
    
    ' on change la mise en forme
    word.Selection.Font.Size = 12
    word.Selection.Font.Bold = False
    
    ' on écrit un petit message de fin
    word.Selection.TypeText vbCrLf & vbCrLf & "Bon courage et à vendredi" & vbCrLf & vbCrLf & _
                                              "Votre professeur de mathématiques"
    
    ' sauvegarde de ce document ainsi créé :
    word.ActiveDocument.SaveAs "c:\temp\vendredi.doc"
    
    ' pour voir le résultat et éviter que Word ne se ferme tout de suite
    ' word.Visible = True
    ' MsgBox "Cliquer pour continuer"
    ' word.Visible = False
    
    ' si l'impression se passe mal, on va à PasImprimante
    On Error GoTo PasImprimante
    
    ' on imprime le document dans un fichier posscript
    ' l'imprimante doit être installée sur votre ordinateur
    word.ActivePrinter = "HP LaserJet 5P/5MP PostScript"
    word.PrintOut Filename:="c:\temp\vendredi.doc", PrintToFile:=True, _
                  OutputFileName:="c:\temp\vendredi.ps"
    
    ' Fermeture de ce document :
    word.ActiveDocument.Close
    Set word = Nothing
    
    ' conversion de ps vers pdf
    Dim ist As String
    ist = conversionPDF("c:\temp\vendredi.ps", "c:\temp\vendredi.pdf")
    If ist = "" Then GoTo PasPDF
    
    
    ' envoi d'un mail
    ' voici la version sans document attaché mais elle marche sans outlook
    'ActiveWorkbook.FollowHyperlink _
            Address:="mailto:xavier.dupre@wanadoo.fr?subject=cours de maths&body=groupes pour vendredi", _
            NewWindow:=True
            
    ' on récupère les adresses dans une chaîne de caractères
    Dim tous As String
    For i = 2 To 13
        tous = tous & Cells(i, 3)
        If i < 13 Then tous = tous & ";"
    Next i
    
    On Error GoTo PasOutlook
                                
    ' envoi d'un mail avec Outlook
    Dim look As Object
    Set look = CreateObject("Outlook.Application")
    Dim email As Object
    Set email = look.CreateItem(olMailItem)
    email.to = tous
    email.Body = "organisation de la séance de vendredi, voir pièce jointe"
    email.Subject = "cours de maths"
    email.Attachments.Add "c:\temp\vendredi.pdf"
    email.Send
    
    Set email = Nothing
    
    Exit Sub
    
PasPDF:
    MsgBox "Il est impossible de convertir le fichier ps en PDF."
    Exit Sub
    
PasImprimante:
    ' Fermeture de ce document :
    word.ActiveDocument.Close
    Set word = Nothing
    MsgBox "Il est impossible d'imprimer."
    Exit Sub
    
PasOutlook:
    MsgBox "Outlook n'est pas disponible ou la conversion en PDF s'est mal passée."
    Exit Sub
    
End Sub

File: td_presentation_cor.tex, line 11


'
' crée deux graphes correspondant à une année
'
Sub GrapheAnnee(ByVal annee As Long)
    
    ' on cherche la ligne correspond à l'année
    Dim ligne As Long
    ligne = 9
    While Worksheets("table").Cells(ligne, 1) <> annee And ligne < 3000
        ligne = ligne + 1
    Wend
    
    If ligne = 3000 Then
        MsgBox "L'année " & annee & " est introuvable."
        Exit Sub
    End If
    
    ' on insère deux feuilles de calcul pour y mettre les graphes
    Dim feuille As Object
    Dim feuille_pie As Object
    
    On Error GoTo existe_pas
    
    Set feuille = Worksheets("graphes")
    Set feuille_pie = Worksheets("graphes_pie")
    GoTo suite
    
existe_pas:

    Set feuille = Sheets.Add
    feuille.Name = "graphes"
    Set feuille_pie = Sheets.Add
    feuille_pie.Name = "graphes_pie"
    
suite:

    ' '''''''''''''''''''''''''''''''''''''''''''''
    ' on crée un premier graphe
    ' '''''''''''''''''''''''''''''''''''''''''''''
    
    ' on récupère les données liées à la feuille (2 colonnes)
    Dim plage As Range
    Set plage = Worksheets("table").Range(Worksheets("table").Cells(ligne, 2), _
                       Worksheets("table").Cells(ligne, 4))
        
    ' création du premier graphe
    Dim graphe_in As ChartObject
    Dim graphe As Chart
    Set graphe_in = Worksheets("graphes").ChartObjects.Add(10 + (ligne - 8) * 20, 10 + (ligne - 8) * 20, 400, 300)
    Set graphe = graphe_in.Chart
    
    ' on spécifie son type
    graphe.ChartType = xlColumnClustered
    
    ' on lui dit quelles sont les données à dessiner,
    ' le second paramètres précise qu'elles sont organisées en colonnes
    graphe.SetSourceData plage, xlLines
    
    ' on lui met un titre
    graphe.HasTitle = True
    graphe.ChartTitle.Text = "Employees Year " & annee
    
    ' on assigne au graphe la légende des x
    graphe.SeriesCollection(1).XValues = "=(table!R7C2,table!R7C3,table!R7C4)"
    graphe.SeriesCollection(1).Name = Worksheets("table").Cells(ligne, 1)
    graphe.SeriesCollection(1).Border.ColorIndex = 3
    graphe.SeriesCollection(1).Interior.ColorIndex = 3
    
    ' on spécifie pas de légende
    graphe.HasLegend = False
    
    ' on indique le maximum sur les ordonnées
    graphe.Axes(xlValue).MaximumScale = 3500
    
    ' '''''''''''''''''''''''''''''''''''''''''''''
    ' on crée un second graphe
    ' '''''''''''''''''''''''''''''''''''''''''''''
    
    ' on récupère les données
    Dim plage2 As Object
    Set plage2 = Worksheets("table").Range(Worksheets("table").Cells(ligne, 5), _
                       Worksheets("table").Cells(ligne, 13))
    
    
    ' on crée le second graphe
    Dim graphe_in_pie As ChartObject
    Dim graphe_pie As Chart
    Set graphe_in_pie = Worksheets("graphes_pie").ChartObjects.Add(10 + (ligne - 8) * 20, 10 + (ligne - 8) * 20, 400, 300)
    Set graphe_pie = graphe_in_pie.Chart
    
    ' on spécifie son type
    graphe_pie.ChartType = xlPie
    
    ' on lui dit quelles sont les données à dessiner,
    ' le second paramètres précise qu'elles sont organisées en colonnes
    graphe_pie.SetSourceData Source:=plage2, PlotBy:=xlRows
    
    ' on lui met un titre
    graphe_pie.HasTitle = True
    graphe_pie.ChartTitle.Text = "Civilian Agencies " & annee
    
    ' on spécifie pas de légende
    graphe_pie.HasLegend = False
    
    ' on lui donne des étiquettes
    graphe_pie.SeriesCollection(1).XValues = "=table!R8C5:R8C13"
    
    ' on lui dit comment afficher les étiquettes
    graphe_pie.SeriesCollection(1).ApplyDataLabels Type:=xlDataLabelsShowLabel, _
        AutoText:=True, LegendKey:=True, HasLeaderLines:=True
    
    ' on change la couleur du fond
    graphe_pie.ChartArea.Interior.ColorIndex = 2
    graphe_pie.PlotArea.Interior.ColorIndex = 2
    
    ' on change quelques détails sur la position du graphe...
    graphe_pie.PlotArea.Left = 87
    graphe_pie.PlotArea.Top = 55
    graphe_pie.PlotArea.Width = 161
    graphe_pie.PlotArea.Height = 160
    graphe_pie.PlotArea.Width = 209
    graphe_pie.PlotArea.Height = 210
    graphe_pie.PlotArea.Border.LineStyle = xlNone
    
    ' on change la taille de la police
    With graphe_pie.SeriesCollection(1).DataLabels.Font
        .Name = "Arial"
        .FontStyle = "Normal"
        .Size = 9
    End With
    
    ' pas de bordure autour du graphe
    graphe_pie.ChartArea.Border.LineStyle = xlNone
    
End Sub

File: td_presentation_cor.tex, line 151


'
' seconde partie : création de la présentation
'
Sub GrapheAnneeMacro_SecondePartie()

    ' on crée un document PowerPoint
    Dim power As Object
    Set power = CreateObject("PowerPoint.Application")
    
    ' création d'une présentation
    Dim pres As Object
    Set pres = power.Presentations.Add(WithWindow:=msoTrue)

    ' on crée autant de pages qu'il y a de graphiques
    Dim page As Object
    
    ' pour voir le résultat et éviter que Word ne se ferme tout de suite
    power.Visible = True
    
    Dim nb As Long
    Dim t As Object
    Dim g1 As Object
    Dim g2 As Object
    
    For nb = 1 To Worksheets("graphes").ChartObjects.Count
    
        ' on récupère les graphes
        Set g1 = Worksheets("graphes").ChartObjects(nb)
        Set g2 = Worksheets("graphes_pie").ChartObjects(nb)
        
        ' on ajoute un slide vide
        Set slide = pres.Slides.Add(Index:=nb, Layout:=12)
        power.ActiveWindow.ViewType = 1
        
        ' on copie le graphique comme une image
        g1.CopyPicture
        
        ' on l'ajoute au slide
        slide.Shapes.Paste
        
        ' on sélectionne l'image pour changer sa taille
        ' magouille PowerPoint
        power.ActiveWindow.Selection.Unselect
        power.ActiveWindow.View.GotoSlide Index:=nb
        power.ActiveWindow.Selection.Unselect
        power.ActiveWindow.Selection.SlideRange.Shapes(1).Select
        
        ' on modifie sa taille
        With power.ActiveWindow.Selection.ShapeRange
            .Height = 538.38
            .Width = 716.38
            .Left = 0#
            .Top = 0#
        End With
        
        ' on récupère le graphe pie
        ' on copie le graphique comme une image
        g2.CopyPicture
        
        ' on l'ajoute au slide
        slide.Shapes.Paste
        
        ' on sélectionne l'image pour changer sa taille
        ' magouille PowerPoint
        power.ActiveWindow.Selection.Unselect
        power.ActiveWindow.View.GotoSlide Index:=nb
        power.ActiveWindow.Selection.Unselect
        power.ActiveWindow.Selection.SlideRange.Shapes(2).Select
        
        ' on modifie sa taille
        With power.ActiveWindow.Selection.ShapeRange
            .Height = 250
            .Width = 350
            .Left = 350#
            .Top = 50#
        End With        
        
        Set slide = Nothing
        
    Next nb
    
    ' on règle les transitions entre transparents
    With power.ActivePresentation.Slides.Range.SlideShowTransition
        .EntryEffect = 2819
        .Speed = 3
        .AdvanceOnClick = msoTrue
        .AdvanceOnTime = msoTrue
        .AdvanceTime = 1
        .SoundEffect.Type = 0
    End With
    

End Sub

File: td_presentation_cor.tex, line 250


Private Sub annuler_Click()
    Unload graphes_dialog
End Sub

Private Sub ok_Click()
    
    ' on génère tous les graphes
    Dim i As Long
    Dim j As Long
    Dim a As Long
    
    i = Val(premier.Text)
    j = Val(dernier.Text)
    
    For a = i To j
        GrapheAnnee a
    Next a
    
    ' on créé la présentation
    GrapheAnneeMacro_SecondePartie
    
    ' on supprime la boîte de dialogue
    Unload graphes_dialog
End Sub

File: td_presentation_image.tex, line 21


Cells (4,3).Value = 3  ' on modifie le contenu de la ligne 4 colonne 3

File: td_presentation_image.tex, line 29


Dim power As Object
Set power = CreateObject("PowerPoint.Application")

File: td_presentation_image.tex, line 35


Dim pres As Object
Set pres = power.Presentations.Add(WithWindow:=msoTrue)

File: td_presentation_image.tex, line 41


power.Visible = True

File: td_presentation_image.tex, line 48


Set slide = pres.Slides.Add(Index:=nb, Layout:=12)
power.ActiveWindow.ViewType = 1

File: td_presentation_image.tex, line 54


power.ActiveWindow.Selection.Unselect
power.ActiveWindow.View.GotoSlide Index:=nb
power.ActiveWindow.Selection.Unselect

File: td_presentation_image.tex, line 61


power.ActiveWindow.Selection.SlideRange.Shapes.AddPicture _
        (Filename:=imnom, LinkToFile:=False, SaveWithDocument:=True, _
        Left:=0, Top:=0).Select

File: td_presentation_image.tex, line 68


Set slide = Nothing

File: td_presentation_image.tex, line 82


power.ActiveWindow.Selection.Unselect
power.ActiveWindow.View.GotoSlide Index:=nb
power.ActiveWindow.Selection.Unselect
power.ActiveWindow.Selection.SlideRange.Shapes(1).Select

File: td_presentation_image.tex, line 90


With power.ActiveWindow.Selection.ShapeRange
    .Left   ' coordonnées du coin supérieur gauche
    .Top    ' 
    
    .Width  ' largeur et 
    .Height ' hauteur de l'image
End With

File: td_presentation_image.tex, line 140


Load image_dialog    ' création de la boîte de dialogue
image_dialog.repertoire.Text = Cells(1, 1).Value  
   ' on stipule que dans la zone de saisie (dont le nom est repertoire),
   ' il doit y avoir lorsque la fenêtre apparaît
   ' le contenu de la première cellule de la feulle de calcul
image_dialog.Show  ' Excel reprend le contrôle et attend vos instructions 
                   ' après avoir affiché la boîte de dialogue

File: td_presentation_image.tex, line 153


' VBA ajoute automatiquement la première et la dernière de ces trois lignes
' variable_Annuler n'est pas la légende (Caption) du bouton Annuler
' mais son nom (Name)
Private Sub variable_Annuler_Click()
   Unload image_dialog
End Sub

File: td_presentation_image.tex, line 164


Unload image_dialog   							' on détruit la boîte de dialogue
Cells(1, 1).Value = repertoire.Text ' on récupère le répertoire saisi
                                    ' et on le met dans la première cellule de la feuille
' et ici : lancer la création du diaporama

File: td_presentation_image.tex, line 173


Private Sub Changer_Click()
    Dim s As String
    s = BrowseForFolderShell("Choisissez un répertoire", repertoire.Text)
    repertoire.Text = s
End Sub

File: td_presentation_image.tex, line 185


Function BrowseForFolderShell(title As String, repertoire As String) As String
    Dim objShell As Object
    Dim objFolder As Object
    Dim strFolderFullPath As String
    
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.BrowseForFolder(0, titre, 0, repertoire)
    
    If (Not objFolder Is Nothing) Then
        On Error Resume Next
        If IsError(objFolder.Items.Item.path) Then
           strFolderFullPath = CStr(objFolder): GoTo Here
        End If
        On Error GoTo 0
        If Len(objFolder.Items.Item.path) > 3 Then
            strFolderFullPath = objFolder.Items.Item.path & Application.PathSeparator
        Else
            strFolderFullPath = objFolder.Items.Item.path
        End If
    Else
        BrowseForFolderShell = repertoire
        Exit Function
    End If
    
Here:
    BrowseForFolderShell = strFolderFullPath
    
    Set objFolder = Nothing
    Set objShell = Nothing
    
End Function

File: td_presentation_image.tex, line 221


Function BrowseForFolderShell(title As String, repertoire As String) As String
    Dim fd As FileDialog
    Set fd = Application.FileDialog(msoFileDialogFolderPicker)
    fd.title = title
    fd.AllowMultiSelect = False
    fd.InitialFileName = repertoire & "\"

    If fd.Show = -1 Then
        Dim v As Variant
        For Each v In fd.SelectedItems
            BrowseForFolderShell = v
        Next
    Else 
        BrowseForFolderShell = repertoire
    End If

    Set fd = Nothing
End Function

File: td_presentation_image.tex, line 250


Function ListFileInFolder(chemin As String) As Variant
    Dim i As Long
    Dim res() As String
    
    ' mise en place de la liste de fichier
    With Application.FileSearch
         .NewSearch
         .FileType = msoFileTypeAllFiles
         .Filename = "*.jpg;*.jpeg;*.tif;*.png;*.bmp"
         .SearchSubFolders = False
         .LookIn = chemin
         If .Execute() > 0 Then
            ReDim res(.FoundFiles.Count)
            For i = 1 To .FoundFiles.Count
                res(i) = .FoundFiles(i)
            Next i
         End If
    End With
    ListFileInFolder = res
End Function

File: td_presentation_image_cor.tex, line 12


'
' retourne la liste des images d'un répertoire
'
Function ListFileInFolder(chemin As String) As Variant
    Dim i As Long
    Dim res() As String

    ' mise en place de la liste de fichier
    With Application.FileSearch
         .NewSearch
         .FileType = msoFileTypeAllFiles
         .Filename = "*.jpg;*.jpeg;*.tif;*.png;*.bmp"
         .SearchSubFolders = False
         .LookIn = chemin
         If .Execute() > 0 Then
            ReDim res(.FoundFiles.Count)
            For i = 1 To .FoundFiles.Count
                res(i) = .FoundFiles(i)
            Next i
         End If
    End With
    ListFileInFolder = res
End Function
      
'
' création d'un power point avec une liste d'images
'
Sub macro_film()

    Dim chemin As String
    Dim image As Variant
    Dim ligne As Long
    Dim colnne As Long
    
    ' on récupère le chemin sélectionné
    chemin = Selection.Value
    
    ' et sa position
    ligne = Selection.Row
    colonne = Selection.Column
    
    ' on récupère la liste des images
    image = ListFileInFolder(chemin)
    
    ' on crée un document PowerPoint
    Dim power As Object
    Set power = CreateObject("PowerPoint.Application")
    
    ' création d'une présentation
    Dim pres As Object
    Set pres = power.Presentations.Add(WithWindow:=msoTrue)

    ' on crée autant de pages qu'il y a de graphiques
    Dim page As Object
    
    ' pour voir le résultat et éviter que Word ne se ferme tout de suite
    power.Visible = True
    
    ' on insère les images
    Dim nb As Long
    For nb = 1 To UBound(image)
    
        ' on écrit le nom de l'image dans la cellule
        Cells(ligne + nb + 1, colonne).Value = image(nb)
    
        ' on ajoute un slide vide
        Set slide = pres.Slides.Add(Index:=nb, Layout:=12)
        power.ActiveWindow.ViewType = 1
        
        ' on sélectionne l'image pour changer sa taille
        ' magouille PowerPoint
        power.ActiveWindow.Selection.Unselect
        power.ActiveWindow.View.GotoSlide Index:=nb
        power.ActiveWindow.Selection.Unselect
        
        ' on insère une image
        power.ActiveWindow.Selection.SlideRange.Shapes.AddPicture _
                (Filename:=image(nb), LinkToFile:=False, SaveWithDocument:=True, _
                Left:=0, Top:=0).Select
        
        ' on sélectionne l'image pour changer sa taille
        ' magouille PowerPoint
        power.ActiveWindow.Selection.Unselect
        power.ActiveWindow.View.GotoSlide Index:=nb
        power.ActiveWindow.Selection.Unselect
        power.ActiveWindow.Selection.SlideRange.Shapes(1).Select
        
        ' on la position en haut à gauche
        With power.ActiveWindow.Selection.ShapeRange
            .Left = 0#
            .Top = 0#
        End With
        
        ' on sélectionne l'image pour changer sa taille
        ' magouille PowerPoint
        power.ActiveWindow.Selection.Unselect
        power.ActiveWindow.View.GotoSlide Index:=nb
        power.ActiveWindow.Selection.Unselect
        power.ActiveWindow.Selection.SlideRange.Shapes(1).Select
        
        ' on modifie sa taille
        With power.ActiveWindow.Selection.ShapeRange
            ' si l'image est trop petite
            If .Height < .Width And .Width < 400 Then .Width = 400
            If .Width < .Height And .Height < 400 Then .Height = 400
            ' si l'image est trop grande
            If .Width > power.Width Then .Width = power.Width
            If .Height > power.Height Then .Height = power.Height
            ' on centre l'image
            .Left = (power.Width - .Width) / 2
            .Top = (power.Height - .Height) / 2
            
            ' on écrit les dimensions de l'image dans les cellules suivantes
            Cells(ligne + nb + 1, colonne + 1).Value = .Left
            Cells(ligne + nb + 1, colonne + 2).Value = .Top
            Cells(ligne + nb + 1, colonne + 3).Value = .Width
            Cells(ligne + nb + 1, colonne + 4).Value = .Height        
        End With

        Set slide = Nothing
    Next nb
        
    ' on met un fond noir
    With power.ActivePresentation.SlideMaster.Background
        .Fill.Visible = msoTrue
        .Fill.ForeColor.SchemeColor = 2
        .Fill.Transparency = 0#
        .Fill.Solid
    End With
    With power.ActivePresentation.Slides.Range
        .FollowMasterBackground = msoTrue
        .DisplayMasterShapes = msoTrue
    End With
    
    ' on règle les transitions entre transparents
    With power.ActivePresentation.Slides.Range.SlideShowTransition
        .EntryEffect = 2819
        .Speed = 3
        .AdvanceOnClick = msoTrue
        .AdvanceOnTime = msoTrue
        .AdvanceTime = 1
        .SoundEffect.Type = 0
    End With
End Sub

File: td_presentation_image_cor.tex, line 160


Function BrowseForFolderShell(title As String, repertoire As String) As String
    Dim objShell As Object
    Dim objFolder As Object
    Dim strFolderFullPath As String
    
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.BrowseForFolder(0, titre, 0, repertoire)
    
    If (Not objFolder Is Nothing) Then
        On Error Resume Next
        If IsError(objFolder.Items.Item.path) Then strFolderFullPath = CStr(objFolder): GoTo Here
        On Error GoTo 0
        '// Is it the Root Dir?...if so change
        If Len(objFolder.Items.Item.path) > 3 Then
            strFolderFullPath = objFolder.Items.Item.path & Application.PathSeparator
        Else
            strFolderFullPath = objFolder.Items.Item.path
        End If
    Else
        BrowseForFolderShell = repertoire
        Exit Function
    End If
    
Here:
    BrowseForFolderShell = strFolderFullPath
    Set objFolder = Nothing
    Set objShell = Nothing
End Function

File: td_presentation_image_cor.tex, line 193


Private Sub Changer_Click()
    Dim s As String
    s = BrowseForFolderShell("Choisissez un répertoire", repertoire.Text)
    repertoire.Text = s
End Sub

Private Sub Ok_Click()
    ' on supprime la boîte de dialogue
    Unload image_dialog    
    Cells(1, 1).Value = repertoire.Text
End Sub

Private Sub Annuler_Click()
    ' on supprime la boîte de dialogue
    Unload image_dialog
End Sub

File: td_sudoku.tex, line 42


Function nombre_possible_pour_case(ByRef su As Variant, _
						ByVal i As Long, ByVal j As Long) As Variant
    ' ....
End Function

File: td_sudoku.tex, line 58


Function nombre_possible_pour_case(ByRef su As Variant, _
						ByVal i As Long, ByVal j As Long) As Variant
    Dim res() As Long     ' on crée le résultat sans connaître son contenu
    If ............ 
        ReDim res(0)                  ' on crée un tableau vide
        nombre_possible_pour_case = res ' c'est le résultat de la fonction
        Exit Function                   ' on quitte la fonction
    End If
End Function

File: td_sudoku.tex, line 73


Dim paspossible(9) As Long
Dim k As Long
For k = 1 To 9
    paspossible(k) = 0  ' au départ, tous les chiffres sont possibles
Next k

File: td_sudoku.tex, line 84


Dim ii, jj As Long
ii = i - ((i - 1) Mod 3)
jj = j - ((j - 1) Mod 3)

File: td_sudoku.tex, line 94


Dim n As Long
n = 0
For k = 1 To 9
    If ............... Then n = n + 1
Next k

File: td_sudoku.tex, line 105


ReDim res(n)
n = 0
For k = 1 To 9
    If ................  Then
        ...........
        ...........
    End If
Next k

' fin
nombre_possible_pour_case = res

File: td_sudoku.tex, line 123


Function resolution(ByRef su As Variant) As Variant
    ' .....
End Function

File: td_sudoku.tex, line 143


Function resolution(ByRef su As Variant) As Variant
    ' étape 1
    Dim i,j,vi,vj As Long
    vi = -1
    For i = 1 To 9 
        For j = 1 To 9
            If su (i,j) = 0 Then
               ...................
            End If
        Next j
     Next i
     
     If vi = ..... Then
         resolution = ..........
         Exit Function
     End If
     
     ' étape 2
     Dim ens As Variant
     ens = nombre_possible_pour_case (.......)
     If UBound (ens) ...... Then
         Dim res(0) As Long
         resolution = res
         Exit Function
     End If
     
     ' étape 3
     Dim k As Long
     Dim copie,solution As Variant
     copie = su
     For k = 1 To ..... 
         copie ( ...... ) = ens (k)
         solution = resolution (copie)
         If ..... Then
             .....
             Exit Function
         End If
     Next k
     
     ' au fait, a-t-on réussi ou non si on arrive ici,
     ' lors de l'exécution du programme ?
     resolution = .....
End Function

File: td_sudoku.tex, line 191


Dim nbiter As Long
Function resolution(ByRef su As Variant) As Variant
    nbiter = nbiter + 1
End Function

File: td_sudoku.tex, line 202


Sub macro_sudoku()
    Dim i As Long
    i = 0
    For Each ch In Selection
        i = i + 1  ' pointeur d'arrêt ici
    Next ch
    If i <> 81 * 2 Then
        MsgBox "Vous n'avez pas sélectionné 81 * 2 cases, on sélectionne la plage B2:J10 + N2:V10"
        Range("B2:J10,N2:V10").Select
        Range("N2").Activate
    End If 
End Sub

File: td_sudoku.tex, line 232


Dim sudoku(9, 9) as Long
i = 1
j = 1
For Each ch In Selection
    sudoku(i, j) = ........
    If j = 9 Then
        ......
    Else
        j = j + 1
    End If
Next ch

File: td_sudoku.tex, line 248


Dim r As Variant
nbiter = 0
r = resolution(sudoku)

File: td_sudoku_cor.tex, line 10


Option Explicit

Dim nbiter As Long

'
'  retourne le nombre de cases non vides
' on compte toutes celles qui ne contiennent pas 0
'
Function sudoku_cases_non_vide(ByRef su As Variant) As Long
    Dim n As Long
    Dim i As Long
    Dim j As Long
    
    n = 0
    For i = 1 To 9
        For j = 1 To 9
            If su(i, j) > 0 Then n = n + 1
        Next j
    Next i
    
    sudoku_cases_non_vide = n
End Function

'
' retourne l'ensemble des nombres possibles pour une case
' en tenant compte des contraintes
'
Function nombre_possible_pour_case(ByRef su As Variant, _
						ByVal i As Long, ByVal j As Long) As Variant

    Dim res() As Long
    
    ' on regarde d'abord si la case est vide
    If su(i, j) > 0 Then
        ReDim res(0)
        nombre_possible_pour_case = res
        Exit Function
    End If
    
    ' on crée un tableau,
    ' si paspossible (i) : alors le chiffre i est déjà
    ' pris ailleurs dans la ligne, dans la colonne ou dans le petit carré
    ' qui contiennent la case i,j
    
    Dim paspossible(9) As Long
    Dim k As Long
    For k = 1 To 9
        paspossible(k) = 0  ' au départ, tous sont possibles
    Next k
    
    ' vérification des contraintes en ligne et en colonne
    For k = 1 To 9
        If su(i, k) > 0 Then
            paspossible(su(i, k)) = 1
        End If
        
        If su(k, j) > 0 Then
            paspossible(su(k, j)) = 1
        End If
    Next k
    
    ' vérification des contraintes dans le petit carré de la case i,j
    Dim ii, jj, iii, jjj As Long
    ii = i - ((i - 1) Mod 3)
    jj = j - ((j - 1) Mod 3)
    
    For iii = ii To ii + 2
        For jjj = jj To jj + 2
            If su(iii, jjj) > 0 Then
                paspossible(su(iii, jjj)) = 1
            End If
        Next jjj
    Next iii
    
    ' nombre de possibles = tous ceux qui ne sont pas dans pospossible
    ' on les compte d'abord
    Dim n As Long
    n = 0
    For k = 1 To 9
        If paspossible(k) = 0 Then n = n + 1
    Next k
    
    ' puis on les met dans res
    ReDim res(n)
    n = 0
    For k = 1 To 9
        If paspossible(k) = 0 Then
            n = n + 1
            res(n) = k
        End If
    Next k
    
    ' fini
    nombre_possible_pour_case = res
    
End Function

'
' retourne l'ensemble des nombres possibles pour une case
' en tenant compte des contraintes
'
Function get_best_solution(ByRef su As Variant) As Variant
    Dim i, j, mi, mj As Long
    Dim pos As Variant
    
    ' on regarde d'abord si toutes les cases sont encore viables
    For i = 1 To 9
        For j = 1 To 9
            If su(i, j) = 0 Then
                pos = nombre_possible_pour_case(su, i, j)
                If UBound(pos) = 0 Then
                    Dim r(0) As Long
                    get_best_solution = r
                    Exit Function
                End If
            End If
        Next j
    Next i
    
    ' on teste la case qui offre le moins de chiffres possibles vérifiant
    ' les contraintes
    Dim l As Long
    l = 0
    For i = 1 To 9
        For j = 1 To 9
            If su(i, j) = 0 Then
                pos = nombre_possible_pour_case(su, i, j)
                If UBound(pos) = 1 Then
                    Dim rrr(2) As Long
                    rrr(1) = i
                    rrr(2) = j
                    get_best_solution = rrr
                    Exit Function
                ElseIf l = 0 Or UBound(pos) < l Then
                    l = UBound(pos)
                    mi = i
                    mj = j
                End If
            End If
        Next j
    Next i
    
    If l > 0 Then
        ' s'il y a une solution
        Dim rr(2) As Long
        rr(1) = mi
        rr(2) = mj
        get_best_solution = rr
    Else
        ' s'il n'y en a pas
        ' excusez le nom de la variable (rrrr),
        ' la portée d'une variable en VBA est la procédure
        ' même si sa déclaration est à l'intérieur d'un bloc
        Dim rrrr(0) As Long
        get_best_solution = rrrr
    End If
End Function

'
' résolution du sudoku, su est le sudoku à résoudre
'
Function resolution(ByRef su As Variant) As Variant
    ' premier cas, le sudoku est déjà résolu,
    ' auquel cas, c'est fini
    ' la variable nbiter compte le nombre d'itération pour la résolution
    ' il vaut mieux vérifier que ce nombre ne devient pas trop grand,
    ' sinon, il est possible que le programme entre dans une boucle infinie
    ' ce qui oblige l'utilisateur à relancer Excel après l'avoir détruit l'application
    ' dans le gestionnaire des tâches
    If sudoku_cases_non_vide(su) = 81 Or nbiter > 2000 Then
        resolution = su
        Exit Function
    End If
    
    nbiter = nbiter + 1
    
    Dim copie As Variant
    copie = su
    
    ' retourne la case la plus sympathique
    Dim b As Variant
    b = get_best_solution(copie)
    
    ' s'il existe une case impossible
    If UBound(b) = 0 Then
        Dim r(0) As Variant
        resolution = r
        Exit Function
    End If
    
    Dim i, j As Long
    i = b(1)
    j = b(2)
    
    Dim nb As Variant
    Dim sol As Variant
    nb = nombre_possible_pour_case(copie, i, j)
    
    ' sinon on teste toutes les solutions possibles pour une case
    Dim k As Long
    For k = 1 To UBound(nb)
        copie(i, j) = nb(k)
        sol = resolution(copie)
        If UBound(sol) > 0 Then
            resolution = sol
            Exit Function
        End If
    Next k
    
    ' pas de solution
    Dim re(0) As Long
    resolution = re
End Function

'
' macro appelée lorsque le bouton est enclenché
'
Sub macro_sudoku()
    Dim sudoku() As Variant
    Dim i, j As Long
    Dim nb As Long
    Dim ch
    
    ' vérification
    i = 0
    For Each ch In Selection
        i = i + 1
    Next ch
    If i <> 81 * 2 Then
        MsgBox "Vous n'avez pas sélectionné 81 * 2 cases, on sélectionne la plage B2:J10 + N2:V10"
        Range("B2:J10,N2:V10").Select
        Range("N2").Activate
    End If
    
    ' on remplit le sudoku avec les 81 premières cases
    ReDim sudoku(9, 9)
    i = 1
    j = 1
    For Each ch In Selection
        sudoku(i, j) = ch.Value
        If j = 9 Then
            j = 1
            i = i + 1
            If i = 10 Then Exit For
        Else
            j = j + 1
        End If
    Next ch
        
    ' on résoud le sudoku
    Dim r As Variant
    nbiter = 0
    r = resolution(sudoku)
    
    If UBound(r) > 0 Then
        ' s'il y a une solution, on remplit les cases
        i = 1
        j = 1
        For Each ch In Selection
            If i >= 10 Then
                ch.Value = r(i - 9, j)
            End If
            If j = 9 Then
                j = 1
                i = i + 1
            Else
                j = j + 1
            End If
        Next ch
    Else
        ' s'il n'y a pas de solution, on remplit les cases de zéros
        i = 1
        j = 1
        For Each ch In Selection
            If i >= 10 Then
                ch.Value = 0
            End If
            If i = 9 Then
                i = 1
                j = j + 1
            Else
                i = i + 1
            End If
        Next ch
    End If
End Sub

calcul d'un quantile

def quantile (valeurs, alpha) :
    """calcul le quantile d'ordre alpha"""
    if len (valeurs) == 0 : raise Exception ("liste vide")
    valeurs.sort ()
    i = int (alpha * len (valeurs))
    return valeurs [i]

calcul d'un quantile

numToAlpha = 'abcdefghijklmnopqrstuvwxyz'.upper ()
def celluple (s) :
    """convertit une cellule en couple ligne,colonne  C2 --> 2,3,  AA1 --> 1,27"""
    if len (s) <= 1 : return 1,1
    if "0" <= s [1] <= "9" : return int (s [1:]), numToAlpha.find (s [0])+1
    else : return int (s [1:]), (numToAlpha.find (s [0])) * 26 + numToAlpha.find (s [1]) + 1

import win32com.client                                  # module 
excel = win32com.client.Dispatch ('Excel.Application')  # connexion à Excel

tab = 'A2:A25'              # plage de valeurs
par = celluple ('C2')       # position du quantile demandé
res = celluple ('C3')       # position du résultat

feuille = excel.ActiveSheet                                  # on récupère la feuille active
plage   = [ v [0].Value for v in feuille.Range (tab) ]       # on convertit une plage en une liste
param   = float (feuille.Cells (par [0], par [1]).Value)     # on convertit une valeur en un réel

try :
    # on calcule le quantile
    import quantile
    q = quantile.quantile (plage, param)
    feuille.Cells (res [0], res [1]).Value = q          # on place le résultat dans la plage C3
except Exception, e :
    # au cas où une erreur se produit
    feuille.Cells (res [0], res [1]).Value = str (e)    # on place l'erreur dans la plage C3

File: chap4_vba_python.tex, line 48


Public Sub UpdatePythonCode()
    Shell ("c:\python25\pythonw excel.py")
End Sub

File: chap4_vba_python.tex, line 66


tab = __PLAGE__               # ligne 11
par = celluple (__PAR__)      # ligne 12
res = celluple (__RES__)      # ligne 13

File: chap4_vba_python.tex, line 78


Public Function LoadString(ByVal file As String)
    ' ouvre un fichier et construit une unique chaîne de caractères à partir de son contenu
    Dim res As String
    Dim sLine As String
    Open file For Input As #1
    Do While Not EOF(1)
        Line Input #1, sLine
        res = res & sLine & vbCrLf  ' on ajoute les sauts de lignes qui sont oubliés lors de la lecture
    Loop
    Close #1
    LoadString = res
End Function

Public Function WriteString(ByVal s As String, ByVal file As String)
    ' on écrit une unique chaîne de caractères dans un fichier
    Open file For Output As #1
        Print #1, s
    Close #1
End Function

Public Sub UpdatePythonCode()
    ' code la macro
    Dim range1 As String
    Dim par As String
    Dim res As String
    python = LoadString("excel_sample.py")
    python = Replace(python, "__PLAGE__", "'A2:A25'")
    python = Replace(python, "__PAR__", "'C2'")
    python = Replace(python, "__RES__", "'C3'")
    WriteString python, "temp.py"
    Shell ("c:\python25\pythonw temp.py")
End Sub

File: chap4_vba_python.tex, line 115


tab = __PAR0__                 # ligne 11
par = celluple (__PAR1__)      # ligne 12
res = celluple (__RES0__)      # ligne 13

File: chap4_vba_python.tex, line 124


Public Sub RunPythonScript(ByVal script As String, ByVal par As String, ByVal res As String)
    Dim p As Variant
    Dim r As Variant
    Dim python As String
    Dim i As Long
    Dim temp As String
    
    p = Split(par)  ' on découpe la liste des plages d'entrées séparées par des espaces
    r = Split(res)  ' on découpe la liste des plages de sorties séparées par des espaces
    
    python = LoadString(script)   ' on charge le script Python
    
    ' on remplace les paramètres d'entrée par les bonnes plages
    For i = 0 To UBound(p)
        temp = "__PAR" & Val(i) & "__"
        python = Replace(python, temp, "'" & p(i) & "'")
    Next i
    
    ' on remplace les paramètres de sortie par les bonnes plages
    For i = 0 To UBound(r)
        temp = "__RES" & Val(i) & "__"
        python = Replace(python, temp, "'" & r(i) & "'")
    Next i
    
    ' la fin est identique, on écrit le fichier temp.py puis on l'exécute
    WriteString python, "temp.py"
    Shell ("c:\python25\pythonw temp.py")
End Sub

Public Sub UpdatePythonCode()
    RunPythonScript "excel_sample2.py", "A2:A25 C2", "C3"
End Sub

File: chap4_vba_python.tex, line 168


import scipy.linalg
import numpy
import random
m = [ [ random.gauss (0,1) for i in range (0,3) ] for i in range (0,3) ]
mat = numpy.array (m)
mat = mat + mat.transpose ()
l,v = scipy.linalg.eig (mat)
print l
print v

fonctions usuelles pour la communication entre \pythons et \textit{Excel

numToAlpha = 'abcdefghijklmnopqrstuvwxyz'.upper ()
def celluple (s) :
    """convertit une cellule en couple ligne,colonne"""
    if len (s) <= 1 : return 1,1
    if "0" <= s [1] <= "9" : return int (s [1:]), numToAlpha.find (s [0])+1
    else : return int (s [1:]), (numToAlpha.find (s [0])) * 26 + numToAlpha.find (s [1]) + 1
        
def nombre_colonne (plage) :
    """retourne le nombre de colonnes d'une plage"""
    p = plage.split (":")
    return celluple (p [1]) [1] - celluple (p [0]) [1] + 1
        
def lit_matrice (plage, feuille) :
    """transcrit une plage de la feuille Excel en matrice"""
    temp = [ v [0].Value for v in feuille.Range (plage) ]
    nc   = nombre_colonne (plage)
    nl   = len (temp) / nc
    res  = [ [ temp [i*nc+j] for j in range (0,nc) ] for i in range (0,nl) ]
    return res

def ecrit_matrice (valeur, vecteur, plage, feuille) :
    """transcrit une matrice vers une plage d'une feuille Excel"""
    # on calcule la premiere cellule de la plage
    if ":" in plage : i,j = celluple (plage.split (":") [0]) 
    else :            i,j = celluple (plage)   
    # les valeurs propres sont complexes
    for l in range (0, len (valeur)) :
        if valeur [l].imag != 0 :  feuille.Cells (i, j + l).Value = str (valeur [l])
        else : feuille.Cells (i, j + l).Value = valeur [l].real
    # les vecteurs propres sont reels
    for k in range (0, len (vecteur)) :
        for l in range (0, len (vecteur [k])) :
            feuille.Cells (i + k + 2, j + l).Value = str (vecteur [k][l])

calcul des valeurs propres

from excel_function import *
import win32com.client
excel = win32com.client.Dispatch ('Excel.Application')

mat = __PAR0__ # = 'A1:C3' ajout pour debugger
res = __RES0__ # = 'A5'    ajout pour debugger

feuille = excel.ActiveSheet

try :
    import scipy.linalg
    import numpy
    mat = numpy.array (lit_matrice (__PAR0__, feuille))
    valeur,vecteur = scipy.linalg.eig (mat)
    ecrit_matrice (valeur, vecteur, __RES0__, feuille)
except Exception, e :
    if ":" in res : i,j = celluple (res.split (":") [0]) 
    else :          i,j = celluple (res)                 
    feuille.Cells (i, j).Value = str (e)

File: chap4_vba_python.tex, line 194


Public Sub UpdatePythonCode()
    RunPythonScript "excel_eig.py", "A1:C3", "A5"
End Sub

File: chap4_vba_python.tex, line 203


Option Explicit  ' rend explicite les déclarations de variables

Private Const PROCESS_QUERY_INFORMATION As Long = &H400
Private Const STILL_ACTIVE As Long = &H103
Public gszErrMsg As String

' utilisation d'une fonction OpenProcess remplaçant Shell, elle ne fait pas partie du langage VBA
' mais elle fait partie d'une DLL système de Windows
' la ligne qui suit déclare la fonction OpenProcess et l'ajoute à la liste de celles disponibles
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _
                                                     ByVal bInheritHandle As Long, _
                                                     ByVal dwProcessId As Long) As Long
                                                     
' permet d'obtenir un code d'erreur après l'exécution de OpenProcess                                                    
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, _
                                                            lpExitCode As Long) As Long

' remplacement de la fonction Shell
' retourne True si l'exécution s'est bien passée, False sinon
' les paramètres d'entrée sont les mêmes que ceux de la fonction Shell
Private Function ShellWait(ByVal szCommandLine As String, _
                           Optional ByVal iWindowState As Integer = vbHide) As Boolean

    Dim lTaskID As Long
    Dim lProcess As Long
    Dim lExitCode As Long
    Dim lResult As Long
    
    On Error GoTo ErrorHandler  ' si une erreur se produit, aller au label ErrorHandler

    ' exécute la ligne de commande szCommandLine
    lTaskID = Shell(szCommandLine, iWindowState)
    
    ' vérifie qu'il n'y a pas d'erreur
    If lTaskID = 0 Then Err.Raise 9999, , "Shell function error."
    
    ' attrape le processus lancé par Shell et qui est en cours d'exécution
    lProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0&, lTaskID)
    
    ' regarde s'il y a des erreurs
    If lProcess = 0 Then Err.Raise 9999, , "Unable to open Shell process handle."
    
    ' attend la fin de l'exécution du script
    Do
        ' lExitCode est égale à STILL_ACTIVE tant que le script continue d'être exécuté
        lResult = GetExitCodeProcess(lProcess, lExitCode)
        DoEvents
    Loop While lExitCode = STILL_ACTIVE
    
    ShellWait = True
    Exit Function
    
ErrorHandler:
    ' gestion des erreurs (gszErrMsg conserve le message d'erreur)
    gszErrMsg = Err.Description
    ShellWait = False
End Function

File: chap4_vba_python.tex, line 293


library (tseries)  

File: chap4_vba_python.tex, line 299


x=get.hist.quote("AXA", quote = c("Open", "High", "Low", "Close"), retclass = "ts")
x100=window(x,start=end(x)[1]-100)
plotOHLC(x100,ylab="prix",main="AXA")

File: chap4_vba_python.tex, line 307


x=get.hist.quote("AXA", quote = c("Open", "High", "Low", "Close"), retclass = "ts")
x100=window(x,start=end(x)[1]-100)
png ("c:\\temp\\essai2.png", width=700, height=500)  # enregistrement au format png
plotOHLC(x100,ylab="prix",main="AXA")
dev.off ()                                           # fin de l'enregsitrement

File: chap4_vba_python.tex, line 324


	Date	Open	High	Low	Close	Volume
20/03/08	56.01	56.75	55.26	55.84	2434000
19/03/08	57.53	57.95	56.40	56.77	2714400
18/03/08	58.85	58.99	57.13	57.61	3265900
...

File: chap4_vba_python.tex, line 333


r <- read.table ("edf.txt", header = TRUE, row.names = 1)

File: chap4_vba_python.tex, line 338


r [[1]]            # accède à la colonne 1 en tant que vecteur
r [["Open"]]       # accède à la colonne Open en tant que vecteur
row.names (r)      # retourne le nom des lignes
length(r)          # retourne le nombre de colonnes
length (r [[1]])   # retourne le nombre de lignes
ts(r)              # convertit r en une série temporelles

File: chap4_vba_python.tex, line 352


from rpy import *    # importer le module rpy

# définition du programme R
code = """library (tseries)
x=get.hist.quote("AXA", quote = c("Open", "High", "Low", "Close"), retclass = "ts")
x100=window(x,start=end(x)[1]-100)
png ("essai2.png", width=700, height=500)
plotOHLC(x100,ylab="prix",main="AXA")
dev.off ()"""

r(code)   # exécution du code

File: chap4_vba_python.tex, line 372


from rpy import *
code = """library (tseries)
x=get.hist.quote("AXA", quote = c("Open", "High", "Low", "Close"), retclass = "ts")
x100=window(x,start=end(x)[1]-100)
plotOHLC(x100,ylab="prix",main="AXA")
r(code)

dessin du cours d'une action avec \codes{rpy

# partie R
from rpy import *
code = """library (tseries)
x=get.hist.quote("AXA", quote = c("Open", "High", "Low", "Close"), retclass = "ts")
x100=window(x,start=end(x)[1]-100)
png ("essai2.png", width=700, height=500)
plotOHLC(x100,ylab="prix",main="AXA")
dev.off ()"""
r(code)

# partie HTML
html = """<html><body><h1>depuis R</h1><img src="NAME"/></body></html>"""
html = html.replace ("NAME", "essai2.png")
f = open ("essai2.html", "w")
f.write (html)
f.close ()

File: chap4_vba_python.tex, line 396


ActiveSheet.Pictures.Insert("essai2.png").Select

dessin du cours d'une action avec \textit{Excel

def finance (action, last, image = "temp.png") :
    # dessin de la série
    from rpy import *
    code = """library (tseries)
    x=get.hist.quote(""" + "\"" + action + "\"" + """, 
               quote = c("Open", "High", "Low", "Close"), retclass = "ts")
    x100=window(x,start=end(x)[1]-""" + str (last) + """)
    png ("c:\\\\essai2.png", width=1000, height=500)
    plotOHLC(x100,ylab="prix",main=""" + "\"" + action + "\"" + """)
    dev.off ()"""
    r(code)

    # extraction avec volume pour export vers Excel
    code = """x=get.hist.quote(""" + "\"" + action + "\"" + """, 
                    quote = c("Open", "High", "Low", "Close", "Volume"), retclass = "ts")
    x100=window(x,start=end(x)[1]-""" + str (last) + """)"""
    r (code)

    # conversion en python
    series = r ("x100")
    return series
    
def copie_tableau (series, i,j) :
    """recopie un tableau dans un feuille"""
    for xi in range (0, len (series)) :
        for xj in range (0, len (series [xi])) :
            feuille.Cells (i + xi, j + xj).Value = series [xi][xj]

import win32com.client
from celluple import *
excel = win32com.client.Dispatch ('Excel.Application')

act = celluple (__PAR0__)
par = celluple (__PAR1__)
res = celluple (__RES0__)

feuille = excel.ActiveSheet
action  = str (feuille.Cells (act [0], act [1]).Value)
param   = float (feuille.Cells (par [0], par [1]).Value)

try :
    series = finance (action, param)
    copie_tableau (series, res [0], res [1])
except Exception, e :
    feuille.Cells (res [0], res [1]).Value = str (e)

File: chap4_vba_python.tex, line 428


' charge un fichier texte
Public Function LoadString(ByVal file As String)
    Dim res As String
    Dim sLine As String
    Open file For Input As #1
    Do While Not EOF(1)
        Line Input #1, sLine
        res = res & sLine & vbCrLf
    Loop
    Close #1
    LoadString = res
End Function

' écrit un fichier texte
Public Function WriteString(ByVal s As String, ByVal file As String)
    Open file For Output As #1
        Print #1, s
    Close #1
End Function

' exécute un script Python
Public Sub RunPythonScript(ByVal script As String, ByVal par As String, ByVal res As String)
    Dim p As Variant
    Dim r As Variant
    Dim python As String
    Dim i As Long
    Dim temp As String
    
    p = Split(par)
    r = Split(res)
    
    python = LoadString(script)
    
    For i = 0 To UBound(p)
        temp = "__PAR" & Val(i) & "__"
        python = Replace(python, temp, "'" & p(i) & "'")
    Next i
    For i = 0 To UBound(r)
        temp = "__RES" & Val(i) & "__"
        python = Replace(python, temp, "'" & r(i) & "'")
    Next i
    
    WriteString python, "temp.py"
    ShellWait ("c:\python25\pythonw temp.py")
End Sub

' lance l'exécution d'un script Python puis charge une image
Public Sub UpdatePythonCode()
    RunPythonScript "rplot2.py", "C3 C4", "B7"
    ActiveSheet.Pictures.Insert("essai2.png").Select
End Sub

' cette dernière fonction est celle attachée à la pression du bouton "dessiner"
Private Sub dessiner_Click()
    UpdatePythonCode
End Sub

File: usb.tex, line 18


class copie_usb (object):
    """recopie des fichiers sur une clé USB"""
    
    def __init__(self,ch1,ch2,accept = ".*",refuse = "") :
        """initialisation,
        @param      ch1         répertoire source
        @param      ch2         répertoire destination
        @param      accept      filtre pour les fichiers acceptés pour la copie
        @param      refuse      pour refuser des fichiers parmi ceux déjà acceptés"""
        
    def accepter (self, fichier) :
        """dit si un fichier est accepté à la copie ou non,
        retourne un booléen"""
        
    def liste_fichier_repertoire (self,repertoire):
        """récupération de la liste des répertoires et celle des fichiers, 
        inclus dans le répertoire repertoire"""
        
    def copie (self) :
        """effectue la copie"""
        
        # première étape
        # récupération de la liste des répertoires et fichiers

        # seconde étape
        # élimination des importuns
        
        # troisième étape
        # on créé les répertoires s'ils n'existent pas
                
        # quatrième étape
        # on recopie les fichiers
        

# petit exemple d'utilisation
c = copie_usb (ch1, ch2, filtre_accept, filtre_refuse)
c.copie ()

File: usb.tex, line 103


import re
t = re.compile (".*[.]htm$", re.IGNORECASE)
if re.match (t, "inDex.htm") : print True
else : print False
if re.match (t, "inDex.html") : print True
else : print False

File: usb.tex, line 114


print re.match (t, "inDex.htm")  # affiche <_sre.SRE_Match object at 0x008712C0>
print re.match (t, "inDex.html") # affiche None

copie de fichiers vers une clé USB

# coding: cp1252
"""copie de fichiers sur une clé USB"""

import re       # pour les expressions régulières
import os       # pour les fichiers et répertoires
import os.path  # pour les noms de fichiers et noms de répertoires
import copy
import shutil   # pour la copie de fichiers

class copie_usb (object):
    """recopie des fichiers sur une clé USB"""
    
    def __init__(self,ch1,ch2,accept = ".*",refuse = "") :
        """initialisation,
        @param      ch1         répertoire source
        @param      ch2         répertoire destination
        @param      accept      filtre pour les fichiers acceptés pour la copie
        @param      refuse      pour refuser des fichiers parmi ceux déjà acceptés"""
        self.ch1     = ch1
        self.ch2     = ch2
        self.accept  = re.compile (accept, re.IGNORECASE) # création des motifs
        self.refuse  = re.compile (refuse, re.IGNORECASE) # création des motifs
        
    def accepter (self, fichier) :
        """dit si un fichier est accepté à la copie ou non"""
        r = re.match (self.accept, fichier)
        if not r : return False
        r = re.match (self.refuse, fichier)
        return not r
        
    def aide (self) :
        """retourne une aide sur les formats d'expression"""
        help (re.engine)
        
    def liste_fichier_repertoire (self,repertoire):
        """récupération de la liste des répertoires et celle des fichiers, 
        inclus dans le répertoire repertoire"""
        rep     = []
        file    = []
        list    = os.listdir (repertoire)
        
        for cc in list :
            c = repertoire + "\\" + cc
            if os.path.isfile (c) : file.append (cc)
            if os.path.isdir (c) : rep.append (cc)
        
        rep2 = copy.copy (rep)
        for chemin in rep2 :
            r,f = self.liste_fichier_repertoire (repertoire + "\\" + chemin)
            for x in r :
                rep.append (chemin + "\\" + x)
            for x in f :
                file.append (chemin + "\\" + x)
            
        return rep,file
        
    def repertoire_selectionne (self, r, file_clean) :
        """dit si la liste file_clean contient au moins un fichier 
        inclus dans le repertoire r"""
        t = re.compile ("^" + r + "\\\\.*", re.IGNORECASE)
        for l in file_clean :
            if re.match (t,l) : return True
        return False
        
    def copie (self) :
        """effectue la copie"""
        
        # récupération de la liste des répertoires et fichiers
        rep,file = self.liste_fichier_repertoire (self.ch1)
        # élimination des importuns
        file_clean = [ f for f in file if self.accepter (f) ]
        
        # facultatif, exclue les répertoires pour lesquels 
        # aucun fichier n'est sélectionné
        rep_clean = [ r for r in rep if self.repertoire_selectionne (r, file_clean) ]
        
        # on créé les répertoires s'il n'existent pas
        if not os.path.exists (self.ch2) :
            print "création du répertoire ", self.ch2
            os.mkdir (self.ch2)

        for r in rep_clean :
            c = self.ch2 + "\\" + r
            if not os.path.exists (c) :
                print "création du répertoire ", r
                os.mkdir (c)
                
        # on recopie les fichiers
        for f in file_clean :
            s = self.ch1 + "\\" + f
            c = self.ch2 + "\\" + f
            print "copie du fichier ", f
            shutil.copy (s, c)
        

if __name__ == "__main__" :
    print "copie de fichiers vers une clé USB"
    ch1             = "C:\\Documents and Settings\\Dupré\\" \
                        "Mes documents\\informatique\\support\\python_td"
    ch2             = "c:\\temp\\copie_usb"
    filtre_accept   = ".*[.].*"
    filtre_refuse   = ".*[.]pdf$|.*[.]html$|.*[.]bmp|programme\\\\.*[.]zip$"
    
    # filtre_accept accepte tout type de fichier
    # filtre_refuse refuse tous les fichiers dont l'extension est pdf, html ou 
    # inclus dans le répertoire programme et ayant l'extension zip
    
    c = copie_usb (ch1, ch2, filtre_accept, filtre_refuse)
    c.copie ()


File: html_recherche.tex, line 13


p = HTMLParser ()
p.feed (text)
p.close ()

File: html_recherche.tex, line 24


<a href="bresenham_ligne4.html"> tracé d'une ligne</a>

File: html_recherche.tex, line 30


def handle_starttag (self, tag,attr) :
    print "balise ", tag
    for i,j in attr :
        print i,j
        if i == "href" :
           # ...

File: html_recherche.tex, line 39


def handle_data (self, data) :
    d = data.replace ("\n", "")

File: html_recherche.tex, line 47


class HTML_explore (HTMLParser.HTMLParser) :

    def __init__ (self, list, url, text) :
        html_parser_script.HTMLParserScript.__init__(self)
        self.list           = list
        self.url            = url
        self.text           = text

File: html_recherche.tex, line 60


adr = urlparse.urljoin ("http://www.lemonde.fr/", "web/article/")

File: html_recherche.tex, line 69


try :
    f       = urllib.urlopen (url)
    d       = f.read ()
    whole   = d
except Exception, exc:
    print "    exception lecture ", exc, "\t -- ", url
    error.append (url)
    continue 

File: html_recherche.tex, line 83


p       = HTML_explore (adr, url, text)
p.feed (whole)
p.close ()

File: html_recherche.tex, line 93


s               = ".*Bush.*"
ex              = re.compile (s, re.IGNORECASE)
if ex.match (contenu) : 
    # ...

File: html_recherche.tex, line 104


url         = "http://www.lemonde.fr/"
# on appelle la fonction process_file pour récupérer les informations
# inscrites dans le fichier XML
s               = ".*ukraine.*"
ex              = re.compile (s, re.IGNORECASE)
li,error,nb     = process_file (url, ex, 3, -10)

recherche de mot-clés sur Internet (1)

# coding: cp1252
"""recherche de mot-clés dans des pages HTML, 
ce programme ne peut lire pour l'instant que le format HTML 2.0
et pas HTML 4.01, format utilisé par la plupart des sites."""

import urllib               # accéder une adresse internet
import urlparse             # manipuler les adresses internet
import re                   # expression à chercher
import html_parser_script   # classe de parser HTML modifiée pour éviter les scripts

class HTML_explore (html_parser_script.HTMLParserScript) :
    """parcour un fichier HTML"""
    
    def __init__ (self, list, text, url, niveau, niveau_max) :
        html_parser_script.HTMLParserScript.__init__(self)
        self.list           = list
        self.niveau         = niveau
        self.niveau_max     = niveau_max
        self.url            = url
        self.text           = text
        
    def cherche (self,url) :
        """recherche un url dans la liste"""
        for n,u in self.list :
            if u == url : return True
        return False
        
    def diese (self,adr) :
        """simplifie les liens avec le symboles #"""
        p = adr.find ("#")
        if p == -1 : return adr
        else : return adr [0 : p]

    def handle_starttag (self, tag,attr) :
        """nouveau tag ou balise"""
        if self.niveau >= self.niveau_max : return
        self.tag = tag
        if self.tag == "a" or self.tag == "area" :
            for i,j in attr :
                if (i == "aref" or i == "href") and len (j) > 0 and j [0] != "#" :
                    adr = self.diese (j)
                    if len (adr) > 4 and (adr [0:4] == "http" or adr == "ftp") :
                        if not self.cherche (adr) :
                            self.list.append ((self.niveau, adr))
                    elif len (adr) > 5 and adr [0:6] != "mailto" :
                        adr = urlparse.urljoin (self.url, adr)
                        if not self.cherche (adr) :
                            self.list.append ((self.niveau, adr))
        
    def handle_endtag (self, tag) :
        """fin d'un tag ou balise"""
        pass
        
    def handle_data (self, data) :
        """texte compris entre le début et la fin d'un tag"""
        d = data.replace ("\n", "")
        if len (d) > 3 :
            self.text.append (data)
        
        
def process_file (url, exp, niveau_max = 5, nbmax = -1) :
    """parcours un fichier HTML et retourne la liste des url
    qui contiennent l'expression, la liste des 
    adresses qui n'ont pas pu être atteinte ainsi que le nombre d'adresses
    explorées, cette fonction n'explore pas plus de 
    nbmax pages sauf si nbmax == -1"""
    
    res     = []
    error   = []

    # création d'une classe qui va parcourir le fichier XML
    adr     = [(0, url)]
    text    = []
    errfile = 0
    nb      = 0
    
    for niv,url in adr :

        nb     += 1
        if nb > nbmax and nbmax >= 0 : break
        whole   = ""
        print "open %d/%d" % (nb,len (adr)), 
        print " found = ", len (res), " -- ", niv, " : ", url

        try :
            f       = urllib.urlopen (url)
            d       = f.read ()
            whole  += d
        except Exception, exc:
            print "    exception lecture ", exc, "\t -- ", url
            error.append (url)
            continue 
            
        try :
            text    = []
            p       = HTML_explore (adr, text, url, niv+1, niveau_max)
            # on lit le fichier file ligne par ligne,
            # chaque ligne est envoyée au parser XML 
            p.feed (whole)
            p.close ()
            
            t = ""
            for s in text : t += s + " "
            t = t.replace ("\n", " ")
            t = t.replace ("\r", " ")
            if exp.match (t) : res.append (url)
                
        except Exception, exc:
            print "    exception html ", exc, exc.__class__, "\t -- ", url
            error.append (url)
            f = open ("c:\\temp\\html_err" + str (errfile) + ".html", "w")
            f.write (whole)
            f.close ()
            errfile += 1
            continue 
    
    return res, error, len (adr)
        
    

if __name__ == "__main__" :
    # choix d'un nom de fichier
    url         = "http://www.lemonde.fr/"
    # on appelle la fonction process_file pour récupérer les informations
    # inscrites dans le fichier XML
    s               = ".*Bush.*"
    ex              = re.compile (s, re.IGNORECASE)
    li,error,nb     = process_file (url, ex, 3, -10)
    
    print "--------------------------------------------------------------------"
    print "--------------------------------------------------------------------"
    print "nombre d'adresses explorées :\t", nb
    print "nombre d'adresses sélectionnées :\t", len (li)
    print "nombre d'adresses non ouvertes ou mal lues :\t", len (error)
    print "--------------------------------------------------------------------"
    print "--------------------------------------------------------------------"
    if len (li) > 0 :
        print "url contenant l'expression ", s
        for l in li :
            print " --------- " , l

    if len (error) > 0 :
        print "url n'ayant pas pu être ouverts ou mal lus "
        for l in error :
            print " --- erreur ", l

recherche de mot-clés sur Internet (2)

# coding: cp1252
"""recherche de mot-clés dans des pages HTML, 
ce programme ne peut lire pour l'instant que le format HTML 2.0
et pas HTML 4.01, format utilisé par la plupart des sites."""

import HTMLParser       # parcourir un fichier HTML
import re
import markupbase

starttagopen = re.compile('<[a-zA-Z]')

attrfind = re.compile(
    r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*'
    r'(\"[a-z]+\"#[a-zA-Z.  ]+[.][a-zA-Z]+|\"[0-9]+\"\"|\'[^\']*\'|"[^"]*"'\
     '|([a-zA-Z_:.]+\s*\([0-9/a-zA-Z\"\',.  &;éèàùûâêîô\-_\?:!=@]*\))'\
     '(;void\(0\);)?|\"\"|[-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~]*))?')

# si locatestarttagend est modifié, il faut penser à modifier
# également attrfind
locatestarttagend = re.compile(r"""
  <[a-zA-Z][-.a-zA-Z0-9:_]*          # tag name
  (?:\s+                             # whitespace before attribute name
    (?:[a-zA-Z_][-.:a-zA-Z0-9_]*     # attribute name
      (?:\s*=\s*                     # value indicator
        (?:([a-zA-Z_:.]+\s*\([0-9/a-zA-Z\"',.  &;éèàùûâêîô\-_\?:!=@]*\))(;void\(0\);)? #                
          |\"[0-9]+\"\"              # colspan = "2""
          |\"[a-z]+\"\#[a-zA-Z.  ]+[.][a-zA-Z]+   # "rect"#Le Monde.fr
          |\"\"                      # alt = ""
          |\"[^\"]*\"                # LIT-enclosed value
          |'[^']*'                   # # LITA-enclosed value
          |[^'\">\s]+                # bare value
         )
       )?
     )
   )*
  \s*                                # trailing whitespace
""", re.VERBOSE)

entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
charref = re.compile('&#@(?:[0-9]+|[xX][0-9a-fA-F]+)[^0-9a-fA-F]')
incomplete = re.compile('&[a-zA-Z#]')

commentclose = re.compile(r'--\s*>|/\s*>|-- /\s*>|-\s*>')


class HTMLParserScript (HTMLParser.HTMLParser) :
    
    def parse_comment(self, i, report=1):
        rawdata = self.rawdata
        #assert rawdata[i:i+4] == '<!--', 'unexpected call to parse_comment()'
        match = commentclose.search(rawdata, i+4)
        if not match:
            print "-------------------------------------------------------"
            print rawdata[i:i+250]
            print "-------------------------------------------------------"
            print end
            print "-------------------------------------------------------"
            return -1
        if report:
            j = match.start()
            self.handle_comment(rawdata[i+4: j])
        j = match.end()
        return j
        
    def _scan_name(self, i, declstartpos):
        rawdata = self.rawdata
        n = len(rawdata)
        if i == n:
            return None, -1
        m = markupbase._declname_match(rawdata, i)
        if m:
            s = m.group()
            name = s.strip()
            if (i + len(s)) == n:
                return None, -1  # end of buffer
            return name.lower(), m.end()
        else:
            self.updatepos(declstartpos, i)
            print "-------------------------------------------------------"
            print rawdata[i:i+250]
            print "-------------------------------------------------------"
            print end
            print "-------------------------------------------------------"
            self.error("expected name token")
            
    def parse_starttag(self, i):
        self.__starttag_text = None
        endpos = self.check_for_whole_start_tag(i)
        if endpos < 0:
            return endpos
        rawdata = self.rawdata
        self.__starttag_text = rawdata[i:endpos]

        # Now parse the data between i+1 and j into a tag and attrs
        attrs = []
        match = HTMLParser.tagfind.match(rawdata, i+1)
        assert match, 'unexpected call to parse_starttag()'
        k = match.end()
        self.lasttag = tag = rawdata[i+1:k].lower()

        while k < endpos:
            m = attrfind.match(rawdata, k)
            if not m:
                break
            attrname, rest, attrvalue = m.group(1, 2, 3)
            if not rest:
                attrvalue = None
            elif attrvalue[:1] == '\'' == attrvalue[-1:] or \
                 attrvalue[:1] == '"' == attrvalue[-1:]:
                attrvalue = attrvalue[1:-1]
                attrvalue = self.unescape(attrvalue)
            attrs.append((attrname.lower(), attrvalue))
            k = m.end()

        end = rawdata[k:endpos].strip()
        if end not in (">", "/>"):
            lineno, offset = self.getpos()
            if "\n" in self.__starttag_text:
                lineno = lineno + self.__starttag_text.count("\n")
                offset = len(self.__starttag_text) \
                         - self.__starttag_text.rfind("\n")
            else:
                offset = offset + len(self.__starttag_text)
            print "-------------------------------------------------------"
            print rawdata[i:i+250]
            print "-------------------------------------------------------"
            print end
            print "-------------------------------------------------------"
            self.error("junk characters in start tag: %s"
                       % `rawdata[k:endpos][:20]`)
        if end.endswith('/>'):
            # XHTML-style empty tag: <span attr="value" />
            self.handle_startendtag(tag, attrs)
        else:
            self.handle_starttag(tag, attrs)
            if tag in self.CDATA_CONTENT_ELEMENTS:
                self.set_cdata_mode()
        return endpos
        
    def check_for_whole_start_tag(self, i):
        rawdata = self.rawdata
        m = locatestarttagend.match(rawdata, i)
        if m:
            j = m.end()
            next = rawdata[j:j+1]
            if next == ">":
                return j + 1
            if next == "/":
                if rawdata.startswith("/>", j):
                    return j + 2
                if rawdata.startswith("/", j):
                    # buffer boundary
                    return -1
                # else bogus input
                self.updatepos(i, j + 1)
                self.error("malformed empty start tag")
            if next == "":
                # end of input
                return -1
            if next in ("abcdefghijklmnopqrstuvwxyz=/"
                        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
                # end of input in or before attribute value, or we have the
                # '/' from a '/>' ending
                return -1
            #if next in "'" :
            #    return -1
            print "------------------------------------"
            print next
            print m.groups ()
            print "------------------------------------"
            print rawdata [i: i + 250]
            print "...................................."
            print rawdata [j: j + 30]
            self.updatepos(i, j)
            self.error("malformed start tag")
        raise AssertionError("we should not get here!")
        
    def goahead(self, end):
        if not self.__dict__.has_key ("_script") :
            self._script    = False         # ajout
            self._nb_script = 0             # ajout
        rawdata = self.rawdata
        i = 0
        n = len(rawdata)
        while i < n:
            match = self.interesting.search(rawdata, i) # < or &
            if match:
                j = match.start()
            else:
                j = n
            if i < j: self.handle_data(rawdata[i:j])
            i = self.updatepos(i, j)
            if i == n: break
            startswith = rawdata.startswith

            if self._script :                           # ajout
                if startswith('</script>', i):          # ajout
                    k = i + len ('</script>')           # ajout
                    self._script = False                # ajout
                    i = self.updatepos(i, k)
                elif startswith('</SCRIPT>', i):       # ajout
                    k = i + len ('</SCRIPT>')           # ajout
                    self._script = False                # ajout
                    i = self.updatepos(i, k)
                else:
                    k = i + 1
                    i = self.updatepos(i, k)
            elif startswith('<', i):
                if startswith("<script", i):
                    self._nb_script += 1
                    k = i + len ("<script")
                    self._script = True
                elif startswith("<SCRIPT", i):
                    self._nb_script += 1
                    k = i + len ("<SCRIPT")
                    self._script = True
                elif starttagopen.match(rawdata, i): # < + letter
                    k = self.parse_starttag(i)
                elif startswith("</", i):
                    k = self.parse_endtag(i)
                elif startswith("<!--", i):
                    k = self.parse_comment(i)
                elif startswith("<!-", i):
                    k = self.parse_comment(i)
                elif startswith("<!/", i):
                    k = self.parse_comment(i)
                elif startswith("<!-- /", i):
                    k = self.parse_comment(i)
                elif startswith("<?", i):
                    k = self.parse_pi(i)
                elif startswith("<!", i):
                    k = self.parse_declaration(i)
                elif (i + 1) < n:
                    self.handle_data("<")
                    k = i + 1
                else:
                    break
                if k < 0:
                    if end:
                        print "######################################### (1)"
                        print rawdata [i:i+250]
                        self.error("EOF in middle of construct")
                    break
                i = self.updatepos(i, k)
            elif startswith("&#", i):
                match = charref.match(rawdata, i)
                if match:
                    name = match.group()[2:-1]
                    self.handle_charref(name)
                    k = match.end()
                    if not startswith(';', k-1):
                        k = k - 1
                    i = self.updatepos(i, k)
                    continue
                else:
                    break
            elif startswith('&', i):
                match = entityref.match(rawdata, i)
                if match:
                    name = match.group(1)
                    self.handle_entityref(name)
                    k = match.end()
                    if not startswith(';', k-1):
                        k = k - 1
                    i = self.updatepos(i, k)
                    continue
                match = incomplete.match(rawdata, i)
                if match:
                    # match.group() will contain at least 2 chars
                    if end and match.group() == rawdata[i:]:
                        print "######################################### (2)"
                        print rawdata [i:i+250]
                        self.error("EOF in middle of entity or char ref")
                    # incomplete
                    break
                elif (i + 1) < n:
                    # not the end of the buffer, and can't be confused
                    # with some other construct
                    self.handle_data("&")
                    i = self.updatepos(i, i + 1)
                else:
                    break
            else:
                assert 0, "interesting.search() lied"
        # end while
        if end and i < n:
            self.handle_data(rawdata[i:n])
            i = self.updatepos(i, n)
        self.rawdata = rawdata[i:]

fond d'écran

"""panorama avec images"""
import pygame
import os
import time
from PIL import Image
import random

def attendre_touche () :
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONUP : return "clic"
        elif event.type == pygame.KEYDOWN : 
            if event.key == 275 : return "right"
            elif event.key == 276 : return "left"
            elif event.key == 273 : return "up"
            elif event.key == 274 : return "down"
            elif event.key == 27 : return "quit"
            elif event.key == 32 : return "pause"
            else :
                pass
                #print "key ", event.key
        else :
            #print event
            pass
    return ""
       

def get_image_list (dir = ".") :
    li = os.listdir (dir)
    res = []
    for l in li :
        s = l.lower ()
        if "jpg" in s or "png" in s or "jpeg" in s :
            res.append (l)
    res.sort ()
    return res
    
def image_resize (im, size, pil = True) :
    s = im.get_size ()
    rapx = float (size [0]) / s [0]
    rapy = float (size [1]) / s [1]
    
    rap = min (rapx, rapy)
    rap = min (rap, 2.0)
    
    size2 = ( int (s [0] * rap), int (s [1] * rap) )
    
    if not pil :
        res = pygame.transform.scale (im, size2)
    else :
        # scale from pygame is not good, use PIL's one
        s = pygame.image.tostring (im, "RGBX")
        temp = Image.fromstring ("RGBX", im.get_size (), s)
        tu = (0,0, im.get_size () [0]-1, im.get_size () [1] - 1)
        temp = temp.transform (size2, Image.EXTENT,  tu, Image.BICUBIC)
        mode = temp.mode
        size = temp.size
        data = temp.tostring()
        res = pygame.image.fromstring (data, size, mode)    
    return res
    
def load_image (file) :
    try :
        im = pygame.image.load (file)
    except Exception, e :
        print "unable to load image ", file, " error ", e
        return None
    return im
    
def display (sur, im) :
    im = image_resize (im, sur.get_size ())
    sur.fill ( (0,0,0) )
    
    x = (sur.get_size () [0] - im.get_size () [0]) / 2
    y = (sur.get_size () [1] - im.get_size () [1]) / 2
    
    sur.blit (im, (x,y))
    
def loop (sur, li, d = 500, rnd = True, transition = True) :
    
    already = { }
    for i in range (0, len (li)) : already [i] = - len (li) 
    
    print "number of images ", len (li)
    lo = 0
    i = 0
    while i < len (li) or rnd :
        
        lo += 1
        if rnd : 
            i = random.randint (0, len (li)-1)
            while lo - already [i]  < len (li) / 2 :
                i = random.randint (0, len (li)-1)
        im = li [i]
        already [i] = lo
        
        
        ti = pygame.time.get_ticks ()
        
        s = load_image (im)
        if s == None : continue
            
        display (sur, s)
        
        if not transition :
            pygame.display.flip ()
        else :
            ts = sur.get_size ()
            for i in xrange (0, ts [0], 20) :
                r = pygame.Rect (i, 0, i+100, ts [1])
                pygame.display.update (r)
                pygame.time.delay (10)
        
        
        ti = ti - pygame.time.get_ticks ()
        
        ti = max (0, d - ti)
        pygame.time.delay (ti)
        
        if pygame.event.peek () :
            t = attendre_touche ()
            if t == "quit" : return 
            elif t == "left" : i -= 1
            elif t == "right" : i += 1
            elif t == "up" : i += 10
            elif t == "down" : i += 10
            elif t == "pause" :
                while attendre_touche () != "pause" :
                    pass
        i += 1
        i = max (i, 0)
        
    print "stop at ", i
            
    
if __name__ == "__main__" :
    li = get_image_list ()
    
    pygame.init ()
    pygame.display.set_mode ((1280,800), pygame.FULLSCREEN)
    #pygame.display.set_mode ((1280,800)) #, pygame.FULLSCREEN)
    s = pygame.display.get_surface ()
    
    loop (s, li)

    pygame.time.delay (1000)

popularité avec des moteurs de recherche

#!/usr/bin/python
# coding: latin-1
import urllib
 
from recherche_voila_popularite import *


class Acteur :
    def __init__ (self, nom, prenom, age, nationalite, sexe) :
        self.nom            = nom
        self.prenom         = prenom
        self.age            = age
        self.nationalite    = nationalite
        self.sexe           = sexe
        
        s = "\"" + prenom + " " + nom + "\""
        self.voila          = combien_voila (s)
        self.bing           = combien_bing (s)
        self.ebay           = combien_ebay (s)
        
    def liste_compteur (self) :
        return [ self.voila, self.bing, self.ebay ]
        
print "commencement"        
act = []
act.append ( Acteur ("foster", "jodie", 40, "us", "f") )
act.append ( Acteur ("depardieu", "gerard", 55, "fr", "h") )
act.append ( Acteur ("deneuve", "catherine", 60, "fr", "f") )
act.append ( Acteur ("harrison", "ford", 60, "us", "h") )
if False :  # False pour corriger le programme plus rapidement, True sinon
    act.append ( Acteur ("redford", "robert", 60, "us", "h") )
    act.append ( Acteur ("depp", "johnny", 40, "us", "h") )
    act.append ( Acteur ("eastwoord", "clint", 75, "us", "h") )
    act.append ( Acteur ("sarandon", "susan", 60, "us", "f") )
    act.append ( Acteur ("dunst", "kirsten", 20, "us", "f") )
    act.append ( Acteur ("portman", "nathalie", 25, "us", "h") )
    act.append ( Acteur ("roberts", "julia", 40, "us", "f") )
    act.append ( Acteur ("tautou", "audrey", 30, "fr", "f") )
    act.append ( Acteur ("cotillard", "marion", 30, "fr", "f") )
    act.append ( Acteur ("binoche", "juliette", 40, "fr", "f") )
    act.append ( Acteur ("berry", "richard", 50, "fr", "h") )
    act.append ( Acteur ("bruel", "patrick", 45, "fr", "h") )

def ajoute_liste (l1, l2) :
    for i in range (0, len (l1)) :
        l1 [i] += l2 [i]
    
def divise_liste (l1, s) :
    for i in range (0, len (l1)) :
        l1 [i] /= s
    

# france contre etats - unis
fr = [ 0,0,0 ]
us = [ 0,0,0 ]
nb_fr = 0
nb_us = 0
for a in act :
    print "cherche ", a.nom,
    l = a.liste_compteur ()
    print l
    if a.nationalite == "fr" :
        nb_fr += 1
        ajoute_liste (fr, l)
    if a.nationalite == "us" :
        nb_us += 1
        ajoute_liste (us, l)

divise_liste (us, nb_us) 
divise_liste (fr, nb_fr) 

print "------------------------------"
print "compteur nb_us = ", nb_us, " nb_fr : ", nb_fr
for i in range (0, len (us)) :
    print "us : ", us [i], " \t fr : ", fr [i]

# homme contre femme
f = [ 0,0,0 ]
h = [ 0,0,0 ]
nb_f = 0
nb_h = 0
for a in act :
    print "cherche ", a.nom,
    l = a.liste_compteur ()
    print l
    if a.sexe == "f" :
        nb_f += 1
        ajoute_liste (f, l)
    if a.sexe == "h" :
        nb_h += 1
        ajoute_liste (h, l)

divise_liste (h, nb_h) 
divise_liste (f, nb_f) 

print "------------------------------"
print "compteur nb_h = ", nb_h, " nb_f : ", nb_f
for i in range (0, len (us)) :
    print "h : ", h [i], " \t f : ", f [i]


occurrences dans une liste

# question 2
def lit_fichier (file) :
    f = open (file, "r")  # ouverture du fichier en mode lecture "r"
    li = f.readlines ()     # lecture des lignes du fichier texte
    f.close ()               # fermeture du fichier, l'acces est libre pour d'autres applications
    
    # on enleve les separateurs de fin de lignes, 
    # caracteres invisibles qui permettent aux editeurs de texte (Scite, Notepad) 
    # de se retrouver dans les lignes
    res = []
    for l in li :
        s = l.replace ("\n", "")
        res.append (s)
    return res
    
# question 3
def compte_A (li) :
    nb = 0
    for l in li :
        if l [0] == "A" : nb += 1
    return nb
    
# question 4
def compte (li, lettre) :
    nb = 0
    for l in li :
        if l [0] == lettre : nb += 1
    return nb
    
# question 5
def compte_toute (li) :
    alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    res = []
    for a in alpha :
        n = compte (li, a)
        res.append (n)
    return res
    
# question 6
def compte_dico (li) :
    res = { }
    for l in li :
        a = l [0]
        if a in res : res [a] += 1
        else : res [a] = 1
    return res
    
    
lis = lit_fichier ("td_note_texte.txt")

a = compte_A (lis)
print a  # donne 65

a = compte (lis, "A")
print a  # donne 65

all = compte_toute (lis) 
print len (all), all # affiche 26 [65, 16, 69, 46, 53, 39, ...

res = compte_dico (lis)
print res  # {'A': 65, 'C': 69, 'B': 16, 'E': 53,  ...

# question 7
"""
cout fonction compte_toute : 26 * cout fonction compte = 26 * longueur de la liste
cout fonction compte_dico :    longueur de la liste * cout recherche dichotomique 
                                       = longueur de la liste * ln(26)/len(2)
"""

# question 8
def compte_8 (li) :
    res = [ ]
    nb = 1
    le = li [0][0]
    for i in range (1, len (li)) :
        if li [i][0] != li [i-1][0] :
            res.append ( (le, nb) )
            nb = 1
            le = li [i][0]
        else : 
            nb += 1
    res.append ( (le, nb) )
    return res
    
res = compte_8 (lis)
print res  # [('A', 65), ('B', 16), ('C', 69), ('D', 46), ('...
    


star

# question 1,2
#
# extrait du fichier une matrice de n lignes et deux colonnes
# separateur de ligne \n
# separateur de colonne \t
#
def lit_fichier (file) :
    f = open (file, "r")
    li = f.readlines ()   # separation en lignes
    f.close ()
    
    mat = []
    for l in li :
        s = l.replace ("\n", "")
        s = s.split ("\t")  # separation en colonne
        if len (s) == 2 :
            # ce test est ajoute pour verifier qu'on ajoute pas 
            # des lignes vides dans la matrice
            # les lignes vides ne contiennent pas de separateur \t 
            # et ne contiennent qu'une colonne
            mat.append (s)
    return mat
    
# question 3    
def prenom_frequent (mat) :
    # les prenoms sont en colonne 0
    res = { }
    for i in range (0, len (mat)) :
        p = mat [i][0]
        if p in res : res [p] += 1
        else : res [p] = 1
            
    # on recherche le maximum : maximum sur toutes les valeurs
    mx = max ( res.values () )
    
    # on recherche tous les prenoms qui sont aussi frequent que mx
    freq = []
    for p in res :
        if res [p] == mx : freq.append (p)
            
    return freq,mx
    
# question 4
def family_group (mat) :
    # on choisit de representer les familles sont la forme d'un dictionnaire de listes
    # cle : parents (colonne 1 de mat)
    # valeur : liste de prenoms (colonne 0 de mat)
    res = { }
    for i in range (0, len (mat)) :
        pr = mat [i][0]
        pa = mat [i][1]
        if pa in res : res [pa].append (pr) # on ajoute le prenom a la liste
        else : res [pa] = [ pr ]   # liste d'un seul prenom
    return res
    
# question 5
def moyenne_mediane (dico) :
    # on repart du resultat de la fonction family_group
    # et on construit la liste des tailles de familles
    taille = []
    for pa in dico :
        taille.append ( len (dico [pa] ) )
    
    moyenne = float (sum (taille)) / len (taille)
    taille.sort ()
    mediane = taille [ len (taille) / 2 ]
    return moyenne, mediane
    
# test    
mat = lit_fichier ("star.txt")
freq,mx = prenom_frequent (mat)
print "prenom frequents ", freq
print "present ", mx, " fois"
fam = family_group (mat)
moyenne, mediane = moyenne_mediane (fam)
print "moyenne ", moyenne, " mediane ", mediane

for pa in fam :
    print pa
    for pr in fam [pa] :
        print "    ", pr
        

tri classique


def tri(l):
    """effectue le tri classique : 
    on recherche le minimum, on le place en premiere
    position et on recommence avec les elements restant"""
    for k in range (0,len (l)-1) :
        # recherche du minimum
        p = k
        for n in range (k+1, len (l)) : 
            if l [n] < l [p] :
                p = n
        # echange
        ech     = l [k]
        l [k]     = l [p]
        l [p]     = ech

k=[2,8,9,5,15,4,56,78,85,15,45,3]
print "non triee ", k
tri(k)
print "triee ",k


tri fusion

def fusion(a,b):
    """fonction fusionnant les deux listes a,b supposees triees,
    retourne une liste triee.
    
    a chaque passage dans la boucle, on ajoute un element
    provenant de l'une des deux listes, on conserve pour ces 
    deux listes l'indice de l'element suivant a inserer 
    dans la liste resultat : k pour la liste a, n pour la liste b
    
    a chaque passage, on choisit le plus petit, 
       si c'est celui de la liste a, on incremente k,
       si c'est celui de la liste b, on incremente n
       
       il faut faire attention lorsqu'on a ajouter les elements d'une liste,
       parce que l'indice k ou n ne designe aucun element, de plus,
       cela signifie qu'on doit ajouter les derniers elements
       de l'autre liste.
    """
    c=[]
    l=len(a)+len(b)
    k=0
    n=0
    while len(c)<l:
        if k==len(a):     # liste a terminee
            c.extend (b[n:])
        elif n==len(b):   # liste b terminee
            c.extend(a[k:])
        elif a[k]<b[n]:   # element de la liste plus petit
            c.append(a[k])
            k=k+1
        else :            # element de la liste b plus petit
            c.append(b[n])
            n=n+1
    return c

def tri(l):
    """effectue le tri par fusion, coupe la liste en deux,
    appelle recursivement le tri par fusion sur chacun des
    deux morceaux puis assemble les deux listes triees
    
    le cout de cette fonction depend de n : 
        - fusionner de liste a un cout en O(n)
        - on appelle la fonction fusion sur :
                - le tableau initial : n elements
                - sur deux moities : 2 * n/2
                - sur quarts quarts : 4 * n/4
                - ...
                - sur n/2 sous-liste de 2 elements : n/2 * 2
    le cout du tri par fusion est n * autant de fois
    qu'on peut divisier n par 2 : O(n log (n))"""
    if len(l)>1:
        n=int(len(l)/2)
        a=l[n:len(l)]  # premiere moitie
        b=l[0:n]       # seconde moitie
        tri(a)         # tri de la premier moitie
        tri(b)         # tri de la seconde moitie
        t=fusion(a,b)  # fusion des deux listes triees
        for i in range(0,len(l)):  # on recopie la liste triee dans la 
            l[i]=t[i]              # liste initiale
        # on ne peut pas ecrire que :
        #   l = t
        # car dans ce cas, on sert du nom l pour stocker autre chose
        # que la liste l, cette ligne attribuerait le nom l a une autre liste
        # qui serait perdue a la fin de la fonction

k=[2,8,9,5,15,4,56,78,85,15,45,3]
print "non triee ", k
tri(k)
print "triee ",k

tracé d'une ligne

# coding: cp1252
"""ce module contient la fonction trace_ligne qui retourne l'ensemble des pixels
concernés par le tracé d'une ligne en 8-connexité entre deux pixels"""
import pygame                 # pour les affichages
import random

def trace_ligne_simple (x1,y1,x2,y2):
    """trace une ligne entre les points de coordonnées (x1,y1) et (x2,y2),
    on suppose que x2 > x1, y2 >= y1, 
    retourne la ligne sous la forme d'un ensemble de pixels (x,y)"""
    
    if y2 - y1 <= x2 - x1 :  # droite en dessous de la première bissectrice
        vx = x2 - x1
        vy = y2 - y1
        b  = vx / 2
        y  = y1
        x  = x1
        
        ligne = []
        while x <= x2 :
            ligne.append ((x,y))
            b -= vy
            x += 1
            if b < 0:
                b += vx
                y += 1
        return ligne
    else :                   # droite au dessus de la première bissectrice
        vx = x2 - x1
        vy = y2 - y1
        b  = vy / 2
        y  = y1
        x  = x1
        
        ligne = []
        while y <= y2 :
            ligne.append ((x,y))
            b -= vx
            y += 1
            if b < 0:
                b += vy
                x += 1
        return ligne
    
def trace_ligne (x1,y1,x2,y2):
    """trace une ligne entre les points de coordonnées (x1,y1) et (x2,y2),
    aucune contrainte sur les coordonnées,
    retourne la ligne sous la forme d'un ensemble de pixels (x,y)"""
    
    if x1 == x2 :
        if y1 <= y2: return [ (x1, i) for i in xrange (y1,y2+1) ]
        else : return [ (x1, i) for i in xrange (y2,y1+1) ]
        
    if y1 == y2 :
        if x1 <= x2: return [ (i, y1) for i in xrange (x1,x2+1) ]
        else : return [ (i, y1) for i in xrange (x2,x1+1) ]
    
    if x1 < x2 :
        if y1 < y2 : 
            return trace_ligne_simple (x1,y1,x2,y2)
        else :
            ligne = trace_ligne_simple (x1,y2,x2,y1)
            return [ (x,y1 + y2 - y) for (x,y) in ligne ]
        
    if x2 < x1 :
        if y1 < y2 : 
            ligne = trace_ligne_simple (x2,y1,x1,y2)
            return [ (x1 + x2 - x, y) for (x,y) in ligne ]
        else :
            ligne = trace_ligne_simple (x2,y2,x1,y1)
            return [ (x1 + x2 - x, y1 + y2 - y) for (x,y) in ligne ]

def display_ligne (ligne, screen):
    """affiche une ligne à l'écran"""
    color = 0,0,0
    for p in ligne:
        pygame.draw.line (screen, color, p,p)
    pygame.display.flip ()
    
    
def attendre_clic (screen):
    """attend la pression d'un clic de souris pour continuer"""
    reste = True
    while reste:
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONUP :
                reste = False
                break

if __name__ == "__main__" :
    pygame.init ()
    
    size      = width, height = x,y = 200, 200
    black     = 0, 0, 0
    white     = 255,255,255
    screen    = pygame.display.set_mode(size)
    screen.fill (white)
    
    print trace_ligne (0,0, 7,3)  
    # affiche [(0, 0), (1, 0), (2, 1), (3, 1), (4, 2), (5, 2), (6, 3), (7, 3)]
    
    for n in xrange (0,10):
        x1      = random.randint (0,x-1)        
        y1      = random.randint (0,y-1)        
        x2      = random.randint (0,x-1)        
        y2      = random.randint (0,y-1)        
        ligne   = trace_ligne (x1,y1,x2,y2)
        display_ligne (ligne, screen)

    attendre_clic (screen)

interface graphique avec Tkinter

import Tkinter as T
root = T.Tk ()

# moitie gauche de la fenetre
f1 = T.Frame ()
f1.grid (column = 0, row = 0)

# moitie droite de la fenetre
f2 = T.Frame ()
f2.grid (column = 1, row = 0)

# creation d'une zone de texte dans la moitie gauche (f1)
l1 = T.Label (f1, text = "f(x) = ")
l1.grid (column = 0, row = 0)

# creation d'une zone de texte dans la moitie droite (f2)
lf2 = T.Label (f2, text = "dessin de la fonction")
lf2.grid (column = 0, row = 0)

# creation d'une zone de saisie
fonction = T.Entry (f1)
fonction.grid (column = 1, row = 0)
fonction.insert (0, "x**2 + x * math.cos (x)")

# creation d'une zone de dessin
dessin = T.Canvas (f2, width = 400, height = 400)
dessin.grid (column = 0, row = 1)
dessin.create_line (0,200,400,200, fill = "blue", width = 2)
dessin.create_text (10,210, text = "-5", fill = "black", font = "arial")

# creation d'un bouton quitter
bouton = T.Button (f1, text = "quitter")
bouton.grid (column = 0, row = 6)
bouton.config (command = root.destroy)

# creation d'un autre bouton
bouton = T.Button (f1, text = "dessin")
bouton.grid (column = 0, row = 2)

# on associe le bouton a une fonction
import random
def fonction_bouton_dessin () :
    dessin.create_line (0,0, random.randint (0,400), random.randint (0,400))

bouton.config (command = fonction_bouton_dessin)

root.mainloop ()

File: window.tex, line 43


import math
x = 0
print eval ("math.cos (x) + math.exp (x)")  # affiche 2

interface graphique avec Tkinter

# on importe le module Tkinter avec le pseudonyme T
import Tkinter as T
import math

# on cree la fenetre principale sans l'afficher
# la fenetre est vide, on lui ajoute des elements par la suite
root = T.Tk ()

# taille de l'ecran (carre)
ecran = 400

# moitie gauche de la fenetre
f1 = T.Frame ()
f1.grid (column = 0, row = 0)

# moitie droite de la fenetre
f2 = T.Frame ()
f2.grid (column = 1, row = 0)

# creation d'une zone de texte dans la moitie gauche (f1)
l1 = T.Label (f1, text = "f(x) = ")
l1.grid (column = 0, row = 0)

# creation d'une zone de texte dans la moitie droite (f2)
lf2 = T.Label (f2, text = "dessin de la fonction")
lf2.grid (column = 0, row = 0)

# creation d'une zone de saisie pour la fonction
fonction = T.Entry (f1)
fonction.grid (column = 1, row = 0)
fonction.insert (0, "x**2 + x * math.cos (x)")

# creation d'une zone de dessin
dessin = T.Canvas (f2, width = ecran, height = ecran)
dessin.grid (column = 0, row = 1)

# creation des quatre zones de texte et de saisie
# pour les limitesdu graphiques
lxmin = T.Label (f1, text = "xmin")
lxmax = T.Label (f1, text = "xmax")
lymin = T.Label (f1, text = "ymin")
lymax = T.Label (f1, text = "ymax")
xmin = T.Entry (f1)
xmax = T.Entry (f1)
ymin = T.Entry (f1)
ymax = T.Entry (f1)
lxmin.grid (column = 0, row = 2)
lxmax.grid (column = 0, row = 3)
lymin.grid (column = 0, row = 4)
lymax.grid (column = 0, row = 5)
xmin.grid (column = 1, row = 2)
xmax.grid (column = 1, row = 3)
ymin.grid (column = 1, row = 4)
ymax.grid (column = 1, row = 5)
xmin.insert (0, "-5")
xmax.insert (0, "5")
ymin.insert (0, "-5")
ymax.insert (0, "5")

# creation d'une zone de texte dans la moitie droite (f2)
lcouleur = T.Label (f1, text = "couleur")
lcouleur.grid (column = 0, row = 6)

# creation d'une zone de saisie pour la couleur
couleur = T.Entry (f1)
couleur.grid (column = 1, row = 6)
couleur.insert (0, "blue")

# creation d'un bouton quitter
bouton = T.Button (f1, text = "quitter")
bouton.grid (column = 0, row = 7)
bouton.config (command = root.destroy)

# creation d'un bouton dessiner
bouton = T.Button (f1, text = "dessin")
bouton.grid (column = 1, row = 7)

# dessin de la fonction 
def fonction_bouton_dessin () :

    # on recupere les bornes du graphique converties en reels
    rxmin = float (xmin.get ())
    rxmax = float (xmax.get ())
    rymin = float (ymin.get ())
    rymax = float (ymax.get ())
    
    # on recupere la fonction
    f    = fonction.get ()
    
    # on recupere la couleur
    c    = couleur.get ()
    
    # tout le probleme consiste a convertir des coordonnees
    # reelles en pixels, c'est un changement de repere
    t    = (rxmax - rxmin) / ecran  # un pixel correspond a t
    
    # on va relier les points ( rxmin + n t, f ( rxmin + n t )
    # pour tous les n compris entre 0 et ecran
    x    = rxmin
    
    # tant que x de depasse pas rxmax
    while x <= rxmax :
    
        # on evalue la fonction f
        y  = eval (f)
        
        # on convertit le point (x, f(x)) en pixels (ix, iy)
        ix = int ((x - rxmin) / (rxmax - rxmin) * ecran) 
        iy = ecran - int ((y - rymin) / (rymax - rymin) * ecran) 
        
        if x == rxmin :
            # si c'est le premier point du graphe, 
            dessin.create_line (ix,iy,ix,iy, fill = c, width = 1)
        else :
            # s'il y a deja eu d'autres points traces (ix_, iy_),
            # on les relie a ix, iy
            dessin.create_line (ix_,iy_,ix,iy, fill = c, width = 1)
            
        # on memorise ix,iy dans ix_,iy_
        ix_,iy_ = ix,iy
        
        # on passe au pixel suivant
        x += t
        
# on associe le bouton dessin a la fonction fonction_bouton_dessin
bouton.config (command = fonction_bouton_dessin)

# on lance la fenetre principale
root.mainloop ()

trois objets Tkinter

# coding:latin-1
import Tkinter                          # import du module des interfaces graphiques

# fenêtre principale
root = Tkinter.Tk ()

# on place un label
l = Tkinter.Label (text = "label")      # on crée l'objet
l.pack ()                               # on l'insère dans la fenêtre principale

# on place une zone de saisie
e = Tkinter.Entry ()                    # on crée l'objet
e.pack ()                               # on l'insère dans la fenêtre principale

# on place un bouton
b = Tkinter.Button (text = "bouton")    # on crée l'objet
b.pack ()                               # on l'insère dans la fenêtre principale

# on affiche la fenêtre
root.mainloop ()

File: pendu.tex, line 27


def fonction () :
    # faire quelque chose ici
b.config (command = fonction)

File: pendu.tex, line 35


l.config (text = "nouvel intitulé")  # changer l'intitulé
contenu = e.get ()                   # récupérer le contenu de la zone de saisie

trois objets Tkinter (2)

# coding:latin-1
import Tkinter                          # 
root = Tkinter.Tk ()                    #   
l = Tkinter.Label (text = "label")      # même programme que précédemment
l.pack ()                               # 
e = Tkinter.Entry ()                    # 
e.pack ()                               # 
b = Tkinter.Button (text = "bouton")    # 
b.pack ()                               # 
   
def fonction () :                       #
    contenu = e.get ()                  #
    l.config (text = contenu)           # lignes insérées
b.config (command = fonction)           #

root.mainloop ()                        # même programme que précédemment

trois objets Tkinter (2) (correction)

# coding:latin-1
import Tkinter
root = Tkinter.Tk ()
l = Tkinter.Label (text = "label")
l.pack ()
e = Tkinter.Entry ()
e.pack ()
b = Tkinter.Button (text = "bouton")
b.pack ()

coup = 0
   
def fonction () :
    global coup
    coup += 1
    contenu = e.get ()
    message = "coup " + str (coup) + " saisie " + contenu
    l.config (text = message)
b.config (command = fonction)

root.mainloop ()

jeu du pendu avec Tkinter

# coding:latin-1
import Tkinter

mot_a_trouve = "pendu"
nb_coup      = 0

# dessin de la fenêtre
root = Tkinter.Tk ()

coup = Tkinter.Label ()
coup.pack ()

jeu = Tkinter.Label ()
jeu.pack ()

lettre = Tkinter.Entry ()
lettre.pack ()

b = Tkinter.Button (text = "jouer")
b.pack ()

# fonction pour le pendu
def blanc_souligne (mot, lettres) :
    res = ""
    for m in mot :
        if m in lettres : res += m
        else : res += "_"
    return res
    
def fonction_jouer () :
    global mot_a_trouve
    global nb_coup
    global coup
    global jeu
    global lettre
    
    nb_coup += 1
    m = blanc_souligne (mot_a_trouve, lettre.get ())
    
    if "_" in m :
        coup.config (text = "nombre de coups " + str (nb_coup))
    else :
        coup.config (text = "gagné")
    
    jeu.config (text = m)
    
b.config (command = fonction_jouer)

# root
root.mainloop ()

File: girafe.tex, line 26


import pygame
pygame.init ()    
image  = pygame.image.load ("girage.jpg")
sizeim = image.get_size ()
size   = (sizeim[0]*3, sizeim[1])
screen = pygame.display.set_mode (size)
screen.blit (image, (0,0))
pygame.display.flip () 

File: girafe.tex, line 40


def attendre_clic (screen,x,y):
    while True:
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONUP :
                return None

File: girafe.tex, line 55


import time
time.sleep (0.1)

File: girafe.tex, line 65


son = pygame.mixer.Sound ("bomb.wav")
son.play ()

File: girafe.tex, line 70


son = pygame.mixer.Sound ("bomb.wav")
son.play ()
son = pygame.mixer.Sound ("bomb.wav")
son.play ()

File: girafe.tex, line 79


font = pygame.font.Font ("freesansbold.ttf", 15) 
text = font.render ("message en blanc à la position 100,100", True, (255,255,255))
screen.blit(text, (100,100)) 
pygame.display.flip ()

File: girafe.tex, line 90


def attendre_touche () :
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONUP : return "clic"
        elif event.type == pygame.KEYDOWN : 
            if event.key == 275 : return "right"
            elif event.key == 276 : return "left"
            elif event.key == 273 : return "up"
            elif event.key == 274 : return "down"
            elif event.key == 27 : return "quit"
            else :
                pass
                #print "key ", event.key # on imprime quand on ne connaît pas le code des touches
        else :
            #print event
            pass
    return "" 

jeu avec des girafes

# coding: latin-1
import pygame
import time

def attendre_touche () :
    """cette fonction retourne différente valeur selon la touche pressée :
       - right : pour la flèche droite
       - gauche : pour la flèche gauche
       - up : pour la flèche haut
       - down : pour la flèche bas
       - quit : pour la touche ESC ou ECHAP
       - '' : chaîne vide pour aucune touche pressée
    """
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONUP : return "clic"
        elif event.type == pygame.KEYDOWN : 
            if event.key == 275 : return "right"
            elif event.key == 276 : return "left"
            elif event.key == 273 : return "up"
            elif event.key == 274 : return "down"
            elif event.key == 27 : return "quit"
            else :
                pass
                #print "key ", event.key
        else :
            #print event
            pass
    return ""
       
       
class ImagePosition :
    """chaque image présente sur le disque dur doit être chargée en
    mémoire (self.image), cette image est affichée à l'écran (self.screen),
    à une position donnée (self.pos),
    si cette image est en fait un motif sur fond blanc, on peut préciser
    à l'ordinateur que ce fond blanc doit laisser apparaître le fond de l'écran
    """
    def __init__ (self, image, pos, screen, transparent = False) :
        """initialisation
           - image : nom d'image
           - pos : position ou afficher l'image
           - screen : variable modélisant l'écran
           - transparent : l'image est-elle un motif dont le fond blanc
                           doit être transparent ?
        """
        self.image  = pygame.image.load (image)
        self.x      = pos [0]
        self.y      = pos [1]
        self.screen = screen
        if transparent : 
            # on précise ici que la couleur blanche (255,255,255)
            # doit être transparent
            self.image.set_colorkey ((255,255,255))
        
    def display (self, transparent = False) :
        """affiche l'image à une position donnée sur l'écran"""
        screen.blit (self.image, (self.x, self.y))
        
def affiche (images) :
    """affiche une liste d'image dans l'ordre dans lequel elles
    apparaissent dans la liste"""
    white  = (255,255,255)
    images [0].screen.fill (white) # met tout en blanc avant de dessiner les images
    for i in images :
        i.display ()
        
def deplacer_avion (images, avion, explosion, sounds, limitx) :
    """jeu, sans pression d'aucun touche, l'avion se déplace 
    vers les deux girafes et fait tout exploser, on peut ralentir
    l'approche de l'avion en :
        - pressant les touches de directions
        - en frappant sans s'arrêter et alternativement les touches gauche droite
    """
    pair = 0   # pair : il faut presser la flèche gauche, impair, flèche droite
    tour = 0   # compte le nombre de tour d'attente, sert à réduire 
               # l'impact des touches pressées par le joueur
    
    # séquence de trois instructions affichant le jeu
    affiche (images)    # on affiche le ciel et les girafes
    avion.display ()    # on affiche l'avion
    pygame.display.flip ()  # on rafraîchit l'écran
    
    # on regarde si une touche a été pressée
    t = attendre_touche ()  
    
    # pour afficher le score
    font = pygame.font.Font ("freesansbold.ttf", 15)    
    
    # le jeu s'arrête lorsqu'on presse la touche ECHAP ou si l'avion
    # touche les girafes
    while t != "quit" and avion.x < limitx :
    
        # on compte le nombre de tours
        tour += 1    
        # en fonction de ce nombre de tour, on détermine l'impact d'une 
        # séquence gauche droite
        dx    = max ((400 - tour) / 100, 1)
        
        # si une touche a été pressée, alors :
        if t == "left" : # flèche gauche
            avion.x -= 1
            if pair % 2 == 0 : 
                avion.x -= dx
                pair += 1
                
        elif t == "right" :  # flèche droite
            avion.x += 1
            if pair % 2 == 1 :
                avion.x -= dx
                pair += 1
                
        elif t == "up" :   # flèche haut
            avion.y -= 1
            
        elif t == "down" : # flèche bas
            avion.y += 1
            
            
        # quelque soit la touche pressée, on actualise le jeu
        # c'est la même séquence de trois touches qu'au début de la fonction
        affiche (images)
        avion.display ()
        
        # on affiche le score également à l'écran
        text = font.render ("score " + str (avion.y), True,(255,255,255))
    
        screen.blit(text, (100,100)) 
            
        pygame.display.flip ()
        
        # le programme attend 50 millisecondes avant de continuer
        time.sleep (0.05)
        
        # on déplace l'avion de force
        avion.x += 2
        avion.y += 1
        
        # on regarde si une touche a été pressée
        t = attendre_touche ()
        
    # on est sorti de la boucle : c'est l'explosion
    # on affiche l'image et on rafraîchit l'écran
    explosion.display ()
    pygame.display.flip ()
    
    # on joue quelques sons
    for i in range (0, len (sounds)) :
        sounds [i].play ()
        time.sleep (1.0*i)  # on attend un peu avant de passer au son suivant
                            # il est possible de ne pas attendre et de tous les 
                            # lancer en même temps
                            
    # on rejoue les sons d'explosion 2 fois séparées de 2 secondes
    for i in range (0, 2) :
        sounds [0].play ()
        sounds [1].play ()
        time.sleep (2.0)

    # on affiche le score : plus l'avion descend, meilleur on est
    print "score ", avion.y
    
    # on affiche le score également à l'écran
    text = font.render ("score " + str (avion.y), True,(255,255,255))
    
    screen.blit(text, (100,100)) 
    pygame.display.flip ()
        
    # on attend la pression de la touche ECHAP avant de quitter le programme
    while t != "quit" :
        t = attendre_touche ()
        

if __name__ == "__main__" :
    
    # initialisation du module pygame
    pygame.init ()

    # on récupère la taille de l'image de la girafe
    sizeim = pygame.image.load("girafe.jpg").get_size ()
    
    # on définit la taille de l'écran comme 3 fois plus large que celle de la girafe
    size   = ( sizeim [0] * 3, sizeim [1])
    screen = pygame.display.set_mode (size)
    
    # on définit l'image de l'avion
    avion       = ImagePosition ("avion.PNG", (0,0), screen, True)
    
    # on définit l'image de l'explosion
    explosion   = ImagePosition ("explosion.jpg", (0,0), screen)
    
    # on estime la limite au delà de laquelle l'avion explose
    limitx      = size [0] - sizeim [0] + sizeim [0] / 3 - avion.image.get_size () [0]
        
    # on définit les sons qui doivent être joués à la fin du jeu
    soundname   = ["bomb.wav", "explosion.wav", "explosion2.wav", "missile.wav", "sheep.wav"]
    sounds = []
    for s in soundname :
        try :
            # exception au cas où le son ne pourrait pas être lu
            sounds.append ( pygame.mixer.Sound (s) )
        except Exception, e :
            print "impossible de charger ", s
            print e

    # on construit la liste des images qui doivent être affichées à chaque fois
    images = []
    images.append ( ImagePosition ("ciel.jpg", (0,0), screen) )
    images.append ( ImagePosition ("girafe.jpg", (size [0] - sizeim [0], 0), screen) )
    
    # on joue
    deplacer_avion (images, avion, explosion, sounds, limitx)
    

manipulation de données dans une table

#coding:utf8
"""
@file
@brief  Contains TableFormulaCore.
"""
import copy, os, os.path, sys, datetime, random, math, numpy, locale, codecs, json

from .. import HalLOG, fLOG, str_to_datetime, EXf, EXs, EXw, EXxw, open_excel
from ..database.database_main import Database
fileprint = HalLOG



class TableFormulaCore :
    """
    
    .. requires numpy
    
    This class aims at representating a table, it provides 
    some "SQL like" functionalities such groupby or innerjoin, select, where...
    
    The class provides an easy to go through the row table by converting each row
    in a dictionary { column_name: value } on the run, Example:
    
    @code
    tbl = TableFormulaCore ( ... )
    newtbl = tbl.filter ( lambda v : v["criteria"] == 5 )
    @endcode
    
    see op __init__ for others ways to create a table.
    
    @var    header      list of column names
    @var    values      list of rows (each row contains as many value as the number of columns)
    @var    index       dictionary { column name : position }, changing ``header`` means also changing ``header``.
    
    Example:
    @code
    TableFormula = TableFormulaCore
    
    table = TableFormula ("name d_a d_b d_c#A 1 2 3#A 1.1 2.1 3.1#B 3 4 5".replace(" ", "\t").replace("#","\n"))
    print (table)
    print ("one value 0,1:", table[0,1])


    print ("---------")
    dist = table.get_distinct_values("name")
    for k in sorted(dist) : print ("*%d : %s"%(int(dist[k]),k))
        
    print ("---------")
    table.add_column ( "has_A", lambda v : 1. if "A" in v["name"] else 0. )
    print (table)

    x = 1./3
    print ("------------- smoothing", x)
    table.add_column_smooth("has_A_smooth", lambda v : v["has_A"], [ -1,0,1], [x,x,x] )
    print (table)
        
    print ("--------- filter")
    fil = table.filter ( lambda v : v["d_b"] == 2)
    print (fil)

    print ("--------- random")
    rnd = table.random( 5)
    print (rnd)

    print ("--------- random unique")
    rnd = table.random( 1, True)
    print (rnd)

    print ("--------- filter quantile")
    fil = table.filter_quantile ( lambda v : v["d_b"], 0, 0.4 )
    print (fil)

    print ("--------- aggregate_column")
    total = table.aggregate (lambda v : v["d_c"])
    print (total)
        
    print ("--------- sort")
    table.sort (lambda v: v["d_b"] + v["d_c"] )
    print (table)
        
    print ("--------- union")
    union = table.union (table)
    print (union)
        
    print ("--------- group sum")
    group = table.groupby ( lambda v: v["name"],
                            [ lambda v: v["d_a"],
                              lambda v: v["d_b"] ],
                            [ "name", "sum_d_a", "sum_d_b"] )
    print (group)
      
    print ("--------- group max")
    groupmax = table.groupby ( lambda v: v["name"],
                            [ lambda v: v["d_a"],
                              lambda v: v["d_b"] ],
                            [ "name", "max_d_a", "max_d_b"],
                            [ max, max ] )
    print (groupmax)
    
    print ("--------- group sum with weights")
    group = table.groupby ( lambda v: v["name"],
                            [ lambda v: v["d_a"] ],
                            [ "name", "weight", "sum_d_a"],
                            [ lambda vec,w :  sum(vec) / w ],
                            lambda v : v ["d_b"])

    print ("--------- innerjoin")
    innerjoin = table.innerjoin (group, lambda v : v["name"], 
                                        lambda v : v["name"], "group" )
    print (innerjoin)

    
    print ("------------- extraction")
    ext = table.extract_columns(["name", "d_a"] )
    print (ext)
    
    print ("------------- remove")
    ext = table.remove_columns(["d_a"] )
    print (ext)
    
    print ("------------- todict")
    d = table.todict( lambda v: v["name"], lambda v: v["d_b"], True)
    print (d)
    
    print ("------------- select")
    d = table.select( lambda v: (v["name"], v["d_b"]))
    print (list(d))
    
    print ("------------- use of an index")
    table.create_index( lambda v : (v["name"], v["d_a"]) )
    row = table.get ( ('A', 1.1) )
    print (row)
    value = table.get ( ('A', 1.1), 2 )
    print (value)
    
    print ("------------- multiply_column_by_row_instance ")
    table = TableFormula ("name d_a d_b d_c#A 1 2 3#A 1.1 2.1 3.1#B 3 4 5".replace(" ", "\t").replace("#","\n"))
    table.add_column ("key_add", lambda v:"unique")
    print (table)
    mul = table.multiply_column_by_row_instance ( 
                        lambda v: v["key_add"],
                        lambda v: v["name"])
    print (mul)
 
    if os.path.exists ("BNP.PA.txt") :
        print ("--------------- financial stock")
        table = TableFormula ("BNP.PA.txt", sep=",")
        table.sort( lambda v : v["Date"] )
        print (table[:10])
        
    print ("--------------- groupby_implicit")
    table = TableFormula ("key_name sum_a len_b avg_c#A 1 2 3#A 1.1 2.1 3.1#B 3 4 5".replace(" ", "\t").replace("#","\n"))
    print (table)
    gr = table.groupby_implicit ( lambda v : v ["key_name"] )
    print (gr)

    print ("--------------- covariance")
    values = [ random.random() for i in range(0,100) ]
    values = [ [ x, x + random.random()/2 ] for x in values ]
    tbl = TableFormula ( ["x", "y"], values).values_to_float()
    cov = tbl.covariance ()
    print (cov)
    
    print ("--------------- histogram")
    hist = tbl.histogram (lambda v : (v["x"],1), 10)
    print (hist)

    print ("--------------- histogram")
    hist = tbl.values_to_float().histograms (["x", "y"], 10)
    print (hist)

    print ("--------------- unions of columns")
    hist = tbl.values_to_float().union_columns(["x", "y"])
    print (hist)
    
    
    @endcode
    """
    
    def add_header_if_not_present(filename, header, encoding = None, logFunction = fileprint) :
        """the function checks if the first line contains the column in header
        otherwise, it modifies the file and add them on the first line
        @param      filename        filename
        @param      header          list of column name (all strings)
        @param      encoding        encoding
        @param      logFunction     use this function to log information about what is happening
        """
        if encoding == None :
            with open(filename, "r") as f : firstline = f.readline().strip("\n\r ")
            su = sum ( map (lambda _ : 1 if _ in header else 0, firstline.split("\t") ) )
            if su < len(header)/2.0 :
                fileprint ("add_header_if_not_present: adding header (%f<%f)"  % (su, len(header)/2) + str(header) + " to " + filename + " firstline " + firstline)
                with open(filename, "r") as f : text = f.read()
                text = "\t".join(header) + "\n" + text
                fileprint ("add_header_if_not_present: writing")
                with open(filename,"w") as f : f.write(text)        
                fileprint ("add_header_if_not_present: complete")
        else :
            with open(filename, "r", encoding = encoding) as f : firstline = f.readline().strip("\n\r ")
            su = sum ( map (lambda _ : 1 if _ in header else 0, firstline.split("\t") ) )
            if su < len(header)/2.0 :
                fileprint ("add_header_if_not_present: adding header (%f<%f)"  % (su, len(header)/2) + str(header) + " to " + filename + " firstline " + firstline)
                with open(filename, "r", encoding = encoding) as f : text = f.read()
                text = "\t".join(header) + "\n" + text
                fileprint ("add_header_if_not_present: writing")
                with open(filename,"w", encoding=encoding) as f : f.write(text)        
                fileprint ("add_header_if_not_present: complete")
    add_header_if_not_present = staticmethod(add_header_if_not_present)
    
    def random_split_file (filename, outfileprefix, nb, has_header = True, encoding = None, logFunction = fileprint) :
        """
        split a file in nb buckets by random (lines are sent to a random file as they come)
        @param      filename        filename to split
        @param      nb              number of buckets
        @param      outfileprefix   output files will start with outfileprefix + '%04d.txt' % i
        @param      encoding        encoding
        @param      has_header      the header will be replicated in each created file
        @param      logFunction     to display information
        @return                     list of created files
        """
        firstline = None
        if has_header :
            if encoding == None :
                with open(filename, "r") as f : firstline = f.readline().strip("\n\r ")
            else :
                with open(filename, "r", encoding = encoding) as f : firstline = f.readline().strip("\n\r ")
        
            fileprint ("random_split_file: file %s has header %s" % (filename, firstline))
        
        fileprint ("random_split_file: split %s in %d parts" % (filename, nb))
        fileName = [ outfileprefix + (".%04d.txt" % n) for n in range(0,nb) ]
        nbline   = 0
        
        if encoding == None :
            filesP = [ open(_, "w") for _ in fileName ]
            if firstline != None :
                for _ in filesP : _.write(firstline + "\n")
            with open(filename, "r") as f : 
                line = f.readline()
                if firstline != None : line = f.readline()
                while line != None and len(line) > 0 :
                    h = random.randint(0,nb-1)
                    filesP[h].write (line)
                    line = f.readline()
                    nbline += 1
                    if nbline % 1000000 == 0 : fileprint ("random_split_file: processed %d lines" % nbline)
        else :
            filesP = [ open(_, "w", encoding = encoding) for _ in fileName ]
            if firstline != None :
                for _ in filesP : _.write(firstline + "\n")
            with open(filename, "r", encoding = encoding) as f : 
                line = f.readline()
                if firstline != None : line = f.readline()
                while line != None and len(line) > 0 :
                    h = random.randint(0,nb-1)
                    filesP[h].write (line)
                    line = f.readline()
                    nbline += 1
                    if nbline % 1000000 == 0 : fileprint ("random_split_file: processed %d lines" % nbline)
                
        for _ in filesP : _.close()
        fileprint ("random_split_file: end")
        return fileName
    random_split_file = staticmethod(random_split_file)
        
    def ratio (x,y) : 
        """
        return a ratio between two real values or an empty string if the denominateur is null
        @return   a real of an empty string
        """
        return x*1.0/y if y != 0 else (0 if x == 0 else "")
    ratio = staticmethod(ratio)
    
    def bootstrap (values, function, nbdraws = -1, alpha = 0.05) :
        """
        return a confidence interval for a statistics
        @param      values      values
        @param      function    produces the statistics over a random set of observations chosen in values
        @param      nbdraws     number of draws, if it is equal to -1, is equal to len(values)
        @param      alpha       confidence level
        @return                 average, min, lower bound, higher bound, max
        """
        stat = [ ]
        N    = len(values)-1
        if nbdraws == -1 : nbdraws = len(values)
        for i in range(nbdraws) :
            randset = [ values[ random.randint(0,N) ] for i in range(N+1) ]
            s       = function(randset)
            stat.append(s)
        stat.sort()
        lv = len(stat)
        alpha = alpha/2
        i1 = int(lv * alpha + 0.5)
        i2 = int(lv * (1-alpha) + 0.5)
        i2 = min (i2, len(stat)-1)
        av = sum(stat) / len(stat)
        return av, min(stat), stat[i1], stat[i2], max(stat)
    bootstrap = staticmethod(bootstrap)
    
    def correlation_bicolumn (values, deviations = False, noCenter = False) :
        """
        assume values is a matrix with two columns
        @param          values      2 column matrix
        @param          deviations  if True, returns cor, sigma1, sigma2
        @param          noCenter    if True, do not remove the average before computing the covariance,
                                    it means we assume variables are already centered
        @return                     correlation factor or correlation, sigma1, sigma2 if deviations is True
        """
        if len(values) <= 1 :
            raise ValueError("expecting more than one observation, not %d" % len(values))
            
        mx = 0.
        my = 0.
        vx = 0.
        vy = 0.
        co = 0.
        nb = 0.
        for a,b in values :
            nb += 1
            mx += a
            my += b
            vx += a**2
            vy += b**2
            co += a*b
        mx /= nb
        my /= nb
        vx /= nb
        vy /= nb
        co /= nb
        if not noCenter :
            vx -= mx**2
            vy -= my**2
            co -= mx*my
        vx  = vx**0.5
        vy  = vy**0.5
        v = vx*vy
        if v != 0 : co /= v
        if deviations : return co,vx,vy 
        else : return co
    correlation_bicolumn = staticmethod(correlation_bicolumn)
    
    def _private_getclass (self) :
        """
        the class often creates another class of the same type,
        this function returns the class object
        """
        return self.__class__
    
    def __init__ (self, file, 
                        numeric_column  = [], 
                        sep             = "\t", 
                        encoding        = None,
                        read_n_lines    = -1,
                        sheet           = 0,
                        **options) :
        """
        constructor, it can either take a filename, an object TableFormulaCore,
        a list of columns and values.
        
        @param      file                filename or a list of column names or a dictionary,
                                        file can also be a `pandas DataFrame <http://pandas.pydata.org/pandas-docs/dev/dsintro.html#dataframe>`_.
        @param      numeric_column      depends on file types (see below examples)
        @param      sep                 column separator if file is a filename
        @param      read_n_lines        read the first n lines (or all if it is -1)
        @param      sheet               in case the file is an Excel file, this parameter precises the sheet number or name
        @param      suffix_nb           if True, adds an integer to the column name if it is a duplicate
        
        Example:
        @code
        table = TableFormula ("name d_a d_b d_c#A 1 2 3#A 1.1 2.1 3.1#B 3 4 5"
                             .replace(" ", "\\t").replace("#","\\n"))
        @endcode
        or
        @code
        table = TableFormula ("file.txt", ["nb"])
        @endcode
        or
        @code
        table  = TableFormula (["date", "Y", "Y2", "xl"], values)
        @endcode
        or
        @code
        data = [ { "one":1, "two":2 }, {"two":2.1, "three":3 } ]
        table = TableFormula (data)
        @endcode
        or
        @code
        data = { 1:{ "one":2.3, "two":2.2 }, 2:{"one":2.1, "two":3 }
        table = TableFormula ("__byrow__", data)
        @endcode
        or
        @code
        table = TableFormula ( numpy.matrix ( ... ))
        @endcode
        or
        @code
        table = TableFormula ( numpy.array ( ... ))
        @endcode
        
        @warning In this second case, rows and header are not copied.
        
        """
        if isinstance(file, str) :
            if os.path.exists (file) : 
                self._read_file (file, numeric_column, sep, encoding, read_n_lines, sheet = sheet)
            elif file == "__byrow__" and isinstance (numeric_column, dict) :
                self._fill_by_row(numeric_column)
            else :
                lines = file.split("\n")
                if len(lines) == 1 :
                    raise FileNotFoundError("a file was probably expected but was not found: " + file)
                self._readlines(lines, numeric_column, sep)
                
        elif isinstance(file, list) :
            if len(file) == 0 :
                raise ValueError("empty data and columns are not allowed")
                
            if isinstance(file[0], dict) :
                self.index = { }
                self.values = []
                for row in file :
                    for k,v in row.items() :
                        if k not in self.index : 
                            self.index[k] = len(self.index)
                    
                # we sort the labels to avoid instabilities
                labels = [ k for k,v in self.index.items() ]
                labels.sort()
                self.index = { }
                for l in labels : self.index[l] = len(self.index)
                            
                for row in file :
                    line = [ None for k in self.index ]
                    for k,v in row.items() :
                        line [ self.index[k] ] = v
                    self.values.append(line)
                    
                self.header = [ None for k in self.index ]
                for k,v in self.index.items () :
                    self.header [ v ] = k
                    
                n = len(self.index)
                for row in self.values :
                    while len(row) < n : row.append(None)
                
            elif isinstance (numeric_column, numpy.matrix) :
                self.header = file
                self.index = { }
                for (i,h) in enumerate (self.header) :
                    self.index [h] = i
                self.values = [ [ float(numeric_column[i,j]) \
                                        for j in range(numeric_column.shape[1]) ] \
                                        for i in range(numeric_column.shape[0]) ] 
            elif isinstance (numeric_column, numpy.ndarray) :
                self.header = file
                self.index = { }
                for (i,h) in enumerate (self.header) :
                    self.index [h] = i
                self.values = [ [ float(numeric_column[i,j]) \
                                        for j in range(numeric_column.shape[1]) ] \
                                        for i in range(numeric_column.shape[0]) ] 
            elif isinstance(file[0], list) :
                if len(file) == 1 :
                    self.header = file[0]
                    self.values = file[1:] + numeric_column
                    self.index = { }
                    for (i,h) in enumerate (self.header) :
                        self.index [h] = i
                else :
                    self.header = file[0]
                    self.values = file[1:]
                    self.index = { }
                    for (i,h) in enumerate (self.header) :
                        self.index [h] = i
            elif isinstance (file[0], str) :
                self.header = file
                self.values = numeric_column
                self.index = { }
                for (i,h) in enumerate (self.header) :
                    self.index [h] = i
                    
            else :
                raise RuntimeError ("this case should not happen " + str(type(file[0])))
                
        elif isinstance( file, numpy.matrix) :
            self.header = [ "c%d" % d for d in range(file.shape[1]) ]
            self.index = { }
            for (i,h) in enumerate (self.header) :
                self.index [h] = i
            self.values = [ [ float(file[i,j]) \
                                    for j in range(file.shape[1]) ] \
                                    for i in range(file.shape[0]) ] 
            
        elif isinstance( file, numpy.ndarray) :
            self.header = [ "c%d" % d for d in range(file.shape[1]) ]
            self.index = { }
            for (i,h) in enumerate (self.header) :
                self.index [h] = i
            self.values = [ [ float(file[i,j]) \
                                    for j in range(file.shape[1]) ] \
                                    for i in range(file.shape[0]) ] 
            
        else :
            try :
                import pandas 
            except ImportError :
                raise TypeError("file has an unexpected type: " + str(type(file)))
                    
            if isinstance (file, pandas.DataFrame) :
                def convert(x) : 
                    return None if isinstance(x, float) and numpy.isnan (x) else x
                df = file
                self.header = [ _ for _ in df.columns ]
                hi = 'index'
                while hi in self.header : hi += "_"
                self.header.insert(0,hi)
                self.values = []
                for i,row in enumerate(df.values) :
                    row = [ df.index[i] ] + [ convert(x) for x in row ]
                    self.values.append(row)
                    
                self.index = { }
                for (i,h) in enumerate (self.header) :
                    self.index [h] = i
                    
            else :
                raise TypeError("file has an unexpected type: " + str(type(file)))
            
        unique = { }
        for i,c in enumerate(self.header) : 
            if c in unique : 
                if options.get("suffix_nb",False) :
                    c = "%s_%d" % (c,i)
                    self.header [ i ] = c
                else :
                    raise KeyError("column " + c + " already exists in %s" % str(self.header))
            unique [c] = True
            
    def __add__ (self, other) :
        """do an addition, add values if types are matching
        @param   other      matrix or float or string
        @return             new matrix, keep the header of the first matrix
        """
        if len(self) != len(other) : raise ValueError("both matrices should have the same number of rows")
        if len(self.header) != len(other.header) : raise ValueError("both matrices should have the same number of columns")
        values = []
        for row,rowo in zip (self.values, other.values) :
            r = []
            for a,b in zip(row,rowo) :
                if type(a) == type(b) :
                    x = a + b
                else :
                    x = None
                r.append(x)
            values.append(r)
        return self._private_getclass() (self.header, values )
        
    def __mul__ (self, other) :
        """do a multiplication (by a number)
        @param   other      matrix or float or string
        @return             new matrix, keep the header of the first matrix
        """
        if not isinstance (other, float) and not isinstance (other, int) :
            raise TypeError("other should be a number")
        values = []
        for row in self.values :
            r = []
            for a in row :
                if a != None : x = a * other
                else : x = None
                r.append(x)
            values.append(r)
        return self._private_getclass() (self.header, values )
        
    def multiplication_term_term (self, other) :
        """do a multiplication term by term (similar to an addition), 
        add values if types are matching
        @param   other      matrix or float or string
        @return             new matrix, keep the header of the first matrix
        """
        if len(self) != len(other) : raise ValueError("both matrices should have the same number of rows")
        if len(self.header) != len(other.header) : raise ValueError("both matrices should have the same number of columns")
        values = []
        for row,rowo in zip (self.values, other.values) :
            r = []
            for a,b in zip(row,rowo) :
                if type(a) == type(b) and not isinstance (a, str) :
                    x = a * b
                else :
                    x = None
                r.append(x)
            values.append(r)
        return self._private_getclass() (self.header, values )
        
    def replicate (self, times) :
        """replicates all rows a given number of times
        @param   times      number of multiplication
        @return             new matrix, keep the header of the first matrix
        """
        values = []
        for i in range (0,times) :
            values.extend (copy.copy(self.values))
        return self._private_getclass() (self.header, values )

    @property 
    def size(self) :
        """returns the size (nb rows, nb columns)
        """
        return len(self), len(self.header)
        
    @property
    def shape(self):
        """returns the size (nb rows, nb columns)
        """
        return self.size
        
    def _fill_by_row(self, values) :
        """
        fill the table
        @param      values      dictionary { <int_row_index>: { <column name>: value} }
        """
        mx = max (values.keys())+1
        self.index  = { }
        self.header = []
        for k,v in values.items () :
            for col in v :
                if col not in self.index :
                    self.index[col] = len(self.index)
                    self.header.append (col)
        self.values = [ [ None for h in self.header ] for k in range(mx) ]
        for k,v in values.items () :
            for col,to in v.items() :
                self.values [ k ] [ self.index [col] ] = to

    def __getitem__ (self, irow) :
        """operator [], accepts slices
        @param      irow        integer, tuple, slice or list
        @return                 depends on irow
                                    - int --> a table with one row
                                    - slice --> a table with several rows
                                    - list --> a table with the selected rows
                                    - tuple --> a value
        """
        if isinstance( irow, int ) :
            return self._private_getclass() (self.header, [self.values[irow] ] )
        elif isinstance( irow, slice ) :
            return self._private_getclass() ( self.header,
                    [self.values[ii] for ii in range(*irow.indices(len(self)))])
        elif isinstance( irow, list ) :
            return self._private_getclass() ( self.header, [self.values[ii] for ii in irow])
        elif isinstance (irow, tuple) :
            if isinstance(irow[1], str) :
                row = self.values[irow[0]]
                v = self._interpret_row(row)
                return v [irow[1]]
            else :
                return self.values[irow[0]][irow[1]]
        else:
            raise TypeError ("Invalid argument type: " + str(type(irow)))
           
    def __setitem__ (self, irow, value) :
        """operator [], just accepts tuple (to change a value)
        @param      irow        2-uple
        @param      value       new value
        """
        if isinstance (irow, tuple) :
            if isinstance(irow[1], str) :
                row = self.values[irow[0]]
                v = self._interpret_row(row)
                v [irow[1]] = value
            else :
                self.values[irow[0]][irow[1]] = value
        else:
            raise TypeError ("Invalid argument type (only tuple accepted): " + str(type(irow)))
           
    def __len__ (self) :
        """returns the number of rows
        """
        return len(self.values)
            
    def __copy__ (self) :
        """operator copy
        """
        return self._private_getclass() (self.header, self.values)
        
    def __deepcopy__ (self, memo) :
        """operator deepcopy
        """
        return self._private_getclass() (copy.deepcopy (self.header, memo),
                                         copy.deepcopy(self.values, memo))
    
    def copy(self) :
        """call copy.deepcopy(self)
        """
        return copy.deepcopy(self)
        
    def delta (self, other) :
        """
        returns a list of differences between self and others
        
        @param      other       TableFormula
        @return                 list of differences (first one)
        """
        if other == None : return False
        if not isinstance (other, TableFormulaCore) : 
            raise TypeError("other is not a table: " + str(type(other)))
        if len(self.header) != len(other.header) : 
            return [ "different number of columns" ]
        for a,b in zip (self.header, other.header) :
            if a != b : return [ "different columns"]
        if len(self.values) != len(other.values) : 
            return ["different number of rows" ]
        line = 0
        for r,s in zip (self.values, other.values) :
            if len(r) != len(s) : 
                return ["different number of values on row %d" % line ]
            col = 0
            for a,b in zip (r,s) :
                if a != b : 
                    return ["different value on cell %d,%d: %s!=%s (type %s, %s)" % (line, col, a,b, str(type(a)), str(type(b))) ]
                col += 1
            line += 1
        return []   
        
    def __eq__ (self, other) :
        """
        check if two tables are equal by value
        @param      other       other table
        @return                 boolean
        """
        if other == None : 
            return False
        if not isinstance (other, TableFormulaCore) : 
            return False
        if len(self.header) != len(other.header) : 
            return False
        for a,b in zip (self.header, other.header) :
            if a != b : 
                return False
        if len(self.values) != len(other.values) : 
            return False
        for r,s in zip (self.values, other.values) :
            if len(r) != len(s) : 
                return False
            for a,b in zip (r,s) :
                if a != b : 
                    return False
        return True
        
    def __str__ (self) :
        """
        convert the table into a string
        @return     string
        """
        rows = [ "\t".join (self.header) ]
        for row in self.values :
            s = "\t".join ( [ str(_) for _ in row ] )
            rows.append (s)
        return "\n".join(rows)
        
    def __html__ (self, class_table = None, class_td = None, class_tr = None, class_th = None) :
        """
        convert the table into a html string
        
        @param  class_table     adds a class to the tag ``table`` (None for none)
        @param  class_td        adds a class to the tag ``td`` (None for none)
        @param  class_tr        adds a class to the tag ``tr`` (None for none)
        @param  class_th        adds a class to the tag ``th`` (None for none)
        """
        clta = ' class="%s"' % class_table  if class_table != None else ""
        cltr = ' class="%s"' % class_tr     if class_tr != None else ""
        cltd = ' class="%s"' % class_td     if class_td != None else ""
        clth = ' class="%s"' % class_th     if class_th != None else ""
        
        rows= [ "<table%s>" % clta ]
        rows.append (  ("<tr%s><th%s>" % (cltr, clth)) + ("</th><th%s>" % clth).join (self.header) + "</th></tr>" )
        septd = "</td><td%s>" % cltd
        strtd = "<tr%s><td%s>" % (cltr, cltd)
        for row in self.values :
            s = septd.join ( [ str(_) for _ in row ] )
            rows.append ( strtd + s + "</td></tr>")
        rows.append ("</table>")
        rows.append("")
        return "\n".join(rows)
        
    def __rst__ (self, add_line = True):
        """
        convert the table into rst format
        @code
        +------------------------+------------+----------+----------+
        | Header row, column 1   | Header 2   | Header 3 | Header 4 |
        | (header rows optional) |            |          |          |
        +========================+============+==========+==========+
        | body row 1, column 1   | column 2   | column 3 | column 4 |
        +------------------------+------------+----------+----------+
        | body row 2             | ...        | ...      |          |
        +------------------------+------------+----------+----------+        
        @endcode
        
        @param      add_line        add a line separator between each row
        """
        tbl     = self.values_to_str()
        length  = [ len(_) for _ in tbl.header ]
        for row in tbl.values :
            for i,v in enumerate(row) :
                length[i] = max ( length[i], len(v) )
        length = [ _+ 2 for _ in length ]
        line   = [ "-" * l for l in length ]
        lineb  = [ "=" * l for l in length ]
        sline  = "+%s+" % ("+".join(line))
        slineb = "+%s+" % ("+".join(lineb))
        res    = [ sline ]
        
        def complete(cool) :
            s,i = cool
            i -= 2
            if len(s) < i : s += " " * (i-len(s))
            return s
        
        res.append ( "| %s |" % " | ".join (map (complete, zip(tbl.header, length)) ) )
        res.append (slineb)
        res.extend ( [ "| %s |" % " | ".join ( map(complete, zip(row,length) )) for row in tbl.values ] )
        if add_line :
            t = len(res)
            for i in range(t-1,3,-1) : 
                res.insert(i, sline)
        res.append (sline)
        return "\n".join(res) + "\n"
        
    def strtype (self) :
        """displays the type of values (not the values)
        """
        rows = [ "\t".join (self.header) ]
        for row in self.values :
            s = "\t".join ( [ str(type(_)) for _ in row ] )
            rows.append (s)
        return "\n".join(rows)
        
    def _read_file (self, file, numeric_column, sep, encoding, read_n_lines, sheet = 0) :
        """
        private
        """
        ext = os.path.splitext(file)[-1].lower()
        if ext in [".xls", ".xlsx"] :
            lines = list( open_excel(file, sheet = sheet ))
            # removing empty column (assuming first row is the header)
            ind = [ i for i,n in enumerate(lines[0]) if len(n) > 0 ]
            if len(ind) < len(lines[0]) :
                lines = [  [ _[i] for i in ind  ] for _ in lines ]
        else :
            if sys.version_info.major >= 3 or encoding == None :
                if encoding == None : f = open (file,"r")
                else : f = open (file,"r", encoding = encoding)
            else :
                f = codecs.open (file, "r", encoding)
        
            if read_n_lines > 0 :
                lines = [ ]
                for line in f :
                    if len(lines) >= read_n_lines : break
                    lines.append(line)
            else :
                lines = f.readlines ()
                
            f.close()
            
        self._readlines(lines, numeric_column, sep)
        
    def change_header (self, new_header) :
        """
        change the column names
        @param      new_header      a list or a function which modifies the header
        
        Example:
        @code
        tbl.change_header ( lambda h : h if h != "column" else "new_name" )
        @endcode
        
        @warning Do not do that yourself, the class holds a dictionary up to date with the column index.
        
        """
        if isinstance (new_header, list) :
            self.header = new_header
            self.index = { }
            for (i,h) in enumerate (self.header) :
                self.index [h] = i
        else :
            he = [ new_header(h) for h in self.header ]
            self.change_header(he)
            
    def rename_column (self, old_name, new_name) :
        """
        rename a column
        @param      old_name    old name
        @param      new_name    new name
        """
        header = [ {old_name:new_name}.get(_,_) for _ in self.header ]
        self.change_header(header)
        
    def save (self, filename, sep = "\t", encoding = None, newline = "\n") :
        """
        saves the tables in a text file, first row is the column names
        @param      filename        filename
        @param      sep             column separator
        @param      encoding        encoding
        @param      newline         line separator
        """
        if sys.version_info.major >= 3 or encoding == None :
            if encoding == None :
                f = open(filename, "w", newline = newline)
            else :
                f = open(filename, "w", encoding = encoding, newline = newline)
        else :
            f = open( filename, "w", encoding = encoding)
            
        f.write (sep.join(self.header))
        f.write("\n")
        for row in self.values :
            f.write (sep.join( [ str(_) for _ in row ] ))
            f.write("\n")
        f.close()
        
    def _readlines(self, lines, numeric_column, sep) :
        """private"""
        if isinstance (lines[0], str) :
            lines = [ _.replace ("\ufeff", "").replace("\xef\xbb\xbf", "") \
                        .strip("\n\r ").split(sep) for _ in lines if len(_) > 0 ]
            self.header = lines[0]
            self.values = lines[1:]  
            self.index = { }
            for (i,h) in enumerate (self.header) :
                self.index [h] = i
        elif isinstance(lines[0], list) :
            self.header = lines[0]
            self.values = lines[1:]  
            self.index = { }
            for (i,h) in enumerate (self.header) :
                self.index [h] = i
        else :
            raise Exception("unexpected format: " + str(type(lines[0])))
            
        self._auto_conversion (numeric_column)
            
    def _auto_conversion (self, others_columns) :
        """
        private
        set up the column type based on the column name
        """
        for i,k in enumerate (self.header) :
            if k == "Date" :
                for row in self.values :
                    if isinstance(row[i], str) :
                        row[i] = datetime.datetime.strptime(row [i], '%Y-%m-%d')
                    elif isinstance(row[i], float) :
                        row[i] = datetime.datetime.utcfromtimestamp(row [i])
                    else :
                        raise Exception("unable to extract a date from type {0}".format(type(row[i])))
            elif k.startswith ("sum_") or k.startswith ("pos_") or \
                k.startswith ("avg_") or \
                k.startswith ("len_") or \
                k.startswith ("nb_") or \
                k.startswith ("max_") or \
                k.startswith ("min_") or \
               k.startswith ("d_") or k in others_columns or \
               k in ["Open","High","Low","Close","Volume","Adj Close"] or \
               k in ["distance", "nb", ] \
               :
                for row in self.values :
                    row[i] = float (row [i] )
            else :
                for row in self.values :
                    if isinstance(row[i],str) and row[i] == "None" :
                        row[i] = None
        
    def get_column_values (self, col) :
        """
        private
        returns all values for one column
        """
        i = self.index [col]
        return [ row [ i ] for row in self.values ]
    
    def get_distinct_values (self, col) :
        """private"""
        row = self.get_column_values (col)
        dis = { }
        for r in row : dis [r] = dis.get(r,0) + 1
        return dis
    
    def _interpret_row (self, row) :
        """private
        returns each row as a dictionary { column_name:value }
        """
        values = { }
        for a,b in zip(self.header, row) :
            values [a] = b
        return values
        
    def __iter__(self):
        """
        iterator on all rows, it returns a dictionary { column:value }
        @return     dictionary
        """
        for row in self.values :
            yield self._interpret_row(row)
        
    def add_column (self, colname, function, position = -1) :
        """
        add a column
        @param      colname     column name or columns name if it is a list or a tuple
        @param      function    function which will gives the values (or a list of functions, or a function which return a tuple)
        @param      position    where to insert the column, -1 for the end
        
        Example:
        @code
        table.add_column ( "has_A", lambda v : 1 if "A" in v["name"] else 0, 0 )
        
        table.add_column ( ("has_A", "has_B"), (lambda v : 1 if "A" in v["name"] else 0, 
                                                lambda v : 1 if "B" in v["name"] else 0 ))
                                                
        table.add_column ( ("has_A", "has_B"), (lambda v : (1 if "A" in v["name"] else 0, 1 if "B" in v["name"] else 0 ))
        @endcode
        """
        if isinstance(colname, str) :
            if position == -1 :
                self.index [colname] = len(self.index)
                for row in self.values :
                    v = self._interpret_row (row)
                    x = function (v)
                    row.append (x)
                self.header.append (colname)
                return self
            else :
                for row in self.values :
                    v = self._interpret_row (row)
                    x = function (v)
                    row.insert(position,x)
                self.header.insert (position, colname)
                self.index = { v:i for i,v in enumerate(self.header) }
                return self
                
        elif isinstance(function, list) :
            if len(colname) != len(function) :
                raise ValueError("unable to continue, colname and function do not have the same number of elements")
            if position == -1 : position = [-1] * len(colname)
            elif isinstance(position, int) : position = [position ] * len(colname)
            else :
                if len(position) != len(colname) :
                    raise RuntimeError("unable to continue, colname and position do not have the same number of elements")
            dec = 0
            for a,b,c in zip(colname, function, position):
                self.add_column(a, b, c + dec)
                dec += 1
        
        else :
            # we assume here, the function returns a tuple
            if not isinstance(position, int) : 
                raise TypeError("we expect an int for position for this case")
                
            if position == -1 :
                for row in self.values :
                    v = self._interpret_row (row)
                    x = function (v)
                    row.extend(x)
                self.header.extend(colname)
                
            else :
                for row in self.values :
                    v = self._interpret_row (row)
                    x = function (v)
                    for i,_ in enumerate(x) :
                        row.insert (position+i, _)
                for i,c in enumerate(colname) :
                    self.header.insert (position+i, c)

            self.index = { v:i for i,v in enumerate(self.header) }
        
    def add_column_index (self, colname = "index", start = 0) :
        """
        Example:
        @code
        table.add_column ( "index_row" )
        @endcode
        """
        self.index [colname] = len(self.index)
        for i,row in enumerate(self.values) :
            row.append (i + start)
        self.header.append (colname)
        return self
        
    def addc (self, colname, function, position = -1) :
        """
        @see me add_column
        """
        return self.add_column(colname, function, position)
        
    def add_column_recursive (self, colname, functionValue, functionAgg) :
        """
        Example:
        @code
        table.add_column_recursive ( lambda v : v ["norm_%s" % loi],
                        lambda li, v : li[-1] + v )
        @endcode
        """
        self.index [colname] = len(self.index)
        values = []
        for row in self.values :
            v = self._interpret_row (row)
            x = functionValue (v)
            y = functionAgg (values, x)
            row.append (y)
            values.append(y)
        self.header.append (colname)
        return self
        
    def add_column_recursive_row (self, colname, functionAgg) :
        """
        Example:
        @code
        table.add_column_recursive_row ("w_%s" % loi, 
                        lambda li, v : li[-1] + v ["norm_%s" % loi] \
                        if len(li)> 0 else v ["norm_%s" % loi] )
        @endcode
        """
        self.index [colname] = len(self.index)
        values = []
        for row in self.values :
            v = self._interpret_row (row)
            y = functionAgg (values, v)
            row.append (y)
            values.append(y)
        self.header.append (colname)
        return self
        
    def add_column_vector (self, colname, vector) :
        """
        add a column defined by vector (list of values for each row)
        
        @param      colname     column to add
        @param      vector      (list) list of values to add to each row
        @return                 self
        """
        if len(vector) != len(self) :
            raise ValueError("vector and table have different length")
        for vec,row in zip (vector, self.values) :
            row.append (vec)
        self.index [colname] = len(self.index)
        self.header.append (colname)
        return self
    
    def add_column_smooth (self, colname, function, position, weights) :
        """
        Example:
        @code
        x = 1./3
        table.add_column_smooth("has_A_smooth", lambda v : v["has_A"], [ -1,0,1], [x,x,x] )
        @endcode
        """
        if len(position) != len(weights) :
            raise ValueError("position and weights must have the same length")
        self.index [colname] = len(self.index)
        column = [ function ( self._interpret_row (row) ) for row in self.values ]
        tw     = sum(weights)
        couple = list(zip (position, weights))
        for p,row in enumerate (self.values) :
            sx = 0.
            sw = 0.
            ms = 0
            for i,w in couple :
                pi = p+i
                if 0 <= pi < len(self) :
                    sx += column[pi] * w
                    sw += w
                else :
                    ms += 1
                   
            if ms == 0 : row.append (sx)
            elif sw != 0 : row.append (sx * tw / sw)
            else : row.append(sx)
        self.header.append (colname)
        return self
            
    def aggregate_column (self, colname, aggregated_function = sum) :
        """
        Example:
        @code
        total = table.aggregate_column ("d_c", sum)
        @endcode
        """
        function = lambda v : v[colname]
        return self.aggregate (function, aggregated_function)
       
    def aggregate (self, function, aggregated_function = sum) :
        """
        Example:
        @code
        total = table.aggregate_column (lambda v : v["d_c"], len)
        @endcode
        """
        return aggregated_function ( 
                [ function ( self._interpret_row(row)) \
                      for row in self.values ] )

    def where (self, condition_function) :
        """@see me filter
        """
        return self.filter (condition_function)
        
    def filter (self, condition_function) :
        """
        Example:
        @code
        fil = table.filter ( lambda v : v["d_b"] == 2)
        @endcode
        
        @warning Rows are not copied.
        
        """
        newv = []
        for row in self.values :
            v = self._interpret_row (row)
            x = condition_function (v)
            if x : newv.append (row)
        final = self._private_getclass() (self.header,newv)
        return final
        
    def groupby_implicit (self,  functionKey, functionWeight = None, logging = None ) :
        """
        use prefix of a column name to know which function to use
        as an aggregated (sum, avg, len, key, none, max, min)
        Example:
        @code
        group = table.groupby_implicit ( lambda v: v["name"] )
        @endcode
        """
        def identical (col, v) : return v [col]
        def first (vec) : return vec[0]
        def avg (vec) : return TableFormulaCore.ratio (sum(vec), len(vec))
       
        functions       = [ ]
        labels          = [ "key"]
        functionsAgg    = [ ]
        keys            = { }
        for col in self.header :
            if col.startswith ("key") :
                values = self.select ( lambda v : (v [col], functionKey(v)) )
                dd = { }
                for v in values :
                    if v[1] not in dd : dd[v[1]] = {}
                    dd[v[1]] [ v[0]] = 1
                for k in dd : dd[k] = len(dd[k])
                keep = []
                for k,v in dd.items () :
                    if v > 1 : keep.append ( (k,v) )
               
                if len(keep) == 0 :
                    functions.append ( lambda v, col=col : identical (col, v) )
                    labels.append (col)
                    functionsAgg.append ( first )
                elif logging != None :
                    end = min (len(keep), 10)
                    mes = ",".join([str(_) for _ in keep[:end]])
                    logging ("removing column " + col + " no unique value : " + str(len(dd)) + ": " + mes)
            elif col.startswith ("sum") :
                    functions.append ( lambda v, col=col : identical (col, v) )
                    labels.append (col)
                    functionsAgg.append ( sum )
            elif col.startswith ("len") :
                    functions.append ( lambda v, col=col : 1 )
                    labels.append (col)
                    functionsAgg.append ( len )
            elif col.startswith ("min") :
                    functions.append ( lambda v, col=col : 1 )
                    labels.append (col)
                    functionsAgg.append ( min )
            elif col.startswith ("max") :
                    functions.append ( lambda v, col=col : 1 )
                    labels.append (col)
                    functionsAgg.append ( max )
            elif col.startswith ("avg") :
                    functions.append ( lambda v, col=col : identical (col, v) )
                    labels.append (col)
                    functionsAgg.append ( avg )
            elif col.startswith ("none") :
                pass
            else :
                raise RuntimeError("unable to aggregate column " + col)
               
        return self.groupby ( functionKey, functions, labels, functionsAgg, functionWeight)
               
    def groupby (self,  functionKey,
                        functionsValue,
                        columns = None,
                        functionsAgg = None,
                        functionWeight = None) :
        """
        Example:
        @code
        group = table.groupby ( lambda v: v["name"],
                                [ lambda v: v["d_a"],
                                  lambda v: v["d_b"] ],
                                [ "name", "sum_d_a", "sum_d_b"] )
        @endcode
        or
        @code
        groupmax = table.groupby ( lambda v: v["name"],
                                [ lambda v: v["d_a"],
                                  lambda v: v["d_b"] ],
                                [ "name", "max_d_a", "max_d_b"],
                                [ max, max ] )
        @endcode
        """
        if not isinstance (functionsValue, list) :
            functionsValue = [ functionsValue ]
        if functionsAgg == None :
            functionsAgg = [ sum for f in functionsValue ]
        if functionWeight == None :
            if columns != None and len(columns) != len(functionsValue) + 1 :
                raise Exception ("columns should have %d names not (%d)"% (len(functionsValue) + 1, len(columns)))
        else :
            if columns != None and len(columns) != len(functionsValue) + 2 :
                raise Exception ("columns should have %d names not (%d)"% (len(functionsValue) + 2, len(columns)))
        if columns != None and not isinstance(columns[0], str) :
            raise TypeError ("expecting type str not %s in columns" % (str(type(columns[0]))))
         
        hist = { }
       
        if functionWeight != None :
            histWeight = { }

            for row in self.values :
                v   = self._interpret_row (row)
                key = functionKey (v)
                w   = 1. if functionWeight == None else functionWeight (v)
               
                if key not in hist :
                    histWeight [key] = [ w ]
                    hist [ key ] = [ [f(v)*w] for f in functionsValue ]
                else :
                    histWeight [key].append (w)
                    h = hist [ key ]
                    for i,f in enumerate (functionsValue) :
                        h[i].append( f (v)*w )
                      
            for key in hist :
                h = hist[key]
                w = sum( histWeight [key] )
                for i in range(0, len(h)) :
                    h[i] = functionsAgg[i] (h[i], w)
               
            f = hist.items if sys.version_info.major >= 3 else hist.iteritems
            histValues = [ [k,sum(histWeight[k])] + v for k,v in f () ]
         
            if columns == None :
                columns = ["key", "weight"] + [ "val%d" % i for i,f in enumerate (functionsValue) ]
            ret = self._private_getclass() (columns, histValues)
            return ret       
        else :
            for row in self.values :
                v   = self._interpret_row (row)
                key = functionKey (v)
                if key not in hist :
                    hist [ key ] = [ [f(v)] for f in functionsValue ]
                else :
                    h = hist [ key ]
                    for i,f in enumerate (functionsValue) :
                        h[i].append( f (v) )
                      
            for key in hist :
                h = hist[key]
                for i in range(0, len(h)) :
                    h[i] = functionsAgg[i] (h[i])
               
            f = hist.items if sys.version_info.major >= 3 else hist.iteritems
            histValues = [ [k,] + v for k,v in f () ]
         
            if columns == None :
                columns = ["key"] + [ "val%d" % i for i,f in enumerate (functionsValue) ]
            ret = self._private_getclass() (columns, histValues)
        return ret
            
    def sort (self, functionValue, reverse = False) :
        """
        Example:
        @code
        table.sort (lambda v: v["d_b"] + v["d_c"] )
        @endcode
        """
        values = [ (functionValue ( self._interpret_row (row)),i) for i,row in enumerate(self.values) ]
        values.sort (reverse = reverse)
        self.values = [ self.values[_[1]] for _ in values ]
        return self
            
    def extract_columns (self, listColumns) :
        """
        extract some columns
        
        @param      listColumns     list of columns to remove or a function
                                    which returns True if the column has to be extracted
                                    based on its name
        @return                     table
        
        Example:
        @code
        ext = table.extract_columns(["name", "d_a"] )        
        @endcode
        """
        if isinstance(listColumns,list) :
            indexes = [ (self.index [col] if isinstance(col,str) else col)  \
                            for col in listColumns ]
            header  = listColumns
            values  = [ [ row[i] for i in indexes ] for row in self.values ]
            return self._private_getclass() (header, values)
        else :
            header =  [ _ for _ in self.header if listColumns(_) ]
            return self.extract_columns(header)
        
    def remove_columns (self, listColumns) :
        """
        remove some columns
        
        @param      listColumns     list of columns to remove or a function
                                    which returns True if the column has to be removed
                                    based on its name
        @return                     table
        
        Example:
        @code
        rem = table.remove ("d_a")
        @endcode
        """
        if isinstance(listColumns, list) :
            cols = [ _ for i,_ in enumerate(self.header) \
                    if _ not in listColumns and i not in listColumns ]
            return self.extract_columns (cols)
        elif isinstance(listColumns, str) :
            cols = [ _ for _ in self.header if _ != listColumns ]
            return self.extract_columns (cols)
        else :
            cols = [ _ for _ in self.header if not listColumns(_) ]
            return self.extract_columns (cols)

    def innerjoin (self, table, 
                            functionKey1, 
                            functionKey2,
                            nameKey         = "key",
                            addSuffixAnyWay = False,
                            prefixToAdd     = None,
                            full            = False,
                            keepKey         = True,
                            putKeyInColumn  = None,
                            missingValue    = None,
                            uniqueKey       = False) :
        """
        @param      table           other table to join with
        @param      functionKey1    key for the first table (a function)
        @param      functionKey2    key for the second table (a function) innerjoin .... ON ...
        @param      addSuffixAnyWay add a suffix to every column from the second table even if names are different (suffix is "+")
        @param      prefixToAdd     prefix to add the the columns of the second table
        @param      full            add all items even if there is no common keys (FULL OUTER JOIN), otherwise keep only common keys
        @param      keepKey         keep the key as a column in the result (column is key), otherwise not
        @param      putKeyInColumn  private parameter: keepKey has to be true and in this case, put the key in this column (integer)
        @param      missingValue    when there is not key on one side, this default value will be put in place
        @param      uniqueKey       if True, the function assumes there is a bijection between rows and keys (one row <--> one key) on both tables,
                                    otherwise, it will not.
        @return                     a table
        
        Example:
        @code
        innerjoin = table.innerjoin (group, lambda v : v["name"],
                                            lambda v : v["name"], "group" )
        @endcode
        """
        defaultVal1 = [ missingValue for k in self.header ]
        defaultVal2 = [ missingValue for k in table.header ]

        if uniqueKey :
            keys = { }
            for row in self.values :
                v = self._interpret_row (row)
                key = functionKey1 (v)
                keys [key] = (row, None)
               
            for row in table.values :
                v = table._interpret_row (row)
                key = functionKey2 (v)
                if key in keys : keys [key] = (keys[key][0], row)
                elif full : keys[key] = (None, row)
                
            if not full :
                d = []
                for k,v in keys.items() :
                    if None in v : d.append(k)
                for _ in d : del keys[_]
            else :
                for k in keys :
                    v = keys[k]
                    if   v[0] == None : keys[k] = (defaultVal1, v[1])
                    elif v[1] == None : keys[k] = (v[0], defaultVal2)
                    
            if keepKey :
                columns = [nameKey]
                for x in self.header :
                    while x in columns : x += "~"
                    columns.append (x)
               
                for x in table.header :
                    if prefixToAdd != None : x = prefixToAdd + x
                    elif addSuffixAnyWay : x += "+"
                    while x in columns : x += "+"
                    columns.append (x)
               
                f = keys.items if sys.version_info.major >= 3 else keys.iteritems
                values = [ [k] + v[0] + v[1] for k,v in f() if len(v) == 2 ]
                return self._private_getclass() (columns, values)
            else :
                columns = []
                for x in self.header :
                    while x in columns : x += "~"
                    columns.append (x)
               
                for x in table.header :
                    if prefixToAdd != None : x = prefixToAdd + x
                    elif addSuffixAnyWay : x += "+"
                    while x in columns : x += "+"
                    columns.append (x)
               
                f = keys.items if sys.version_info.major >= 3 else keys.iteritems

                if putKeyInColumn == None :
                    values = [ v[0] + v[1] for k,v in f() if len(v) == 2 ]
                else :
                    values = []
                    for k,v in f():
                        if len(v) == 2 :
                            nr = v[0] + v[1]
                            nr[putKeyInColumn] = k
                            values.append(nr)
                           
                return self._private_getclass() (columns, values)
        else :
            keys = { }
            for row in self.values :
                v = self._interpret_row (row)
                key = functionKey1 (v)
                if key in keys:  
                    keys [key][0].append(row) 
                else :
                    keys [key] = ( [row] , None )
               
            for row in table.values :
                v = table._interpret_row (row)
                key = functionKey2 (v)
                if key in keys : 
                    if keys[key][1] == None : 
                        keys [key] = (keys[key][0], [row])
                    else :
                        keys [key][1].append(row) 
                elif full : 
                    keys[key] = (None, [row])
                
            if not full :
                d = []
                for k,v in keys.items() :
                    if None in v : d.append(k)
                for _ in d : del keys[_]
            else :
                for k in keys :
                    v = keys[k]
                    if   v[0] == None : keys[k] = ( [ defaultVal1 ], v[1])
                    elif v[1] == None : keys[k] = (v[0], [ defaultVal2 ] )
                    
            if keepKey :
                columns = [nameKey]
                for x in self.header :
                    while x in columns : x += "~"
                    columns.append (x)
               
                for x in table.header :
                    if prefixToAdd != None : x = prefixToAdd + x
                    elif addSuffixAnyWay : x += "+"
                    while x in columns : x += "+"
                    columns.append (x)
               
                f = keys.items if sys.version_info.major >= 3 else keys.iteritems
                
                values = []
                for k,v in f():
                    if len(v) == 2 :
                        for ka in v[0] :
                            for kb in v[1] :
                                values.append (  [k] + ka + kb  )
                return self._private_getclass() (columns, values)
            else :
                columns = []
                for x in self.header :
                    while x in columns : x += "~"
                    columns.append (x)
               
                for x in table.header :
                    if prefixToAdd != None : x = prefixToAdd + x
                    elif addSuffixAnyWay : x += "+"
                    while x in columns : x += "+"
                    columns.append (x)
               
                f = keys.items if sys.version_info.major >= 3 else keys.iteritems

                if putKeyInColumn == None :
                    values = [ v[0] + v[1] for k,v in f() if len(v) == 2 ]
                else :
                    values = []
                    for k,v in f():
                        if len(v) == 2 :
                            for ka in v[0] :
                                for kb in v[1] :
                                    nr = ka + kb
                                    nr[putKeyInColumn] = k
                                    values.append(nr)
                           
                return self._private_getclass() (columns, values)
            
    def filter_quantile (self, function, alpha_min = 0.025, alpha_max = 0.025) :
        """
        sort all rows using criteria defined by function and remove
        rows at the extremes
        
        @param      function        values used to estimate the quantiles
        @param      alpha_min       lower quantile 
        @param      alpha_max       higher quantile 
        @return                     a table containing all the rows where the criterium
                                    is within the two quantiles
        
        Example:
        @code
        fil = table.filter_quantile ( lambda v : v["d_b"], 0, 0.4 )
        @endcode
        
        @warning Rows are not copied.
        
        """
        values = [ ]
        for row in self.values :
            v = self._interpret_row (row)
            val = function (v)
            values.append ( (val, row) )
        values.sort ()
        lv = len(values)
        i1 = int(lv * alpha_min + 0.5)
        i2 = int(lv * (1-alpha_max) + 0.5)
        i1 = max(i1,0)
        i1 = min(i1, lv)
        i2 = max(i1,i2)
        i2 = min(i2, lv)
        if i2 == i1 :
            raise RuntimeError("unable to extract quantile, the table is either " +
                            "empty or chosen quantile are not correct")
        values = [_[1] for _ in values[i1:i2] ]
        return self._private_getclass() (self.header, values )        
            
    def union (self, table) :
        """
        @param      table       table
        @return                 table (with the same number of columns)
        
        concatenates two tables by rows, they must have the same header, rows of both tables are merged into a single matrix
        Example:
        @code
        union = table.union (table2)
        @endcode
        """
        if len(self.header) != len(table.header) :
            raise ValueError("tables do not have the same number of columns\ntbl1: %s\ntbl2: %s" % ( ",".join(self.header), ",".join(table.header)))
        for a,b in zip(self.header, table.header) :
            if a != b :
                raise ValueError("tables do not have the same column names")
        return self._private_getclass() (self.header, self.values + table.values)
        
    def concatenate (self, table, addPrefix = "") :
        """
        concatenates two tables by columns
        @param      table       table
        @param      addPrefix   add a prefix to each column from table    
        @return                 table  (with the same number of rows as the longest one)
        """
        maxr   = max (len(self), len(table))
        header = self.header + [ addPrefix + h for h in table.header ]
        values = [ ]
        for i in range(0,maxr) :
            r1 = self.values[i]  if i < len(self)  else [ None ] * len(self.header)
            r2 = table.values[i] if i < len(table) else [ None ] * len(self.table)
            values.append (r1 + r2)
        return self._private_getclass() (header, values)

    def random (self, n, unique = False) :
        """
        select n random row from the table, returns a table
        @param      n       number of desired random rows
        @param      unique  draws unique rows or non unique rows
                            (tirage sans remise ou avec remise)
        @return             a table
        
        Example:
        @code
        rnd = table.random(10)
        @endcode
        """
        if unique :
            if n > len(self) :
                raise ValueError("number of desired random rows is higher " + \
                                "than the number of rows in the table")
            index = { }
            while len(index) < n :
                h = random.randint(0,len(self)-1)
                index[h] = 0
            values = [ self.values[h] for h in index ]
            return self._private_getclass() (self.header, values)
        else :
            values = []
            for i in range(0,n) :
                h = random.randint(0,len(self)-1)
                values.append (self.values[h])
            return self._private_getclass() (self.header, values)
            
    def todict (self, functionKey, functionValue, useList = False) :
        """
        convert the table as a dictionary { key:value }
        each of them is defined by functions.
        
        @param      functionKey     defines the key
        @param      functionValue   defines the value
        @param      useList         if there are multiple rows sharing the same key, it should be true,
                                    all values are stored in a list
        @return                     a dictionary { key:row } or { key: [ row1, row2, ...] }
        
        Example:
        @code
        d = table.todict( lambda v: v["name"], lambda v: v["d_b"], True)
        @endcode
        """
        res = {}
        if useList :
            for row in self.values :
                v = self._interpret_row(row)
                key = functionKey(v)
                val = functionValue(v)
                if key in res : res[key].append (val)
                else : res[key] = [ val ]
        else :
            for row in self.values :
                v = self._interpret_row(row)
                key = functionKey(v)
                val = functionValue(v)
                res[key] = val
        return res
        
    def reduce_dict (self, functionKey, functionValue, useList = False) :
        """
        @see me todict
        """
        return todict (functionKey, functionValue, uselist)
        
    def select (self, functionRow) :
        """
        @param      functionRow   fonction
        @return                   table
        
        Example:
        @code
        d = table.select( lambda v: (v["name"], v["d_b"]))
        print (list(d))
        @endcode
        """
        for row in self.values :
            v = self._interpret_row (row)
            nr = functionRow(v)
            yield nr
            
    def modify_all (self, modification_function) :
        """
        apply the same modification to every number
        @param      modification_function       modification to apply to every number
        @return                                 new table
        
        The signature of the function is the following one:
        @code
        def function (value, column_name) :
            # ....
            return new_value
        @endcode
        
        Example:
        @code
        tbl = tbl.modify_all(lambda v,c : {"string":"", "numerical":0}.get (c,None) if v == None else v )
        @endcode
        """
        values = []
        for row in self.values :
            r = [ ]
            for v,h in zip( row, self.header) :
                r.append (modification_function (v,h) )
            values.append ( r ) 
        return self._private_getclass() (self.header, values)
        
    def dcast (self, 
                        functionKey, 
                        functionInstance,
                        full = True) :
        """
        @see me multiply_column_by_row_instance
        """
        return self.multiply_column_by_row_instance (functionKey, functionInstance, full)

    def multiply_column_by_row_instance (self, 
                        functionKey, 
                        functionInstance,
                        full = True) :
        """
        @param      functionKey         defines a key (function)
        @param      functionInstance    defines a second key (will be moved to the columns dimension)
        @param      full                introduces missing values for not found combinations
        @return                         a table
        
        If a column contains a finite set of value, for example,
        we have the temperature for several cities organized like if
        it were a table from a database: city, date, temperatue.
        We would like to get another table where we have:
        date temparature_city1 temperature_city2...
        
        Then we would type:
        Example:
        @code
        mul = table.multiply_column_by_row_instance (
                            lambda v: v["date"],
                            lambda v: v["city"])
        @endcode
        The input table would be like:
        @code
        city   date
        A      jan
        A      feb
        B      feb
        @endcode
        It returns:
        @code
        KEY	    A|city	A|date	B|city	B|date
        feb	    A	    feb	    B	    feb
        jan	    A	    jan	    None	None
        @endcode
        """
        values = [ functionInstance ( self._interpret_row(row)) for row in self.values ]
        distinct = { }
        for v in values : distinct[v] = 0
        distinct = [ _ for _ in distinct ]
        distinct.sort()
        table1 = copy.deepcopy (self)
        table  = None
        header = copy.copy(table1.header)
        orig   = len (header)
        nameKey = "~KEY~"
        while nameKey in header : nameKey += "*"
        nbJoin = 0
       
        for val in distinct :
            table2 = table1.filter ( lambda v : functionInstance(v) == val )
            if table == None :
                table = table2.copy()
            else :
                colkey = table.header[0]
                table = table.innerjoin (  table2,
                                           functionKey if nbJoin == 0 else \
                                                    lambda v :v [colkey],
                                           functionKey,
                                           nameKey          = nameKey,
                                           prefixToAdd      = str(val) + "|",
                                           full             = full,
                                           keepKey          = nbJoin == 0,
                                           putKeyInColumn   = None if nbJoin == 0 else 0,
                                           uniqueKey        = True)
                                          
                if nbJoin == 0 :
                    head = []
                    nb = 0
                    for h in table.header :
                        if not h.endswith("~") and nb < orig :
                            head.append ( "%s|%s" % (distinct[0], h)  )
                            nb += 1
                        else : head.append (h)
                    header = ["KEY"] + head[1:]
                    table = self._private_getclass() (header, table.values)
               
                nbJoin += 1
               
        if nbJoin == 0 :
            head = []
            nb = 0
            for h in table.header :
                if not h.endswith("~") and nb < orig :
                    head.append ( "%s|%s" % (distinct[0], h)  )
                    nb += 1
                else : head.append (h)
            values = []
            for row in self.values :
                v = self._interpret_row(row)
                r = [ functionKey (v) ] + row
                values.append (r)
            header = ["KEY"] + head
            table = self._private_getclass() (header, values)

        return table
        
    def create_index (self, functionIndex) :
        """
        this method creates an index,
        to get an indexes row, use method get
        Example:
        @code
        table.create_index( lambda v : (v["name"], v["d_a"]) )
        row = table.get ( ('A', 1.1) )
        value = table.get ( ('A', 1.1), 2 )
        @endcode
        """
        self.indexspecial = { }
        for row in self.values :
            v = self._interpret_row (row)
            nr = functionIndex(v)
            if nr in self.indexspecial :
                raise KeyError("unable to add %s because it is already present" % str (nr))
            self.indexspecial [nr] = row
        return self
        
    def get (self, rowIndex, column = None) :
        """
        use the index created by method create_index
        Example:
        @code
        table.create_index( lambda v : (v["name"], v["d_a"]) )
        row = table.get ( ('A', 1.1) )
        value = table.get ( ('A', 1.1), 2 )
        @endcode
        """
        if "indexspecial" not in self.__dict__ :
            raise Exception("no index was created")
        row = self.indexspecial [rowIndex]
        if column == None : return row
        elif isinstance (column, int) : return row[column]
        else : return row [ self.index [column] ]
                
    def avg_std (self, functionValue, 
                       functionWeight = lambda v : 1) :
        """
        returns the average and standard deviation
        """
        avg = 0.
        std = 0.
        n   = 0.
        for i,row in enumerate(self.values) :
            v    = self._interpret_row(row)
            x    = float (functionValue(v))
            w    = functionWeight(v)
            avg += x * w
            std += x*x * w
            n   += w
            
            #check  = std/n - (avg/n)**2        
            #if check < 0 :
            #    raise Exception("float error i=%d issue with %f avg %f x2 %f var %d" % (i,x, avg/n, std/n, check)) 
        
        if n != 0 :
            avg /= n
            std /= n
            std -= avg*avg
            std  = math.sqrt(std)
        else :
            avg = 0.
            std = 0.
        return avg, std
            
    def add_column_cumulative ( self,
                                column_index,
                                column_name,
                                functionIndex,
                                functionValue,
                                normalize = False,
                                reverse = False,
                                cumulative = True,
                                functionSort = None) :
        """
        also called the Gini function
        Example:
        @code
        table.add_column_cumulative ( "index_%s" % col,
                                      "dist_%s" % col,
                                    lambda v : v["sum_nbclient"],
                                    lambda v : v[col],
                                    functionSort = lambda v : v [col] / v["sum_nbclient"],
                                    normalize = True)       
        @endcode
        """
       
        if functionSort == None :
            functionSort = functionValue
       
        val = [ ]
        for row in self.values :
            v = self._interpret_row (row)
            i = functionIndex (v)
            s = functionSort(v)
            v = functionValue(v)
            val.append ( (s,i,v) )
           
        val.sort (reverse = reverse)

        if cumulative :
            res = [ (0.,0.)]
            for s,i,v in val :
                res.append ( ( i + res[-1][0], v + res[-1][1] ) )
            del res[0]
           
            if normalize :
                sumi = res[-1][0]
                sumv = res[-1][1]
                if sumi != 0 and sumv != 0 :
                    res = [ (_[0] / sumi, _[1] / sumv) for _ in res ]
                else :
                    raise ZeroDivisionError ("cannot divide by zero, all indexes or all values are null")
           
        else :
            res = [ (i,v) for s,i,v in val ]
       
            if normalize :
                sumi = sum ( [_[0] for _ in res ] )
                sumv = sum ( [_[1] for _ in res ] )
                if sumi != 0 and sumv != 0 :
                    res = [ (_[0] / sumi, _[1] / sumv) for _ in res ]
                else :
                    raise ZeroDivisionError ("cannot divide by zero, all indexes or all values are null")

        for row,add in zip (self.values, res) :
            row.extend (add)
        self.index [column_index] = len(self.index)
        self.index [column_name] = len(self.index)
        self.header.append (column_index)
        self.header.append (column_name)
        return self        

    def transpose (self, labelC = None, labelAsRow = True) :
        """
        computes the transpose
        @param      labelC          proposes labels for the column,
                                    if None, take "r%d" % i,
                                    if it is a string, the function assumes it is a column name
        @param      labelAsRow      add the label as a row
        @return                     new table
        """
        if labelC == None :
            label = ["r%d" % i for i in range (0, len(self.values)) ]
            if labelAsRow : label = ["rowheader"] + label
            rem = None
        elif isinstance(labelC, str):
            label = list(self.select(lambda v:v[labelC]))
            rem = label
        else :
            rem = None
            label = labelC
            
        values = [ ]
        for i in range (0, len(self.header)) :
            if rem != None and self.header[i] == labelC :
                continue
            row = [ _[i] for _ in self.values ]
            if labelAsRow : row = [self.header[i]] + row 
            values.append(row)
        return self._private_getclass()(label, values)
        
    def covariance(self) :
        """
        computes the covariance matrix, the first column
        will contains the column names
        @return         new table
        """
        for i,x in enumerate(self.values[0]) :
            if not isinstance(x, float) :
                raise TypeError("expecting a float on column %d" % i)
        values = self.np_matrix
        N = values.shape[0]
        sums   = numpy.sum (values, axis=0) / N
        for i in range(0, values.shape[1]) :
            values[:,i] -= sums[0,i]
        cov    = values.transpose () * values
        cov   /= N
        head   = [ "var" ]+ self.header
        size = cov.shape
        values = [ [ self.header[i] ] +  [ float(cov[i,j]) \
                          for j in range(0,size[1]) ] \
                    for i in range(0,size[0]) ]
        tbl = self._private_getclass()(head, values)
        return tbl
        
    def correlation_col (self, col1, col2, noCenter = False) :
        """
        computes the correlation between two columns
        @param      col1        column 1
        @param      col2        column 2
        @param      noCenter    does the computation without removing the average
        @return                 float (covariance)
        """
        values  = [ [ self._interpret_row(row)[col1],
                      self._interpret_row(row)[col2] ] for row in self.values ] 
            
        if len(values) <= 1 :
            raise ValueError("expecting more than one observation, not %d" % len(values))
            
        mx = 0.
        my = 0.
        vx = 0.
        vy = 0.
        co = 0.
        nb = 0.
        for a,b in values :
            nb += 1
            mx += a
            my += b
            vx += a**2
            vy += b**2
            co += a*b
        mx /= nb
        my /= nb
        vx /= nb
        vy /= nb
        co /= nb
        if not noCenter :
            vx -= mx**2
            vy -= my**2
            co -= mx*my
        vx  = vx**0.5
        vy  = vy**0.5
        v = vx*vy
        if v != 0 : co /= v
        return co
        
    def covariance_col (self, col1, col2, noCenter = False) :
        """
        computes the correlation between two columns
        @param      col1        column 1
        @param      col2        column 2
        @param      noCenter    does the computation without removing the average
        @return                 float (covariance)
        """
        values  = [ [ self._interpret_row(row)[col1],
                      self._interpret_row(row)[col2] ] for row in self.values ] 
            
        if len(values) <= 1 :
            raise ValueError("expecting more than one observation, not %d" % len(values))
            
        mx = 0.
        my = 0.
        co = 0.
        nb = 0.
        for a,b in values :
            nb += 1
            mx += a
            my += b
            co += a*b
        mx /= nb
        my /= nb
        co /= nb
        if not noCenter :
            co -= mx*my
        return co
        
    def correlation_row (self, row1, row2, noCenter = False) :
        """
        computes the correlation between two columns
        @param      row1        row 1 (integer)
        @param      row2        row 2 (integer)
        @param      noCenter    does the computation without removing the average
        @return                 float (covariance)
        """
        values  = [ [a,b] for a,b in zip ( self.values[row1], self.values[row2] ) ]
            
        if len(values) <= 1 :
            raise ValueError("expecting more than one observation, not %d" % len(values))
            
        mx = 0.
        my = 0.
        vx = 0.
        vy = 0.
        co = 0.
        nb = 0.
        for a,b in values :
            nb += 1
            mx += a
            my += b
            vx += a**2
            vy += b**2
            co += a*b
        mx /= nb
        my /= nb
        vx /= nb
        vy /= nb
        co /= nb
        if not noCenter :
            vx -= mx**2
            vy -= my**2
            co -= mx*my
        vx  = vx**0.5
        vy  = vy**0.5
        v = vx*vy
        if v != 0 : co /= v
        return co
        
    def covariance_row (self, row1, row2, noCenter = False) :
        """
        computes the correlation between two columns
        @param      row1        row 1 (integer)
        @param      row2        row 2 (integer)
        @param      noCenter    does the computation without removing the average
        @return                 float (covariance)
        """
        values  = [ [a,b] for a,b in zip ( self.values[row1], self.values[row2] ) ]
            
        if len(values) <= 1 :
            raise ValueError("expecting more than one observation, not %d" % len(values))
            
        mx = 0.
        my = 0.
        co = 0.
        nb = 0.
        for a,b in values :
            nb += 1
            mx += a
            my += b
            co += a*b
        mx /= nb
        my /= nb
        co /= nb
        if not noCenter :
            co -= mx*my
        return co
        
    def correlation(self, useBootstrap      = False, 
                          collapseFormat    = True,
                          nbdraws           = -1,
                          alpha             = 0.05,
                          functionKeepValue = lambda val,low,high : "%f|%f,%f" % (bo[0], bo[2],bo[3])) :
        """
        computes the correlation matrix, the first column
        will contains the column names
        @param      useBootstrap            if True, use a bootstrap method to estimate the correlation
        @param      collapseFormat          if True and useBootstrap is True, produces a format average|lower bound|higher bound (at a definite confidence level)
        @param      nbdraws                 number of draws (if -1, then it will be equal to the number of observations)  
        @param      alpha                   confidence level
        @param      functionKeepValue       if collapseFormat is True, this function is used to collapse val,low,high in a single string
        @return                             new table
        """
        
        if useBootstrap :
            head   = [ "var" ]+ self.header
            values = [ [i] + [ 0. for r in self.header ] for i in self.header ]
            for i in range(len(self.header)) :
                fileprint("TableFormulaCore.correlation (useBootstrap=True) [row=%d/%d]" % (i, len(self.header)))
                values[i][0] = self.header[i]
                for j in range(len(self.header)) :
                    vs = [ [row[i], row[j]] for row in self.values ]
                    bo = TableFormulaCore.bootstrap (vs, 
                                        function = TableFormulaCore.correlation_bicolumn, 
                                        nbdraws  = nbdraws, 
                                        alpha    = alpha)
                    if collapseFormat :
                        st             = functionKeepValue (bo[0],bo[2],bo[3])
                        values[i][j+1] = st
                    else :
                        raise NotImplementedError("collapseFormat False is not implemented yet")
            tbl = self._private_getclass()(head, values)
            return tbl
        else :
            for i,x in enumerate(self.values[0]) :
                if not isinstance(x, float) :
                    raise TypeError("expecting a float on column %d" % i)
                    
            values = self.np_matrix
            N = values.shape[0]
            sums   = [ sum(values[:,i]) / N for i in range(0,values.shape[1]) ]
            
            for i in range(0, values.shape[1]) :
                values[:,i] -= sums[i]
                
            cov    = values.transpose () * values
            cov   /= N
            diag   = [ cov[i,i]**0.5 for i in range(cov.shape[0]) ]
            for i in range(cov.shape[0]) :
                if diag [i] > 0 :
                    cov [i,:] /= diag[i]
                    cov [:,i] /= diag[i]
            
            head   = [ "var" ]+ self.header
            size = cov.shape
            values = [ [ self.header[i] ] +  [ float(cov[i,j]) \
                              for j in range(0,size[1]) ] \
                        for i in range(0,size[0]) ]
            tbl = self._private_getclass()(head, values)
            return tbl
        
    def values_to_float(self, only_if_possible = False, subset_columns = None) :
        """
        converts all values into float
        @param    only_if_possible      if True, converts all possible values and catches exception,
                                        if False, converts everything, raises an exception when not possible
        @param    subset_columns        if None, takes all of them, otherwise, try to convert
                                        only for the listed columns
        @return                         table
        """
        tbl = self.copy()
        if subset_columns != None :
            subset = { i:True for i,v in enumerate(self.header) if v in subset_columns }
        if only_if_possible :
                
            for row in tbl.values :
                for i in range(0,len(row)) :
                    if subset_columns == None or i in subset :
                        try :
                            v = float(row[i])
                            row[i] = v
                        except (ValueError, TypeError) :
                            continue
        else :
            for row in tbl.values :
                for i in range(0,len(row)) :
                    if subset_columns == None or i in subset :
                        row[i] = float(row[i])
        return tbl
        
    def values_to_str(self, subset_columns = None, format = None) :
        """
        converts all values into str
        @param    subset_columns        if None, takes all of them, otherwise, try to convert
                                        only for the listed columns
        @param    format                format for the conversion, by None by default but it could be for exemple %1.2f.
        @return                         table
        """
        tbl = self.copy()
        if subset_columns != None :
            subset = { i:True for i,v in enumerate(self.header) if v in subset_columns }
               
        if format == None :
            for row in tbl.values :
                for i in range(0,len(row)) :
                    if subset_columns == None or i in subset :
                        row[i] = str(row[i])
        else :
            for row in tbl.values :
                for i in range(0,len(row)) :
                    if (subset_columns == None or i in subset) and isinstance (row[i],float) :
                        row[i] = format % row[i]
        return tbl
        
    def values_to_date(self, format = None, only_if_possible = False, subset_columns = None) :
        """
        converts all values into dates
        @param    only_if_possible      if True, converts all possible values and catches exception,
                                        if False, converts everything, raises an exception when not possible
        @param    format                date format see fn str_to_datetime
        @param    subset_columns        if None, takes all of them, otherwise, try to convert
                                        only for the listed columns
        @return                         table
        """
        tbl = self.copy()
        if subset_columns != None :
            subset = { i:True for i,v in enumerate(self.header) if v in subset_columns }
        if only_if_possible :
            if subset_columns != None :
                subset = { i:True for i,v in enumerate(self.header) if v in subset_columns }
                
            for row in tbl.values :
                for i in range(0,len(row)) :
                    if subset_columns == None or i in subset :
                        try :
                            v = str_to_datetime(row[i], format)
                            row[i] = v
                        except (ValueError, TypeError) :
                            continue
        else :
            for row in tbl.values :
                for i in range(0,len(row)) :
                    if subset_columns == None or i in subset :
                        row[i] = float(row[i])
        return tbl
        
    def histogram (self,    functionValue, 
                            nbDiv                = 100, 
                            secondColumnIsWeight = False,
                            normalize            = True,
                            removeExtreme        = 0.05) :
        """
        computes an histograms on one vector
        @param      functionValue           function which produces the value to histogram
        @param      nbDiv                   number of divisions for this histograms (boundaries are min and max)
        @param      secondColumnIsWeight    if True, the second column is the weight
        @param      normalize               if True, normalize by the sum of weights
        @param      removeExtreme           remove extreme values at both sides (0.05 means 0.025 on each side)
        @return                             table with two columns
        """
        values  = list ( [ functionValue (self._interpret_row(row)) for row in self.values ] )
        if removeExtreme != None and removeExtreme > 0 :
            values.sort ()
            al = int (len(values) * removeExtreme / 2)
            if al == 0 :
                raise Exception("removeExtreme has no impact (%d,%f)" % (len(values),len(values)*removeExtreme/2))
            if al*2 < len(values) :
                values = values [al:len(values)-al]
            
        mi      = min(values)
        ma      = max(values)
        
        if isinstance (values[0], tuple) or isinstance(values[0], list) :
            # weight
            W    = 0.
            div  = (ma[0]-mi[0]) / nbDiv
            hist = [ [ mi[0]+n*div, 0.] for n in range (0,nbDiv+1) ]
            for v in values :
                x = int ((v[0] - mi[0]) // div)
                hist[x][1] += v[1]
                W += v[1]
            mi = mi[0]
        else :
            W    = len(values)
            div  = (ma-mi) / nbDiv
            hist = [ [ mi+n*div, 0.] for n in range (0,nbDiv+1) ]
            for v in values :
                x = int ((v - mi) // div)
                if 0 <= x < len(hist) : 
                    hist[x][1] += 1.
    
        if normalize and W > 0 :
            for i in range(len(hist)) :
                hist[i][1] /= W
                
        values = [ [mi+n*div, hist[n]] for n in range(len(hist)) ]
        tbl = self._private_getclass()(["x", "hist(x)"], hist)
        return tbl
        
    def histograms (self,   columnsSet,
                            nbDiv                = 100, 
                            secondColumnIsWeight = False,
                            normalize            = True,
                            removeExtreme        = 0.05,
                            histxName            = "histKey") :
        """
        computes a common histograms on all columns
        @param      columnsSet              set of columns
        @param      nbDiv                   number of divisions for this histograms (boundaries are min and max)
        @param      secondColumnIsWeight    if True, the second column is the weight
        @param      normalize               if True, normalize by the sum of weights
        @param      removeExtreme           remove extreme values at both sides (0.05 means 0.025 on each side)
        @param      histxName               column name given to the x axis shared by every histogram
        @return                             table with two columns
        
        @warning The function skips any NaN of Inf value.
        
        """
        values  = [] 
        for row in self.values : 
            temp = self._interpret_row(row)
            for t in columnsSet : 
                values.append (temp[t])
            
        if removeExtreme != None and removeExtreme > 0 :
            values.sort ()
            al = int (len(values) * removeExtreme / 2)
            if al == 0 :
                raise Exception("removeExtreme has no impact (%d,%f)" % (len(values),len(values)*removeExtreme/2))
            if al*2 < len(values) :
                values = values [al:len(values)-al]
            
        mi      = min(values)
        ma      = max(values)
        W       = len(values)
        div     = (ma-mi) / nbDiv
        if div == 0 :
            raise RuntimeError("unable to continue since div is null: min,max = %f,%f" % (mi, ma))
        hist    = [ [ mi+n*div, 0.] for n in range (0,nbDiv+1) ]
        value   = { i:{histxName:hist[i][0]} for i in range(len(hist)) }
        su      = { }
        for row in self.values :
            for _ in columnsSet :
                temp = self._interpret_row(row)
                if math.isnan(temp[_]) or math.isinf (temp[_]) :
                    continue
                x = int ( (temp[_] - mi) // div )
                if x not in value : 
                    # it means extremes were removed
                    continue
                    #raise Exception("value %d,%f is not allowed min,max = [%f,%f]" % (x, temp[_], mi, ma))
                value [x][_] = value[x].get (_, 0.) + 1.
                su [_] = su.get(_, 0.) + 1.
                
        if normalize and W > 0 :
            for k,v in value.items () :
                for _ in v : 
                    if _ != histxName : v[_] /= su[_]
                
        tbl = self._private_getclass()("__byrow__", value)
        return tbl
        
    def union_columns (self, columnsSet) :
        """
        computes the union of all values from all columns present in columnSet
        @param      columnsSet      set of columns
        @return                     table
        """
        values  = [] 
        for row in self.values : 
            temp = self._interpret_row(row)
            for t in columnsSet : 
                values.append (temp[t])
        tbl = self._private_getclass()(["x"], [ [ x ] for x in values ])
        return tbl
        
    def mu_sigma (self, functionValues, removeExtreme = None) :
        """
        computes the average and the standard deviation a vector of values
        @param      functionValues      function produces the vector of values
        @param      removeExtreme       remove extreme values at both sides (0.05 means 0.025 on each side)
        @return                         (average, standard deviation)
        """
        if removeExtreme != None and removeExtreme > 0 :
            values = []
            for row in self.values :
                row = self._interpret_row(row)
                val = functionValues (row)
                values.append (val)
            values.sort()
            al = int (len(values) * removeExtreme / 2)
            if al == 0 :
                raise Exception("removeExtreme has no impact (%d,%f)" % (len(values),len(values)*removeExtreme/2))
            if al*2 < len(values) :
                values = values [al:len(values)-al]
            tbl = TableFormulaCore (["x"], [ [_] for _ in values] )
            return tbl.mu_sigma (lambda v : v ["x"], 0)
        else :
            mu = 0.
            si = 0.
            nb = 0.
            for row in self.values :
                row = self._interpret_row(row)
                val = functionValues (row)
                mu += val
                si += val**2
                nb += 1.
            mu /= nb
            si /= nb
            si -= mu**2
            return mu, si**0.5
            
    def mu_sigma_each_column (self, columnsSet = None, removeExtreme = None) :
        """
        returns a table with the average and the standard deviation for each columns
        @param      removeExtreme       remove extreme values at both sides (0.05 means 0.025 on each side)
        @param      columnsSet          set of column to deal with
        @return                         table with two rows: average and standard deviation
        """
        values = [ [], [] ]
        if columnsSet == None : columnsSet = self.header
        for col in columnsSet :
            mu,sigma = self.mu_sigma (lambda v : v [col], removeExtreme)
            values[0].append(mu)
            values[1].append(sigma)
        tbl = self._private_getclass()(columnsSet, values)
        return tbl
            
    @property 
    def np_matrix(self) :
        """
        returns the values as a numpy matrix
        @return         numpy matrix
        """
        return numpy.matrix(self.values)
        
    @property 
    def np_array(self) :
        """
        returns the values as a numpy array
        @return         numpy array
        """
        return numpy.array(self.values)
        
    @property
    def dataframe(self):
        """
        creates a pandas dataframe
        @return     pandas.dataframe
        """
        import pandas
        #
        #val = { }
        #for i,h in enumerate(self.header) :
        #    val [h] = [ row[i] for row in self.values ]
        #return pandas.DataFrame(val)
        return pandas.DataFrame(self.values, columns=self.header)
        
    @property
    def json(self):
        """
        returns a json format
        @return         string
        """
        rows = [ row for row in self ]
        return json.dumps(rows)
        
    def center_reduce (self, columnsSet     = None, 
                             op             = None, 
                             removeExtreme  = None,
                             mu_sigma       = None ) :
        """
        center and reduce a set of columns (or all if columnsSet is None)
        @param      removeExtreme       remove extreme values at both sides (0.05 means 0.025 on each side)
        @param      columnsSet          set of column to deal with
        @param      op                  if can be:
                                            - None:   substract mean and normalize,
                                            - "mean": substract mean only,
                                            - "norm": normalize only
        @param      mu_sigma            matrix with two rows (one for mean, second for sigma), if None,
                                        if computes that from the matrix self, columns must have the same order 
                                        that columnSet
        @return                         the same table (with only the considered columns)
        """
        if op not in [None, "mean", "norm"] :
            raise ValueError('expecting a value in [None, "mean", "norm"] for op')
        if columnsSet == None : columnsSet = self.header
        mus = self.mu_sigma_each_column(columnsSet, removeExtreme) if mu_sigma == None else mu_sigma
        tbl = self.extract_columns (columnsSet)
        n   = len(self.header)
        for row in tbl.values :
            if op == None or op == "mean" :
                for i in range(n) :
                    row[i] -= mus.values[0][i]
            if op == None or op == "norm" :
                for i in range(n) :
                    row[i] /= mus.values[1][i]
        return tbl
        
    def halpython(self, features, label_class):
        """
        builds table in a file which can be used to trained 
        a machine learned model using `hal_python <http://www.xavierdupre.fr/app/hal_python3/hal_python_help_html/index.html>`_.
        
        @param      features        list of columns considered as features
        @param      label_class     integer which contains the class to learn
        """
        mi      = min ( self.select ( lambda row : row [label_class] ) )
        ma      = max ( self.select ( lambda row : row [label_class] ) )
        de      = int(ma - mi + 1)
        columns = [ "keys"] + \
                  [ "x%d" % d for d in range(len(features)) ] + \
                  [ "p%d" % d for d in range(de) ]
        values = []
        def bin(e) : return 1.0 if e else 0.0
        for i,row in enumerate(self.values) :
            row = self._interpret_row(row)
            r  = [ "k%d"%i ] + [ row[c] for c in features ] 
            r += [ bin(row[label_class]-mi == c) for c in range(de) ]
            values.append(r)
        return self._private_getclass() (columns, values)
    
    @staticmethod
    def save_multiple_as_excel( filename, 
                            list_table,
                             font       = "Calibri",
                             close      = True,
                             encoding   = None):
        """
        saves multiple table in one Excel file

        @param      filename        filename (can be None)
        @param      list_table      list of 2uple ("name", tbl )
        @param      font            font name
        @param      close           if True, close the file, otherwise, the user will have to
        @param      encoding        encoding
        @return                     object Workbook
        """
        ext = os.path.splitext(filename)[-1].lower() if filename != None else None
        if ext != None and ext == ".xls" :
            font0 = EXf.Font()
            font0.name = font
            font0.bold = True
            style0 = EXs.XFStyle()
            style0.font = font0

            wb = EXw.Workbook(encoding = encoding) if encoding != None else EXw.Workbook()
            for sheetname, self in list_table :
                ws0 = wb.add_sheet(sheetname)
                
                for i,l in enumerate(self.header) :
                    ws0.write (0,i, l, style0)
                    
                fnt = EXf.Font()
                fnt.name = font
                style = EXs.XFStyle()
                style.font = fnt
                
                for irow, row in enumerate(self.values) :
                    for icol,val in enumerate(row) :
                        if isinstance (val, int) or isinstance (val, float) :
                            st = val
                        elif isinstance (val, str) :
                            if encoding != None :
                                st = val.encode(encoding).decode(encoding)
                            else : 
                                st = val
                        elif val != None :
                            st = str(val)
                        else :
                            continue
                        ws0.write(irow+1,icol, st, style)

            wb.save(filename)
            return wb
            
        elif ext == None or ext == ".xlsx" :
            wb = EXxw.Workbook(filename) if filename != None else EXxw.Workbook()
                # it does not work with xlsxwriter so, we open an existing one
                #_file = os.path.abspath(os.path.split(__file__) [0])
                #_file = os.path.join(_file, "..", "..", "code", "hofile", "unicode.xlsx")
                #if not os.path.exists (_file) :
                #    raise FileNotFoundError("unable to find a pre-existing excel file using unicode: " + _file)
                
            for sheetname, self in list_table :
                ws0 = wb.add_worksheet(sheetname)
                
                style0 = wb.add_format({'bold': True})
                style0.set_font_name(font)

                for i,l in enumerate(self.header) :
                    ws0.write (0,i, l, style0)
                    
                style = wb.add_format()
                style.set_font_name(font)
                
                for irow, row in enumerate(self.values) :
                    for icol,val in enumerate(row) :
                        if isinstance (val, int) or isinstance (val, float) :
                            st = val
                        elif isinstance (val, str) :
                            if encoding != None :
                                st = val.encode(encoding).decode(encoding)
                            else : 
                                st = val
                        elif val != None :
                            st = str(val)
                        else :
                            continue
                        ws0.write(irow+1,icol, st, style)

            if filename != None and close: 
                wb.close()
            return wb
            
        else :
            raise NameError("extension should be .xls or .xlsx for file " + filename)
        
    def save_as_excel (self, filename, 
                             font       = "Calibri",
                             sheetname  = "sheet0",
                             close      = True,
                             encoding   = None
                             ) :
        """
        saves the table as a new Excel file, you can use ``.xls`` or ``.xlsx``
        if filename is None, the function returns an object (xslx) and does not save it.
        
        @param      filename        Excel filename
        @param      sheetname       name of the sheet to add
        @param      font            font name
        @param      close           if True, close the file, otherwise, the user will have to
        @param      encoding        encoding
        @return                     object Workbook
        """
        return TableFormulaCore.save_multiple_as_excel( filename, [ (sheetname, self) ],
                    font = font, close = close, encoding = encoding)
            
    def schema_database(self, add_id = True):
        """
        returns the schema for a database which would contains this database
        
        @param      add_id      if True, adds an index "PRIMARYKEY"
        @return                 dictionary { index_column: (name, type) }
        """
        schema = { i:(l,str) for i,l in enumerate(self.header) }
        if add_id != None :
            schema [-1] = (add_id, int, "PRIMARYKEY", "AUTOINCREMENT")
            
        if len(self) > 0 :
            # we use the first row to determine type
            for i,v in enumerate(self.values[0]) :
                if not isinstance(v,str) :
                    schema [i] = (schema[i][0], type(v) )
        return schema
        
    def fill_sql_table (self, filename_or_database, tablename, add_id = "idr") :
        """
        returns a Database object, creates the database if it does not exists,
        same for the table
        
        @param      filename_or_database    filename or Database object, 
                                                in that second case, we assume method connect was called before
        @param      tablename               table name
        @param      add_id                  if != None, then the function adds an id, it first takes the 
                                            max(id) and goes on incrementing it;
        @return                             Database object (new or the one from the parameters),
                                            in both case, the database is not disconnected
        """
        
        schema = self.schema_database(add_id)
                    
        if isinstance(filename_or_database, str) :
            HalLOG("fill_sql_table: creating database ", filename_or_database)
            db = Database(filename_or_database, LOG = fLOG)
            db.connect()
            
            HalLOG ("fill_sql_table ", schema)
            if tablename not in db.get_table_list () : 
                HalLOG ("creationg of table ", schema)
                cursor = db.create_table (tablename, schema)
                db.append_values ( self.values, tablename, schema, cursor = cursor)
            else :
                db.append_values ( self.values, tablename, schema)
        else :
            db = filename_or_database
            db.append_values ( self.values, tablename, schema)
        
        return db
        

graphes sous MatPlotLib

#coding:utf8
"""
@file
@brief  Contains TableFormulaGraph which inherits from TableFormulaCore.

.. requires matplotlib

"""

from inspect import isfunction
import copy, os, os.path, sys, datetime, random, math, datetime

from  ..             import HalLOG
from .tableformula   import TableFormulaCore
fileprint = HalLOG


## constant
global_default_figsize = (10,10)



class TableFormulaGraph (TableFormulaCore) :
    """
    
    .. requires matplotlib
    
    Extension of TableFormulaCore, add graph method to the core class. 
    The class contains basic graphs for frequent graphs. I switch from 
        - matplotlib (which crashes when you ask formore than 50 graphs),
        - Gnuplot (not yet)
        - d3js  (not yet)
        - hal_python (something fast but not very appealing)
        - hal_python_mat (same graph hal_python but converted into a matplotlib graw, it may not work)
        
    You can see below some examples:

    @image hal_python_ex_img.png
    
    
        
    Example:
    @code
    print ("--------- graph XY")
    table = TableFormula ("name sum_a sum_b sum_c#A 1 2 3#A 1.1 2.1 3.1#B 3 4 5".replace(" ", "\t").replace("#","\\n"))
                         
    print ("--------- graph XY hal_python")
    table.graph_XY ( [ [ lambda v: v["sum_a"], lambda v: v["sum_b"], "xy label 1"],
                      [ lambda v: v["sum_b"], lambda v: v["sum_c"], "xy label 2"],
                        ],
                     outImage = "image_XY.hal.png",
                     layout = "hal_python").Display()
        
    table.graph_XY ( [ [ lambda v: v["sum_a"], lambda v: v["sum_b"], lambda v: str(v["sum_b"]), "xy label 1"],
                      [ lambda v: v["sum_b"], lambda v: v["sum_c"], "xy label 2"],
                        ],
                     outImage = "image_XY.hal2.png",
                     layout = "hal_python", show=True)
        
                     
    print ("--------- graph XY matplotlib")
    table.graph_XY ( [ [ lambda v: v["sum_a"], lambda v: v["sum_b"], "xy label 1"],
                      [ lambda v: v["sum_b"], lambda v: v["sum_c"], "xy label 2"],
                        ],
                     outImage = "image_XY.png")    
                     
    print ("--------- graph distribution")
    values = [ [ x*0.1, math.exp(-x*0.1) ] for x in range (0,50) ]
    table  = TableFormula (["X", "Y"], values)
    table.graph_distribution ( lambda v: v["X"], lambda v: v["Y"],
                    outImage = "image_distribution.png",
                    title = "distribution")

    print ("--------- graph XY and dates")
    values = [ [ datetime.datetime (2013,1,x,1,2,4), math.exp(-x/10.)  ] for x in range (1,32) ]
    table  = TableFormula (["date", "Y"], values)
    table.graph_XY ( [ [ lambda v: v["date"], lambda v: v["Y"], "date Y"] 
                        ],
                     outImage = "image_XY_dates.png")    

    print ("--------- graph bar")
    values = [ [ datetime.datetime (2013,1,x,1,2,4), 
                 math.exp(-x/10.),
                 math.exp(-x/5.),
                 "label %d" % x
                 ] for x in range (1,32) ]
    table  = TableFormula (["date", "Y", "Y2", "xl"], values)
    
    table.graph_bar ( None, 
                        [ [ lambda v: v["Y"], "Y"],  
                          [ lambda v: v["Y2"], "Y2"] ],
                     outImage = "image_bar.png")    

    print ("--------- graph bar, x label")
    table.graph_bar ( lambda v: v ["xl"], 
                        [ [ lambda v: v["Y"], "Y"],  
                          [ lambda v: v["Y2"], "Y2"] ],
                     outImage = "image_bar_xlabel.png")    

    print ("--------- graph bar dates")
    table.graph_bar ( lambda v: v ["date"], 
                        [ [ lambda v: v["Y"], "Y"],  
                          [ lambda v: v["Y2"], "Y2"] ],
                     outImage = "image_bar_dates.png")    
                     
    print ("--------- show the last one")
    TableFormula.importmodules()
    plt = sys.modules["matplotlib.pyplot"]
    plt.show()
    @endcode
    """

    # keep track of produced graphs
    privateGraphStory = []
    
    def __init__ (self, file, 
                        numeric_column  = [], 
                        sep             = "\t",
                        encoding        = None,
                        read_n_lines    = -1,
                        sheet           = 0,
                        **options) :
        """
        constructor, see `TableFormulaCore.__init__ <pyhome3.srcpyhome.tables.tableformulas.tableformula.TableFormulaCore.__init__>`
        """
        if isinstance(file, TableFormulaCore) :
            TableFormulaCore.__init__ (self, file.header, file.values, **options)
        else :
            TableFormulaCore.__init__ (self, file = file, 
                                             numeric_column = numeric_column, 
                                             sep = sep, 
                                             encoding = encoding,
                                             read_n_lines = read_n_lines,
                                             sheet = sheet,
                                             **options) 

    def importmodules () :
        if "pylab" not in sys.modules :
            import pylab
            import matplotlib
            import matplotlib.pyplot as plt
        if "numpy" not in sys.modules :
            import numpy
    importmodules = staticmethod(importmodules)
    
    def ShowLastGraph () :
        TableFormulaGraph.importmodules()
        plt = sys.modules["matplotlib.pyplot"]
        plt.show()           
    ShowLastGraph = staticmethod(ShowLastGraph)
    
    def privateBeginGraph () :
        TableFormulaGraph.importmodules()
        matplotlib  = sys.modules["matplotlib"]
        plt         = sys.modules["matplotlib.pyplot"]
        np          = sys.modules["numpy"]
        if len(TableFormulaGraph.privateGraphStory) > 0 :
            plt.close()
        return plt, np, matplotlib
    privateBeginGraph = staticmethod(privateBeginGraph)
        
    def privateEndGraph (plt, fig, ax, outImage, xlabel, ylabel, title) :
        if xlabel != None : plt.xlabel(xlabel)
        if ylabel != None : plt.ylabel(ylabel)
        if title  != None : ax.set_title(title)
        
        if outImage == None : 
            plt.show()
        else :
            plt.savefig(outImage)
        TableFormulaGraph.privateGraphStory.append (fig)
    privateEndGraph = staticmethod(privateEndGraph)
    
    def private_GetHalPython():
        if "hal_python" not in sys.modules : 
            import hal_python
            hal_python.Begin()
        return sys.modules["hal_python"]
    private_GetHalPython = staticmethod(private_GetHalPython)
    
    def graph_XY (self,  curves,
                        outImage    = None,
                        xlabel      = None,
                        ylabel      = None,
                        marker      = True,
                        linkPoint   = False,
                        title       = None,
                        formatDate  = "%Y-%m-%d",
                        legendLoc   = 0,
                        figsize     = global_default_figsize,
                        layout      = "matplotlib",
                        show        = False,
                        **params
                        ) :
        """
        @param      curves      list of 3-uples (generator for X, generator for Y, label)
                                for some layout, it can also be: 
                                (generator for X, generator for Y, generator for labels, label)
        @param      outImage    a filename if you want to save it as an image
        @param      xlabel      label for X axis
        @param      ylabel      label for Y axis
        @param      marker      add a marker for each point
        @param      linkPoint   link points between them
        @param      title       graph title
        @param      formatDate  if X axis is a datetime object, the function will use this format
                                to print dates
        @param      legendLoc   location of the legend
        @param      figsize     size of the figure
        @param      layout      type of graphs (could be matplotlib, gnuplot, hal_python, hal_python_mat, d3js)
        @param      show        if True, opens a window to show the graph
        @param      params      extra parameters (depends on the layout):
                                    - hal_python:
                                    - label_is_class: a color for every distinct label
        @return                 an object
        
        @warning    Only matploblib is implemented.
                                        
        
        for the legend position, see `matplotlib <http://matplotlib.org/api/legend_api.html>`_.
        
        example:
        @code
        table.graph_XY ( [ [ lambda v: v["sum_a"], lambda v: v["sum_b"], "xy label 1"],
                          [ lambda v: v["sum_b"], lambda v: v["sum_c"], "xy label 2"],
                            ],
                         outImage = "image.png")
        @endcode
        """
        
        if layout == "matplotlib" :
            HalLOG("graph_XY: layout: ", layout)
            plt, np, matplotlib = TableFormulaGraph.privateBeginGraph()
            smarker = { (True,  True) :'o-',
                        (True,  False):'o',
                        (False, True) :'-',
                        #(False, False) :''
                        } [ marker, linkPoint ]
            fig     = plt.figure(figsize = figsize)
            ax      = fig.add_subplot(111)
            allvalues = []

            for xf,yf,label in curves :
                x = [ xf (self._interpret_row(row)) for row in self.values ]
                y = [ yf (self._interpret_row(row)) for row in self.values ]
                x = [ _ for _ in x if _ != None ]
                y = [ _ for _ in y if _ != None ]
                ax.plot(x, y, smarker, label = label)
                allvalues += x

            if isinstance (allvalues[0], datetime.datetime) :
                hfmt = matplotlib.dates.DateFormatter(formatDate)
                if "%H" in formatDate or "%M" in formatDate :
                    ax.xaxis.set_major_locator(matplotlib.dates.MinuteLocator())
                ax.xaxis.set_major_formatter(hfmt)
                fig.autofmt_xdate()

            plt.legend (loc=legendLoc)
            TableFormulaGraph.privateEndGraph(plt, fig, ax, outImage, xlabel, ylabel, title)
            if show : TableFormulaGraph