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 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.ShowLastGraph() elif layout in ["hal_python", "hal_python_mat"] : HalLOG("graph_XY: layout: ", layout) hal = TableFormulaGraph.private_GetHalPython() pl = None for curve in curves : xf,yf = curve[:2] vx = [ xf (self._interpret_row(row)) for row in self.values ] vy = [ yf (self._interpret_row(row)) for row in self.values ] scatter = not isinstance(vx[0],str) if len(curve) == 4 and isfunction(curve[2]) : lf = curve[2] la = [ lf (self._interpret_row(row)) for row in self.values ] else : la = [ ] ti = curve[-1] link = 2 if linkPoint else 1 mark = [] if not marker else ([ 4 for _ in vx ]) if params.get("label_is_class", False) : if pl == None : if scatter : pl = hal.PlotObject() else : pl = hal.PlotObject(vx) names = { } for l in la : names[l] = names.get(l, len(names)) names = list(names.keys()) names.sort() index = { n:i for i,n in enumerate(names) } la = [ index[_] for _ in la ] names = [ "%s-%s" % (ti, _) for _ in names ] pl.AddClass(names, la, list(range(len(vy))), vy, link, label = vx, size = mark) else : if pl == None : pl = hal.PlotObject() pl.Add(ti, vx, vy, link, label = la, size = mark) mpl = 0 if layout == "hal_python_mat" : mpl = 1 if figsize != None and figsize != global_default_figsize : im = pl.GetImage(size = figsize, matplotlib = mpl) else : im = pl.GetImage(matplotlib = mpl) if outImage != None : im.Save(outImage) if show : im.Display() hal.Pause() return pl elif layout == "gnuplot" : """ set term png set output "temp/image_gnu.png" set grid ### plot \\ "temp/series0.txt" title "dec ----" with points axis x1y1,\\ "temp/series1.txt" title "dec -no" with points axis x1y1,\\ "temp/series2.txt" title "dec -yes" with points axis x1y1 exit """ raise NotImplementedError("layout %s is not available yet" % layout) else : raise NotImplementedError("layout %s is not available yet" % layout) def graph_distribution (self, x, y, outImage = None, xlabel = None, ylabel = "%", title = None, figsize = global_default_figsize, layout = "matplotlib", show = False, ) : """ @param x generator for X @param y generator for Y @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 title graph title @param figsize size of the figure @param layout type of graphs (could be matplotlib, gnuplot, hal_python, d3js) @param show if True, opens a window to show the graph @warning Only matploblib is implemented. Example: @code table.graph_distribution ( lambda v: v["X"], lambda v: v["Y"], outImage = "imageDistribution.png") @endcode """ if layout == "matplotlib": plt, np, matplotlib = TableFormulaGraph.privateBeginGraph() x = [ x(self._interpret_row(row)) for row in self.values ] y = [ y(self._interpret_row(row)) for row in self.values ] x = [ _ for _ in x if _ != None ] y = [ _ for _ in y if _ != None ] dx = (x[-1] - x[0]) / (len(x)-1) left = np.array( [ _ for _ in x ] ) right = np.array( [ _ for _ in x[1:] ] + [ x[-1] + dx ] ) bottom = np.zeros(len(left)) top = bottom + np.array(y) fig = plt.figure(figsize = figsize) ax = fig.add_subplot(111) XY = np.array([[left,left,right,right], [bottom,top,top,bottom]]).T barpath = matplotlib.path.Path.make_compound_path_from_polys(XY) patch = matplotlib.patches.PathPatch(barpath, facecolor='blue', edgecolor='gray', alpha=0.8) ax.add_patch(patch) ax.set_xlim(left[0], right[-1]) ax.set_ylim(bottom.min(), top.max()) TableFormulaGraph.privateEndGraph(plt, fig, ax, outImage, xlabel, ylabel, title) if show : TableFormulaGraph.ShowLastGraph() else : raise NotImplementedError("layout %s is not available yet" % layout) def graph_bar (self, xf, curves, outImage = None, xlabel = None, ylabel = None, title = None, formatDate = "%Y-%m-%d", legendLoc = 0, figsize = global_default_figsize, layout = "matplotlib", show = False, ) : """ @param xf generator for X @param curves list of 2-uples (generator for Y, 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 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, d3js) @param show if True, opens a window to show the graph @warning Only matploblib is implemented. For the legend position, see `matplotlib <http://matplotlib.org/api/legend_api.html>`_. Example: @code table.graph_bar ( lambda v: v ["xl"], [ [ lambda v: v["Y"], "Y"], [ lambda v: v["Y2"], "Y2"] ], outImage = "image_bar_xlabel.png") @endcode """ if layout == "matplotlib" : plt, np, matplotlib = TableFormulaGraph.privateBeginGraph() fig = plt.figure(figsize = figsize) ax = fig.add_subplot(111) wei = 0.9 / len(curves) colors = ['g', 'orange', 'b', 'c', 'r', 'y'] nb = 0 for yf,label in curves : y = [ yf (self._interpret_row(row)) for row in self.values ] x = [nb*wei + _ for _ in range(0,len(y)) ] y = [ _ for _ in y if _ != None ] x = [ _ for _ in x if _ != None ] ax.bar(x, y, label = label, width=wei, color = colors[nb%len(colors)]) nb += 1 if xf != None : x = [ xf (self._interpret_row(row)) for row in self.values ] if isinstance (x[0], datetime.datetime) : x = [ _.strftime(formatDate) for _ in x ] x = [ _ for _ in x if _ != None ] ax.set_xticks(range(0,len(x))) ax.set_xticklabels( x ) labels = ax.get_xticklabels() plt.setp(labels, rotation=30, fontsize=10) plt.legend (loc=legendLoc) TableFormulaGraph.privateEndGraph(plt, fig, ax, outImage, xlabel, ylabel, title) if show : TableFormulaGraph.ShowLastGraph() else : raise NotImplementedError("layout %s is not available yet" % layout)
résolution d'un sudoku (fonctions)
s = [[0, 0, 0, 3, 0, 0, 8, 0, 0], \ [0, 0, 7, 9, 0, 8, 0, 0, 5], \ [0, 0, 0, 2, 0, 4, 1, 0, 0], \ [0, 9, 0, 8, 1, 0, 0, 4, 7], \ [0, 4, 0, 0, 0, 0, 0, 0, 6], \ [0, 0, 0, 0, 0, 0, 0, 0, 0], \ [0, 1, 0, 0, 0, 5, 0, 2, 0], \ [5, 3, 4, 0, 0, 0, 0, 0, 0], \ [0, 0, 0, 7, 0, 0, 0, 0, 0]] i = 0 j = 1 def chiffre_barre_ligne (s,r,i) : for k in range (0,9) : if s [i][k] > 0 : r [ s [i][k]-1 ] = 0 def chiffre_barre_colonne (s,r,j) : for k in range (0,9) : if s [k][j] > 0 : r [ s [k][j]-1 ] = 0 def chiffre_barre_carre (s,r,i,j) : a = i/3 * 3 b = j/3 * 3 for k in range (a,a+3) : for l in range (b,b+3) : if s [k][l] > 0 : r [ s [k][l]-1 ] = 0 def nombre_possible (s,i,j ) : r = [ 1,1,1,1,1,1,1,1,1] chiffre_barre_ligne (s,r,i) chiffre_barre_colonne (s,r,j) chiffre_barre_carre (s,r,i,j) return r def meilleure_case (s ) : dmin = 10 imin = jmin = -1 rmin = [] for i in range (0,9) : for j in range (0,9) : if s [i][j] == 0 : r = nombre_possible (s,i,j) d = sum (r) if d < dmin : dmin = d imin = i jmin = j rmin = r return imin,jmin,rmin def resolution (s) : imin,jmin,rmin = meilleure_case (s) if imin == -1 : return "jackpot" d = sum (rmin) if d == 1 : p = rmin.index (1) s [imin][jmin] = p+1 print "s modifie ",imin,jmin,p+1 a = resolution (s) if a == 0 : s [imin][jmin] = 0 return 0 else : return 1 elif d == 0 : print "on s'arrete" return 0 elif d > 1 : print "on continue" for n in range (0, 9) : if rmin [n] == 1 : s [imin][jmin] = n+1 a = resolution (s) if a == 0 : s [imin][jmin] = 0 else : return 1 return 0 resolution (s) for i in range (0,9) : print s[i]
résolution d'un sudoku (classes)
import copy import psyco psyco.full () class Sudoku : """definition d'un sudoku""" def __init__ (self, tab) : """tab est soit un entier indiquant la dimension du sudoku ou le sudoku lui-même""" try : i = tab [0][0] self.tab = tab self.dim = len (tab) except : self.dim = tab self.tab = [ [ 0 for i in range (0,self.dim) ] \ for j in range (0,self.dim) ] def __str__ (self) : """affiche un sudoku""" s = "" for i in range (0,self.dim) : if i % 3 == 0 and i > 0 : s += "\t------------------------------------------\n" s += "\t" for j in range (0,self.dim) : if j % 3 == 0 and j > 0 : s += "|\t" if self.tab [i][j] == 0 : s += "." else : s += str (self.tab [i][j]) s += "\t" s += "\n" return s def __getitem__ (self, p) : """retourne l'élément p [0], p [1] du sudoku""" return self.tab [p [0]][p [1]] def __setitem__ (self, p, v) : """change l'élément p [0], p [1] du sudoku""" self.tab [p [0]][p [1]] = v def filled (self) : """retourne le nombre de cases non vides""" n = 0 for i in range (0, self.dim) : for j in range (0, self.dim) : if self [ (i,j) ] > 0 : n += 1 return n def possible (self, i, j) : """retourne l'ensemble des nombres possibles pour pour la case i,j""" # vérification des contraintes sur les lignes et les colonnes if self.tab [i][j] > 0 : return [] se = [] for k in xrange (0, self.dim) : if self.tab [i][k] > 0 : se.append (self.tab [i][k]) if self.tab [k][j] > 0 : se.append (self.tab [k][j]) # vérification des contraintes dans chaque petit carré ii = int (i / 3) jj = int (j / 3) for iii in range (ii * 3, (ii+1)*3) : for jjj in range (jj * 3, (jj+1)*3) : if self.tab [iii][jjj] > 0 : se.append (self.tab [iii][jjj]) sol = [] for n in xrange (1, self.dim+1) : if n not in se : sol.append (n) return sol def get_best_solution (self, error = []) : """retourne la meilleure case à essayer, celle pour laquelle l'ensemble des nombres possibles est le plus petit : - 0 chiffre : configuration impossible, résultat = None - 1 chiffre : on avance, résultat = (i,j,[ c] ) - n > 1 chiffres : on essaye l'ensemble le moins grand, résultat = (i,j,[ c1, c2, c3, ...] ) """ # on regarde d'abord si c'est impossible for i in xrange (0,self.dim) : for j in xrange (0,self.dim) : if self.tab [i][j] > 0 : continue b = self.possible (i,j) if len (b) == 0 : return None # sinon best = None pos = None for i in xrange (0,self.dim) : for j in xrange (0,self.dim) : if (i,j) in error : continue b = self.possible (i,j) if len (b) == 1 : # une case où il y a une seule possibilité return (i,j,b) elif len (b) > 1 : # plusieurs possibilités, on prend l'ensemble le plus petit if best == None or len (best) > len (b) : pos = (i,j) best = b # résultat if best == None : return None else : return (pos [0], pos [1], best) class EnigmeSudoku : """résolution d'un Sudoku""" def __init__ (self, sudoku, display = True) : """définition de la classe qui résoud le Sudoku""" self.sudoku = sudoku def __str__ (self) : return str (self.sudoku) def resoud (self, solutioni = None) : # solution = [ ]) : """resolution, exploration en profondeur, fonction recursive""" if solutioni == None : # cas simple : première itération solutioni = copy.deepcopy (self.sudoku) self.count = 0 elif solutioni.filled () == solutioni.dim ** 2 : # second simple : le sudoku est terminé return solutioni solution = copy.deepcopy (solutioni) # pour compter le nombre d'itérations self.count += 1 # retourne la case la plus sympathique next = solutioni.get_best_solution () # s'il existe une case impossible if next == None : return None # sinon on essaye toutes les solutions pour cette case for n in next [2] : solution [ (next [0], next [1]) ] = n res = self.resoud (solution) if res != None : # réussi return res # toutes les solutions pour cette case mènent à une impasse return None if __name__ == "__main__" : sudoku_exemple = [ \ [5,3,0,0,7,0,0,0,0], \ [6,0,0,1,9,5,0,0,0], \ [0,9,8,0,0,0,0,6,0], \ [8,0,0,0,6,0,0,0,3], \ [4,0,0,8,0,3,0,0,1], \ [7,0,0,0,2,0,0,0,6], \ [0,6,0,0,0,0,2,8,0], \ [0,0,0,4,1,9,0,0,5], \ [0,0,0,0,8,0,0,7,9]] s = Sudoku (sudoku_exemple) print s print "-----------------------------\n" en = EnigmeSudoku (s) print "-----------------------------\n" sol = en.resoud () print "-----------------------------\n" print "iteration ", en.count print sol print "fin"
File: puzzle_girafe.tex, line 72
def compatible (self, bord) : return self.couleur == bord.couleur and self.partie != bord.partie
File: puzzle_girafe.tex, line 102
def voisin_possible (self, p, a) : d = p.position - self.position if abs (d) == 1 and (p.position - 1) / 3 == (self.position - 1) / 3 : # voisin en x return True elif abs (d) == 3 : # voisin en y return True else : # pas voisin return False
File: puzzle_girafe.tex, line 149
HOBBBVHM HOBBBVHM HBBMBVHO HMBBBVHB BMBOHBHV HVBMBOHM BMBVHBHO HVHMBBBO BMHOHVBB
File: puzzle_girafe.tex, line 176
def piece_position (self, pos) : for p in self.piece : if p.position == pos : return p return None
File: puzzle_girafe.tex, line 192
def ensemble_voisin (self, i) : i -= 1 res = [] for x in [-1,0,1] : for y in [-1,0,1] : if abs (x) == abs (y) : continue if x == -1 and i % 3 == 0 : continue if x == 1 and i % 3 == 2 : continue if y == -1 and i / 3 == 0 : continue if y == 1 and i / 3 == 2 : continue j = i + x + y * 3 if j in range (0,9) : res.append (j) return [ j+1 for j in res ]
File: puzzle_girafe.tex, line 218
def angle_possible (self, p, display = False) : voisin = self.ensemble_voisin (p.position) if display : print "voisin = ", voisin res = [] for a in [0,90,180,270] : r = True for v in voisin : piece = self.piece_position (v) if piece != None : r = r and piece.voisin_possible (p, a) if r : res.append (a) return res
ensemble des permutations
# coding: latin-1 def echange (l, i, j) : """permutation des éléments i et j de la liste l""" t = l [i] l [i] = l [j] l [j] = t def applique_permutation (set, p) : """applique la permutation p à l'ensemble set""" return [ set [k-1] for k in p ] def permutation (n) : if n == 1 : return [ [ 1 ] ] else : per = permutation (n-1) # permutation sur {1,...,n-1} set = [ i+1 for i in range (0,n) ] # ensemble de départ res = [] # résultat for i in range (0, n) : echange (set, 0, i) # échange élément 0 et i for p in per : # boucle sur les permutations de {1,...,n-1} pr = [ set [0] ] + applique_permutation ( set [1:], p ) res.append (pr) # on l'ajoute au résultat echange (set, 0, i) # échange élément 0 et i return res print (permutation (1)) # retourne [ [ 1 ] ] print (permutation (2)) # retourne [[1, 2], [2, 1]] print (permutation (3)) # retourne [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2]]
résolution d'un puzzle
# coding: cp1252 import pygame import random import copy import time class Bord : """définition d'un bord ou côté d'une pièce, il possède : - partie : une partie de la girafe (haut ou bas) - une couleur : la couleur de cette partie, (orange, violet, bleu clair, bleu foncé) """ def __init__ (self, definition) : """definition est une chaîne de 2 caractères qui définit un bord, exemple : HO pour haut orange BB pour bas bleu BV pour bas violet HM pour haut mauve """ if definition [0] == "H" : self.partie = "haut" elif definition [0] == "B" : self.partie = "bas" else : self.partie = definition + "###" if definition [1] == "O" : self.couleur = "orange" elif definition [1] == "B" : self.couleur = "bleu clair" elif definition [1] == "M" : self.couleur = "violet" elif definition [1] == "V" : self.couleur = "bleu fonce" else : self.couleur = definition + "##" def __str__ (self) : """cette méthode est appelée lorsqu'on exécute l'instruction print avec un objet de type Bord""" s = self.partie + " " + self.couleur return s def compatible (self, bord) : """dit si deux bords sont compatibles, c'est à dire de la même couleur et de partie différente""" return self.couleur == bord.couleur and self.partie != bord.partie class Piece : """définition d'une pièce du puzzle, celle-ci inclut : - bord : cette liste contient quatre objets de type Bord, cette liste ne changera plus - position : c'est la position de la pièce dans le puzzle, ce qui nous intéresse, c'est la position finale de la pièce dans le puzzle, cette information va donc bouger au fur et à mesure que nous allons essayer de résoudre le puzzle - orientation : de même que pour la position, une pièce peut être tournée sans changer de position, c'est le résultat final qui nous intéresse pour l'affichage, on ajoute deux informations : - name : le nom de l'image de la pièce - image : c'est la représentation de l'image dans la mémoire de l'ordinateur pour le module pygame """ def __init__ (self, name, definition, position, numero) : """ on définit la pièce - name : nom de l'image représentant la pièce - definition : chaîne de 8 caractères, c'est une suite de 4 x 2 caractères définissant chaque bord, voir la classe bord pour leur signification - position : c'est la position initiale de la pièce, on suppose que l'orientation est nulle pour commencer à partir de ces informations, on construit : - image : c'est la représentation en mémoire de l'image de la pièce - bord : c'est une liste qui définit les 4 bords de la pièce - orientation : c'est l'orientation de la pièce, au début de la résolution, elle est nulle """ self.name = name image = pygame.image.load (name) self.image = pygame.transform.scale (image, (250,250)) s = self.image.get_size () self.image_petite = pygame.transform.scale (self.image, (int(s[0]*0.7), int(s[1]*0.7))) self.bord = [] for i in range (0,4) : self.bord.append ( Bord (definition [i*2:i*2+2] ) ) self.orientation = 0 self.position = position self.numero = numero def __str__ (self) : """définition ce qu'on doit afficher lorsqu'on exécute l'instruction print avec un objet de type Piece""" s = str (self.position) + " : " for b in self.bord : s += str (b) + " - " s += " orientation " + str (self.orientation) s += " numero " + str (self.numero) return s def affiche (self, screen, position) : """affiche la pièce à l'écran en tenant compte de sa position et de son orientation""" if "darker" in self.__dict__ and self.darker : position = ( position [0] + 20, position [1] + 20 ) image = pygame.transform.rotate (self.image_petite, self.orientation) screen.blit (image, position) else : image = pygame.transform.rotate (self.image, self.orientation) screen.blit (image, position) def bord_angle (self, angle, orientation = None) : """retourne le bord connaissant l'orientation de la pièce, le bord demandé est celui correspondant à : - 0 bord droit - 90 bord haut - 180 bord gauche - 270 bord bas""" if orientation == None : return self.bord_angle (angle, self.orientation) else : dif = (angle - orientation + 360) % 360 / 90 return self.bord [dif] def voisin_possible (self, p, a) : """détermine si la pièce self peut être voisine avec la pièce p tournée de l'angle a""" d = p.position - self.position if abs (d) == 1 and (p.position - 1) / 3 == (self.position - 1) / 3 : # voisin en x if d == 1 : a1 = 0 a2 = a1 + 180 else : a1 = 180 a2 = 0 elif abs (d) == 3 : # voisin en y if d == 1 : a1 = 90 a2 = 270 else : a1 = 270 a2 = 90 else : # pas voisin return False b1 = self.bord_angle (a1) b2 = p.bord_angle (a2, a) return b1.compatible (b2) class Puzzle : """définition d'une classe puzzle, elle contient simplement une liste de 9 pièces dont les positions sont : 1 2 3 4 5 6 7 8 9 et les orientations choisies dans l'ensemble { 0,90,180,270 } """ def __init__ (self, dir = ".") : """on définit le puzzle à partir des informations contenus dans le répertoire dir qui doit contenir : - 9 images appelées piece0.png, ..., piece1.png - un fichier definition.txt contenant la définition de chacun des 4 bords de chacune des 9 pièces HOBBBVHM HOBBBVHM HBBMBVHO HMBBBVHB BMBOHBHV HVBMBOHM BMBVHBHO HVHMBBBO BMHOHVBB """ # on lit définition.txt f = open (dir + "/definition.txt") bo = f.readlines () f.close () # on définit chaque pièce self.piece = [] for i in range (1,10) : name = dir + "/piece" + str (i) + ".png" d = bo [i-1] p = Piece (name, d, 0, i) self.piece.append ( p ) def __str__ (self) : """ce qu'on doit afficher lorsqu'on exécute l'instruction print avec un objet de type Puzzle""" s = """1 2 3 4 5 6 7 8 9 """ for p in self.piece : s += str (p) + "\n" return s def pixel (self, position) : """retourne en fonction de la position (1 à 9) de la pièce sa position sur l'écran, soit deux coordonnées""" p = position - 1 ligne = p / 3 colonne = p % 3 return (colonne * 250, ligne * 250) def affiche (self, screen, petite = False) : """affiche les pièces sur l'écran, en plus petit pour celles qui ne sont pas encore placées""" screen.fill ((0,0,0)) free = [0 for i in self.piece] for p in self.piece : if p.position > 0 : p.darker = False p.affiche (screen, self.pixel (p.position)) free [p.position-1] = 1 if petite : em = [] for i in range (0, len (free)) : if free [i] == 0 : em.append (i+1) i = 0 for p in self.piece : if p.position == 0 : p.darker = True p.affiche (screen, self.pixel (em [i])) i += 1 pygame.display.flip () def meilleure_piece (self, free, pos) : """retourne la prochaine pièce à placer sur le puzzle, dans un premier temps, on peut prend la première qui vient, ensuite, on peut essayer un choix plus judicieux""" if len (free) == 0 : return None else : return free [0] def piece_position (self, pi) : """recherche la piece associée à la position pi""" for p in self.piece : if p.position == pi : return p return None def ensemble_voisin (self, i) : """retourne les positions voisins de la position i""" i -= 1 res = [] for x in [-1,0,1] : for y in [-1,0,1] : if abs (x) == abs (y) : continue if x == -1 and i % 3 == 0 : continue if x == 1 and i % 3 == 2 : continue if y == -1 and i / 3 == 0 : continue if y == 1 and i / 3 == 2 : continue j = i + x + y * 3 if j in range (0,9) : res.append (j) return [ j+1 for j in res ] def nb_place (self) : """retourne le nombre de places vides""" i = 0 for p in self.piece : if p.position == 0 : i += 1 return i def angle_possible (self, p, display = False) : """retourne l'ensemble des angles possibles pour une pièce donnée""" voisin = self.ensemble_voisin (p.position) if display : print "voisin = ", voisin res = [] for a in [0,90,180,270] : r = True for v in voisin : piece = self.piece_position (v) if piece != None : r = r and piece.voisin_possible (p, a) if r : res.append (a) return res def solution (self, pos = 1, screen = None) : if pos == 1 : for p in self.piece : p.position = 0 self.nb_position = 0 self.essai = 0 self.essai += 1 if self.nb_position == len (self.piece) : time.sleep (0.2) return # le tableau free mémorise l'ensemble des pièces non encore placées free = [] for p in self.piece : if p.position == 0 : free.append (p) if screen != None : self.affiche (screen, True) pygame.display.flip () p = self.meilleure_piece (free, pos) # si p == None, on n'étudie pas les solutions avec les pièces placées # avant aux positions 1 à pos --> on n'entrera pas dans la boucle suivante while p != None : p.position = pos angle = self.angle_possible (p) # p est la pièce choisie, pour cette pièce # on passe en revue toutes les orientations for a in angle : p.orientation = a time.sleep (0.2) # temporisation if self.nb_place () == 0 : return True else : r = self.solution (pos+1, screen = screen) if r : return True p.position = 0 # on réactualise le tableau free qui aura été modifié par # l'appel à self.solution et on enlève le choix précédemment testé free2 = free free = [] for f in free2 : if f.numero != p.numero : free.append (f) # on passe au choix suivant avec free contenant les pièces # placées et les pièces essayées p = self.meilleure_piece (free, pos) def attendre_clic (): """attend la pression d'un clic de souris""" reste = True while reste: for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONUP : reste = False break if __name__ == "__main__" : # taille de l'écran size = (750,750) # initialisation du module pygame pygame.init () screen = pygame.display.set_mode (size) # on définit le puzzle p = Puzzle () # on affiche le puzzle avec print (format texte) print p # on affiche le puzzle à l'écran p.affiche (screen, petite = True) attendre_clic () # on rafraîchit l'écran pour que le puzzle apparaissent pygame.display.flip () # on trouve la solution r = p.solution (screen = screen) print "résolution ", r print "appelle à la méthode solution ", p.essai # on attend la pression d'un clic de souris avant de terminer le programme p.affiche (screen, petite = True) attendre_clic ()
suite de Syracuse
def syracuse (u0) : suite = [ ] ops = [ ] u = u0 while u != 1 : suite.append (u) if u % 2 == 0 : ops.append (1) u = u/2 else : u = (3*u+1) / 2 ops.append (0) suite.append(u) suite.append(0) ops.reverse() return suite, ops def base2 (ops) : s = 0.0 i = 1 for k,v in enumerate(ops) : if v == 1 : s += i i *= 2 return s if __name__ == "__main__" : for i in range (1,30) : s,o = syracuse(i) t = max ( [ _ for _ in s if _%2 == 1] ) n = base2(o) print "% 3d len % 3d %d %d suite" % (i,len(s), t, n), o,s
File: syracuse.tex, line 111
1 len 1 suite [1] 2 len 2 suite [2, 1] 3 len 6 suite [3, 5, 8, 4, 2, 1] 4 len 3 suite [4, 2, 1] 5 len 5 suite [5, 8, 4, 2, 1] 6 len 7 suite [6, 3, 5, 8, 4, 2, 1] 7 len 12 suite [7, 11, 17, 26, 13, 20, 10, 5, 8, 4, 2, 1] 8 len 4 suite [8, 4, 2, 1] 9 len 14 suite [9, 14, 7, 11, 17, 26, 13, 20, 10, 5, 8, 4, 2, 1] 10 len 6 suite [10, 5, 8, 4, 2, 1] 11 len 11 suite [11, 17, 26, 13, 20, 10, 5, 8, 4, 2, 1] 12 len 8 suite [12, 6, 3, 5, 8, 4, 2, 1] 13 len 8 suite [13, 20, 10, 5, 8, 4, 2, 1] 14 len 13 suite [14, 7, 11, 17, 26, 13, 20, 10, 5, 8, 4, 2, 1] 15 len 13 suite [15, 23, 35, 53, 80, 40, 20, 10, 5, 8, 4, 2, 1] 16 len 5 suite [16, 8, 4, 2, 1]
résolution de l'énigme d'Einstein
# http://en.wikipedia.org/wiki/Zebra_Puzzle # http://fr.wikipedia.org/wiki/Int%C3%A9gramme import os, sys, copy #: definition of all possible values (French terms) #: colors ttcouleur = ["jaune", "bleu", "rouge", "blanc", "vert"] #: nationalities ttnationalite = ["danois", "norvegien", "anglais", "allemand", "suedois"] #: drinks ttboisson = ["eau", "the", "lait", "cafe", "biere"] #: smoke brand ttcigare = ["Dunhill", "Blend", "Pall Mall", "Prince", "Bluemaster"] #: animal ttanimal = ["chats", "cheval", "oiseaux", "poisson", "chiens"] #: all possibles values ensemble = [ ttcouleur, ttnationalite, ttboisson, ttcigare, ttanimal ] def permutation (nb) : """ Compute all permutation of set [[ 1, 2, ..., nb ]]. Example for 3: @code [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]] @endcode @param nb permutation over the set [[1..n]] @return list of all possible permutation @warning This method can be very long if nb is high (>10). """ per = [] p = [i for i in range (0,nb)] while p [0] < nb : next = False for i in range (1,nb) : if p [i] in p [0:i] : next = True break if not next : per.append (copy.copy (p)) p [nb-1] += 1 for j in range (nb-1, 0, -1) : if p [j] >= nb : p [j] = 0 p [j-1] += 1 return per class Rule : """ this class defines a constraint of the problem or a clause (see `http://en.wikipedia.org/wiki/Clause_(logic)`) There are 5 different types of clauses described by Einstein's enigma each of them is described by a different class. There are defined by classes: @ref cl RulePosition, @ref cl RuleEquivalence, @ref cl RuleVoisin, @ref cl RuleAvant, @ref cl RuleEnsemble. """ def __init__ (self) : """constructor """ #: name of the rule self.name = None #: set of clauses self.set = None def genere (self) : """generates all possible clauses (list of lists) (l [0][0] et l [0][1]) ou (l [1][0] et l [1][1]), a clause is a triplet of (person, (property, category) )""" return None def __str__ (self) : """display """ if self.name != None : if "clauses" not in self.__dict__ : s = self.name + " \t: " a = self.genere () for al in a : st = "\n ou " + str (al) if len (st) > 260 : st = st [:260] + "..." s += st if len (s) > 1000 : break return s else : s = self.name + " \t: " + str (self.set) for al in self.clauses : st = "\n ou " + str (al) if len (st) > 260 : st = st [:260] + "..." s += st if len (s) > 1000 : break return s else : return "None" def combine (self, cl1, cl2) : """combine two clauses, two cases : 1. nothing in common or everything in common --> concatenation of clauses 2. a position or a property in common --> null clause @param cl1 clause 1 @param cl2 clause 2 @return the new clause A clause is a @ref cl Rule. """ # incompatibility for p1 in cl1 : for p2 in cl2 : if p1 [1][0] == p2 [1][0] : # same property if p1 [0] != p2 [0] : # but different positions return None if p1 [0] == p2 [0] : # same person if p1 [1][1] == p2 [1][1] and p1 [1][0] != p2 [1][0] : # same category but different properties return None # compatibility r = copy.deepcopy (cl1) for c in cl2 : if c not in r : r.append (c) return r def combine_cross_sets (self, set1, set2) : """ combines two sets of clauses @param set1 set of clauses 1 @param set2 set of clauses 2 @return combination """ if len (set1) == 0 : return copy.deepcopy (set2) if len (set2) == 0 : return copy.deepcopy (set1) res = [] for cl1 in set1 : for cl2 in set2 : r = self.combine (cl1, cl2) if r != None : res.append (r) return res class RulePosition (Rule) : """p1 at position """ def __init__ (self, p1, pos) : self.set = [p1] self.name = "position" self.position = pos def genere (self) : return [ [ ( self.position, self.set [0]) ] ] class RuleEquivalence (Rule) : """p1 equivalent to p2 """ def __init__ (self, p1, p2) : self.set = [p1, p2] self.name = "equivalence" def genere (self) : l = [] for i in range (0,5) : l.append ( [ (i, self.set [0]), (i, self.set [1]) ] ) return l class RuleVoisin (Rule) : """p1 and p2 are neighbors """ def __init__ (self, p1, p2) : self.set = [p1, p2] self.name = "voisin" def genere (self) : l = [] for i in range (0,4) : l.append ( [ (i, self.set [0]), (i+1, self.set [1]) ] ) l.append ( [ (i+1, self.set [0]), (i, self.set [1]) ] ) return l class RuleAvant (Rule) : """ p1 before p2 """ def __init__ (self, p1, p2) : self.set = [p1, p2] self.name = "avant" def genere (self) : l = [] for j in range (1,5) : for i in range (0,j) : l.append ( [ (i, self.set [0]), (j, self.set [1]) ] ) return l class RuleEnsemble (Rule) : """permutation of the elements of a category """ def __init__ (self, set, categorie) : self.set = [ (s,categorie) for s in set ] self.name = "ensemble" def genere (self) : l = [] per = permutation (5) for p in per : tl = [] for i in range (0,len (p)) : tl.append ( (i, self.set [p [i]]) ) l.append (tl) return l class Enigma : """ this class solves the enigma """ def __init__ (self, display = True) : """ we describe the enigma using the classes we defined above @param display if True, use print to print some information """ self.regle = [] self.regle.append ( RulePosition (self.find ("lait") , 2) ) self.regle.append ( RulePosition (self.find ("norvegien"), 0) ) self.regle.append ( RuleEquivalence (self.find ("Pall Mall"), self.find ("oiseaux")) ) self.regle.append ( RuleEquivalence (self.find ("anglais"), self.find ("rouge")) ) self.regle.append ( RuleEquivalence (self.find ("suedois"), self.find ("chiens")) ) self.regle.append ( RuleEquivalence (self.find ("danois"), self.find ("the")) ) self.regle.append ( RuleEquivalence (self.find ("vert"), self.find ("cafe")) ) self.regle.append ( RuleEquivalence (self.find ("jaune"), self.find ("Dunhill")) ) self.regle.append ( RuleEquivalence (self.find ("biere"), self.find ("Bluemaster")) ) self.regle.append ( RuleEquivalence (self.find ("allemand"), self.find ("Prince")) ) self.regle.append ( RuleVoisin (self.find ("Dunhill"), self.find ("cheval")) ) self.regle.append ( RuleVoisin (self.find ("norvegien"), self.find ("bleu")) ) self.regle.append ( RuleVoisin (self.find ("Blend"), self.find ("eau")) ) self.regle.append ( RuleVoisin (self.find ("Blend"), self.find ("chats")) ) self.regle.append ( RuleAvant (self.find ("vert"), self.find ("blanc")) ) self.regle.append ( RuleEnsemble (ttcouleur, 0 )) self.regle.append ( RuleEnsemble (ttnationalite, 1) ) self.regle.append ( RuleEnsemble (ttboisson, 2) ) self.regle.append ( RuleEnsemble (ttcigare, 3 )) self.regle.append ( RuleEnsemble (ttanimal, 4 )) for r in self.regle : r.clauses = r.genere () r.utilise = False self.count = 0 def find (self, p) : for i in range (0, len (ensemble)) : if p in ensemble [i] : return (p, i) return None def __str__ (self) : if "solution" not in self.__dict__ or self.solution == None or len (self.solution) == 0 : if self.count > 0 : s = "solution impossible apres " + str (self.count) + " iterations \n" else : s = "" for r in self.regle : s += str (r) + "\n" return s else : sr = ["solution, iteration " + str (self.count)] matrix = [ list( " "*5) for _ in range(0,5) ] for row in self.solution : i = row[0] j = row[1][1] s = row[1][0] matrix[i][j] = s + " " * (10 - len(s)) for row in matrix : sr.append ( ", ".join (row) ) classic = "\n".join(sr[1:]) html = classic.replace(",","</td><tr>").replace("\n","</td></tr>\n<tr><td>") return sr[0]+"\n" + "\n".join( [ classic, "<table>", "<tr><td>" + html + "</td></tr>", "</table>" ] ) def solve (self, solution = [], logf = print) : # solution = [ ]) : """solve the enigma by eploring in deepness, the method is recursive @param solution [] empty at the beginning, recursively used then """ self.count += 1 if self.count % 10 == 0 : logf ("*",self.count, " - properties in place : ", len (solution)-1) if len (solution) == 25 : # we know the solution must contain 25 clauses, # if are here than the problem is solved unless some incompatibility for r in self.regle : cl = r.combine_cross_sets ([ solution ], r.clauses) if cl == None or len (cl) == 0 : # the solution is incompatible with a solution return None self.solution = solution return solution # we are looking for the rule which generates the least possible clauses # in order to reduce the number of possibilities as much as possible # the research could be represented as a tree, we avoid creating two many paths best = None rule = None for r in self.regle : cl = r.combine_cross_sets ([ solution ], r.clauses) if cl == None : # the solution is incompatible with a solution return None # we chech rule r is bringing back some results for c in cl : if len (c) > len (solution) : break else : cl = None if cl != None and (best == None or len (best) > len (cl)) : best = cl rule = r if best == None : # the solution is incompatible with a solution return None rule.utilise = True # we test all clauses for c in best : r = self.solve (c, logf = logf) if r != None : # we found return r rule.utilise = False # impossible return None if __name__ == "__main__" : en = Enigma () print (en) print ("-----------------------------\n") en.solve () print ("-----------------------------\n") print (en)
énigme de Harry Potter, tome 1 (avec des fonctions)
def solution_correcte (sol) : """cette fonction recoit un tableau de 7 cases, chaque case contient un entier compris entre 0 et 3 inclus : 0 : poison, 1 : vin, 2 : reculer, 3 : avancer la fonction determine si l'agencement propose dans sol verifie les cinq regles de l'enonce, retourne True si toutes les regles sont verifiees ou False si l'une des regles n'est pas verifiee, rappel : les indices vont de 0 a 6 inclus car il y a 7 cases""" # regle 1 nb = [0,0,0,0] for s in sol : nb [s] += 1 if nb [0] != 3 : return False # 3 poison if nb [1] != 2 : return False # 2 vin if nb [2] != 1 : return False # 1 reculer if nb [3] != 1 : return False # 1 avancer # regle 2 for i in range (1,len (sol)) : if sol [i] == 1 and sol [i-1] != 0 : return False # regle 3 if sol [0] == sol [6] : return False if sol [0] == 3 : return False if sol [6] == 3 : return False # regle 4 if sol [2] == 0 : return False if sol [5] == 0 : return False # regle 5 if sol [1] != sol [5] : return False # si on arrive ici, c'est que toutes les regles sont verifiees return True def affiche_solution (sol) : a = ["poison", "vin", "reculer", "avancer"] res = "" for s in sol : res += "{0}, ".format(a [s]) return res # seconde idee : 2 boucles seulement pour # parcourir toutes les solutions def solution(): sol = [ 0,0,0,0,0,0,0] while sol [0] < 4 : r = solution_correcte (sol) if r : return sol sol [6] += 1 for i in range (len (sol)-1, 0, -1) : # on parcourt les indices en # allant de 6 a 1 inclus if sol [i] >= 4 : sol [i] = 0 sol [i-1] += 1 if __name__ == "__main__": res = solution() print(affiche_solution(res))
énigme de Harry Potter, tome 1 (avec des classes)
contenu_case = ["poison", "vin", "reculer", "avancer"] class Case : def __init__ (self, contenu) : self.contenu = contenu_case.index (contenu) def __str__ (self) : return contenu_case [self.contenu] class Regle1 : def correcte (self, cases) : nb = [0,0,0,0] for s in cases : nb [s.contenu] += 1 if nb [0] != 3 : return False # 3 poison if nb [1] != 2 : return False # 2 vin if nb [2] != 1 : return False # 1 reculer if nb [3] != 1 : return False # 1 avancer return True class Regle2 : def correcte (self, cases) : for i in range (1,len (cases)) : if cases [i].contenu == 1 and cases [i-1].contenu != 0 : return False return True class Regle3 : def correcte (self, cases) : if cases [0].contenu == cases [6].contenu : return False if cases [0].contenu == 3 : return False if cases [6].contenu == 3 : return False return True class Regle4 : def correcte (self, cases) : if cases [2].contenu == 0 : return False if cases [5].contenu == 0 : return False return True class Regle5 : def correcte (self, cases) : if cases [1].contenu != cases [5].contenu : return False return True class Enigme : def __init__ (self) : self.regle = [ Regle1 (), Regle2 (), Regle3 (), Regle4 (), Regle5 ()] self.cases = [ Case ("poison") for i in range (0,7) ] def __str__ (self) : for s in self.cases : print (s, ", ",) print ("") def solution_correcte (self) : for r in self.regle : if not r.correcte (self.cases) : return False return True def resoud (self) : for c in self.cases : c.contenu = 0 while self.cases [0].contenu < 4 : r = self.solution_correcte () if r : print (self.__str__ ()) self.cases [6].contenu += 1 for i in range (len (self.cases)-1, 0, -1) : # on parcourt les indices en # allant de 6 a 1 inclus if self.cases [i].contenu >= 4 : self.cases [i].contenu = 0 self.cases [i-1].contenu += 1 e = Enigme () e.resoud ()
File: vigenere.tex, line 11
ABCDEFGHIJKLMNOPQRSTUVWXZ BCDEFGHIJKLMNOPQRSTUVWXZA CDEFGHIJKLMNOPQRSTUVWXZAB DEFGHIJKLMNOPQRSTUVWXZABC EFGHIJKLMNOPQRSTUVWXZABCD FGHIJKLMNOPQRSTUVWXZABCDE GHIJKLMNOPQRSTUVWXZABCDEF HIJKLMNOPQRSTUVWXZABCDEFG IJKLMNOPQRSTUVWXZABCDEFGH JKLMNOPQRSTUVWXZABCDEFGHI KLMNOPQRSTUVWXZABCDEFGHIJ LMNOPQRSTUVWXZABCDEFGHIJK MNOPQRSTUVWXZABCDEFGHIJKL NOPQRSTUVWXZABCDEFGHIJKLM OPQRSTUVWXZABCDEFGHIJKLMN PQRSTUVWXZABCDEFGHIJKLMNO QRSTUVWXZABCDEFGHIJKLMNOP RSTUVWXZABCDEFGHIJKLMNOPQ STUVWXZABCDEFGHIJKLMNOPQR TUVWXZABCDEFGHIJKLMNOPQRS UVWXZABCDEFGHIJKLMNOPQRST VWXZABCDEFGHIJKLMNOPQRSTU WXZABCDEFGHIJKLMNOPQRSTUV XZABCDEFGHIJKLMNOPQRSTUVW ZABCDEFGHIJKLMNOPQRSTUVWX ABCDEFGHIJKLMNOPQRSTUVWXZ
File: vigenere.tex, line 42
lescodessecretsontjoueunrolediscretmaisimportantdanslhistoire CODECODECODECODECODECODECODECODECODECODECODECODECODECODECODEC
File: vigenere.tex, line 49
lescodessecretsontjoueunrolediscretmaisimportantdanslhistoire CODECODECODECODECODECODECODECODECODECODECODECODECODECODECODEC NSV...
code de Vigenère
al = "abcdefghijklmnopqrstuvwxyz" al = al.upper () carre = [] for i in range (0,26) : carre.append (al) al = al [1:26] + al [0] for c in carre : print c
décryptage du code de Vigenère
def CarreVigenere () : """creation du carre de Vigenere""" al = "abcdefghijklmnopqrstuvwxyz" al = al.upper () carre = [] for i in range (0,26) : carre.append (al) al = al [1:26] + al [0] return carre def CodeVigenere (message, cle, carre) : """code un message selon le code de Vigenere, message est le message a coder cle est la cle carre est le carre de Vigenere""" alphabet = carre [0] # contient l'alphabet (premiere ligne du carre) resultat = "" # contiendra le message code # on parcourt le message for i in range (0, len (message)) : # j est la position de la lettre dans le cle # associee a la lettre i dans le message # % retourne le reste d'une division entiere j = i % len (cle) a = alphabet.find (message [i]) # numero de la lettre message [i] b = alphabet.find (cle [j]) # numero de la lettre cle [j] c = carre [b][a] resultat += c return resultat def DecodeVigenere (message, cle, carre) : """decode un message selon le code de Vigenere, message est le message a decoder cle est la cle carre est le carre de Vigenere""" alphabet = carre [0] # contient l'alphabet (premiere ligne du carre) resultat = "" # contiendra le message code # on parcourt le message for i in range (0, len (message)) : # j est la position de la lettre dans le cle # associee a la lettre i dans le message # % retourne le reste d'une division entiere j = i % len (cle) b = alphabet.find (cle [j]) # numero de la lettre cle [j] a = carre [b].find (message [i]) # numero de la lettre message [i] # dans la ligne du carre correspondant # au decalage introduit par cle [j] c = carre [0][a] resultat += c return resultat message = "ceci est le message non code sans signe de ponctuation" message = message.replace (" ", "") message = message.upper () cle = "VIGENERES" carre = CarreVigenere () code = CodeVigenere (message, cle, carre) decode = DecodeVigenere (code, cle, carre) print "------------------ cle" print cle print "------------------ message" print message print "------------------ message code" print code print "------------------ message decode" print decode print "------------------" if decode == message : print "message bien retranscrit" else : print "message mal retranscrit" ############################################################################# ############################################################################# ############################################################################# print "" print "####################################################################" print "seconde partie : decoder sans la cle" print "cette methode ne marche que sur un message plus long ou de nombreux" print "message mis bout a bout, on essaye la methode sur le fichier :" print "hugo_dernier_jour_condamne.txt" print "####################################################################" def PGCD (m,n) : """determine le PGCD""" if m == 1 or n == 1 : return 1 if m == n : return m if m < n : return PGCD (m, n-m) return PGCD (n, m-n) def DecodeVigenereLongueurCle (message, mot = 3) : """cette fonction determine la longueur de la cle, elle repere les groupes de trois lettres qui se repete dans le message code et suppose qu'il y une tres forte probabilite qu'un meme groupe de trois soit code avec les memes trois lettres du message et les memes trois lettres de la cle message : .....DES...........DES...........DES.........DES....DES cle : ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD code : .....EGV.........................EGV.........EGV.......... distance : <----------24--------------><----8-----> la longueur de la cle divise le PGCD de 24 et 8 """ al = "abcdefghijklmnopqrstuvwxyz" al = al.upper () # parcours du message pour recenser toutes les positions dico = {} for i in xrange (0, len (message)-2) : t = message [i:i+mot] if dico.has_key (t) : dico [t].append (i) else : dico [t] = [i] # on va garder toutes les distances entre # entre deux occurrences du meme mot de n lettres dis = [] for d in dico : p = dico [d] if len (p) > 1 : for i in range (0, len (p)-1) : #print d, p [i+1] - p [i], " --- ", float (p [i+1] - p [i]) / 8 dis.append ( p [i+1] - p [i] ) # on extrait le PGCD if len (dis) == 0 : print "impossible de determiner la cle" return 0 if len (dis) == 1 : return dis [0] longueur = PGCD (dis [0], dis [1]) for d in dis : longueur = PGCD (longueur, d) if longueur > 5 : # si la longueur est suffisante, le resultat a des chances d'etre bon return longueur else : # sinon, on relance l'algorithme avec des mots plus grand return DecodeVigenereLongueurCle (message, mot+1) def DecodeVigenereCle (code, l) : """determine la cle du message code, connaissant sa longueur, on suppose que la lettre E est la lettre la plus frequente """ al = "abcdefghijklmnopqrstuvwxyz" al = al.upper () cle = "" for i in xrange (0, l) : nombre = [ 0 for a in al] sous = code [i:len (code):l] # on extrait toutes les lettres # i, i+l, i+2l; i+3l, ... # on compte les lettres for k in sous : nombre [ al.find (k) ] += 1 # on cherche le maximum p = 0 for k in range (0, len (nombre)) : if nombre [k] > nombre [p] : p = k # on suppose que al [p] est la lettre E code, # il ne reste plus qu'a trouver la lettre de la cle # qui a permis de coder E en al [p] cle += al [ (p + 26 - al.find ("E")) % 26 ] return cle # on lit Victor Hugo f = open ("hugo_dernier_jour_condamne.txt") message = f.read () # lit tout d'une seule traite f.close () # on limite la taille du fichier message = message [5000:7000] # on enleve les signes de ponctuation et on met en majuscule message = message.replace ("\n", "") message = message.replace ("\r", "") message = message.replace ("\t", "") message = message.replace (" ", "") message = message.replace (",", "") message = message.replace (";", "") message = message.replace (":", "") message = message.replace (".", "") message = message.replace ("'", "") message = message.replace ("\"", "") message = message.replace ("-", "") message = message.replace ("!", "") message = message.replace ("?", "") message = message.replace ("(", "") message = message.replace (")", "") message = message.upper () # on code print "on code, longueur du message ", len (message) code = CodeVigenere (message, cle, carre) memoire = cle cle = None # on oublie la cle # on determine la longueur de la cle l = DecodeVigenereLongueurCle (code) # on determine la cle en suppose que la lettre E est la plus frequente # ne marche pas pour les textes anglais cle_code = DecodeVigenereCle (code, l) # decode le texte decode = DecodeVigenere (code, cle_code, carre) print "------------------ vraie" print memoire print "------------------ cle trouve par Babbage" print "longueur ", l, " cle : ", cle_code if memoire == cle_code : print "bonne cle" else : print "mauvaise cle" print "------------------ message" print message [:200] print "------------------ message code" print code [:200] print "------------------ message decode" print decode [:200] print "------------------" if decode == message : print "message bien retranscrit" else : for i in xrange (0, len (decode)) : if message[i] != decode [i] : print i, message[i], decode[i] print "message mal retranscrit"
File: position_table_cor.tex, line 24
def trois_pareil (table) : """table est une suite booleens, on retourne True s'il n'y en a pas trois consecutifs""" for i in xrange (len (table)-2) : if table [i] == table [i+1] == table [i+2] : return False return True def compte (n) : """on parcours toutes les tables possibles et on compte les bonnes configurations""" table = [ False for i in range (0,n) ] nb = 0 bon = 0 while table [0] != None : if n == 5 and trois_pareil (table) : print table nb += 1 if trois_pareil (table) : bon += 1 for i in xrange (len (table)-1, -1, -1) : if not table [i] : table [i] = True break else : table [i] = False if i == 0 : table [0] = None return nb, bon for n in range (3, 15) : nb, bon = compte (n) print n, " nb = ", nb, " bon = ", bon, " mauvais = ", print " proba = ", print float (bon) / float (nb), " \t", print bon, "/", nb
File: position_table_cor.tex, line 194
HFF FFH FHH HHH HHF
File: position_table_cor.tex, line 278
HFF FFH FHH HHF HFF
File: position_table_cor.tex, line 287
HFF FFH FHH HHF HFF FFH ajouté FHF ajouté
table équilibrée
############################################################################### # questions 1 a 5 ############################################################################### def lit_fichier (nom) : """cette fonction lit le contenu d'un fichier et retourne une liste contenant ses lignes""" f = open (nom, "r") li = f.readlines () f.close () r =[] for l in li : s = l.replace ("\n", "") s = s.replace ("\r", "") r.append (s) return r def genre (prenom, femme, homme) : """retourne le genre d'un prenom""" if prenom in femme : return True if prenom in homme : return False return None def contrainte (table, femme, homme) : """cette fonction verifie que la table obeit aux contrainte d'Harmonie : il ne peut y avoir trois personnes voisines du meme sexe qui se suivent""" ge = [ genre (t,femme, homme) for t in table ] for i in range (0,len (ge)) : if ge [i] == ge [ (i+1) % len (ge) ] == ge [(i+2) % len (ge) ] : return False return True def dominique (table, femme, homme) : """cette fonction dit si on peut placer dominique, deux schemas de figures possibles : 1- H F dominique H F 2- F H dominique F H """ ge = [ genre (t,femme, homme) for t in table ] for i in range (0,len (ge)) : if ge [i] != ge [ (i+1) % len (ge) ] and \ ge [(i+2) % len (ge)] != ge [ (i+3) % len (ge) ] and \ ge [i] == ge [ (i+2) % len (ge) ] : return True return False femme = lit_fichier ("femme.txt") homme = lit_fichier ("homme.txt") table = lit_fichier ("table.txt") r = contrainte (table, femme, homme) print "la table suit les desirs d'Harmonie : ", r r = dominique (table, femme, homme) print "peut-on ajouter Dominique : ", r ############################################################################### # question 6 ############################################################################### def contrainte_dominique (table, femme, homme) : """meme fonction que contrainte mais on tient aussi du fait que le genre peut etre indetermine (None), toute configuration incertaine est eliminee""" ge = [ genre (t,femme, homme) for t in table ] for i in range (0,len (ge)) : if ge [i] == ge [ (i+1) % len (ge) ] == ge [(i+2) % len (ge) ] : return False if ge [i] == None and ge [ (i+1) % len (ge) ] == ge [(i+2) % len (ge) ] : return False if ge [i] == ge [ (i+1) % len (ge) ] and ge [(i+2) % len (ge) ] == None : return False if ge [i] == ge [ (i+2) % len (ge) ] and ge [(i+1) % len (ge) ] == None : return False if ge [i] == None and ge [ (i+1) % len (ge) ] == None : return False if ge [i] == None and ge [ (i+2) % len (ge) ] == None : return False if ge [ (i+2) % len (ge) ] == None and ge [ (i+1) % len (ge) ] == None : return False return True def place_dominique (table, femme, homme) : """on cherche a inserer autant de dominique que possible""" nb = len (table) fin = False while not fin : fin = True for i in range (0, len (table)) : table.insert (i, "DOMINIQUE") r = contrainte_dominique (table, femme, homme) if r : fin = False break else : del table [i] return len (table) - nb print "-----------------------------------------------------------------" nb = place_dominique (table, femme, homme) print "nombre de dominique ", nb for p in table : print p ############################################################################### # question 7 ############################################################################### # # nombre minimal : partie entiere de (n+1)/2 # nombre maximal : 2n # ############################################################################### # question 8 ############################################################################### def trois_pareil (table) : """table est une suite booleens, on retourne True s'il n'y en a pas trois consecutifs""" for i in xrange (len (table)-2) : if table [i] == table [i+1] == table [i+2] : return False return True def trois_pareil_rond (table) : """table est une suite booleens, on retourne True s'il n'y en a pas trois consecutifs""" for i in xrange (len (table)) : if table [i] == table [ (i+1) % len (table)] == table [(i+2) % len (table)] : return False return True def compte (n) : """on parcours toutes les tables possibles et on compte les bonnes configurations""" table = [ False for i in range (0,n) ] nb = 0 bon = 0 while table [0] != None : nb += 1 if trois_pareil_rond (table) : bon += 1 for i in xrange (len (table)-1, -1, -1) : if not table [i] : table [i] = True break else : table [i] = False if i == 0 : table [0] = None return nb, bon print "-----------------------------------------------------------------" print "calcul en parcourant toutes les tables possibles" print "-----------------------------------------------------------------" for n in range (3, 15) : nb, bon = compte (n) print n, " nb = ", nb, " bon = ", bon, print " proba = ", float (bon) / float (nb), " \t", print bon, "/", nb ############################################################################### # question 8 # markov ############################################################################### # module pour le calcul matriciel import numpy import copy def construit_matrice () : """construit la matrice de transition, le vecteur des probabilites d'entrees dans chaque etat""" # construction des etats etat = [] for i in range (0,2) : for j in range (0,2) : for k in range (0,2) : etat.append ( (i,j,k) ) # construction de la matrice mat = [] for i in range (0, len (etat)) : l = [] for j in range (0, len (etat)) : if etat [i] [1:3] == etat [j] [0:2] : # (i,j,k) --> (j,k,0) ou (j,k,1) l.append (1) else : l.append (0) # on renormalise sur chaque ligne s = sum (l) for j in range (0, len (etat)) : l[j] /= float (s) mat.append (l) entree = [ 0.125 for i in range (0,8) ] return etat, numpy.matrix (mat), numpy.matrix (entree) def calcul_probabilite_droite (n, etat, mat_, entree) : """calcule les probabilites pour une table droite""" pos = [ etat.index ( (0,0,0) ), etat.index ( (1,1,1) ) ] temp = copy.deepcopy (entree) mat = copy.deepcopy (mat_) for p in pos : for i in range (0,8) : mat [ (p,i) ] = 0.0 mat [ (p,p) ] = 1.0 m = mat ** (n-1) sum = 0.0 for i in range (0,8) : for j in range (0,8) : if i not in pos and j not in pos : sum += m [ (i,j) ] * mat [ (j,i) ] return sum print "-----------------------------------------------------------------" print "calcul avec les chaines de Markov" print "-----------------------------------------------------------------" etat,mat,entree = construit_matrice () for n in range (3,15) : proba = calcul_probabilite_droite (n, etat, mat, entree) print n, " bon ", proba
décomposition d'une fraction ractionnelle
#include "stdio.h" #include "string.h" ////////////////////////////////////////////////////////////////////// typedef struct { double *C ; int Ligne ; int Colonne ; } Matrice ; typedef struct { double *C ; int Degre ; } Polynome ; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // fonction matricielle // crée une matrice Matrice matrice_new (int ligne, int colonne) ; // crée une matrice carrée identité Matrice matrice_new_identite (int ligne) ; // libère une matrice void matrice_free (Matrice *mat) ; // change la valeur d'un coefficient void matrice_change (Matrice *mat, int i, int j, double val) ; // retourne la valeur d'un coefficient double matrice_donne (Matrice *mat, int i, int j) ; // fait une copie de matrice Matrice matrice_copie (Matrice *mat) ; // produit de matrice Matrice matrice_produit (Matrice *mat1, Matrice *mat2) ; // écrire une matrice char *matrice_ecrit (Matrice *mat) ; // réalise le pivot de Gauss // et retourne la matrice de passage Matrice matrice_pivot_gauss (Matrice *mat) ; // réalise le pivot de Gauss de haut en bas // et retourne la matrice de passage Matrice matrice_pivot_gauss_inverse (Matrice *mat) ; // utilise les deux fonctions précédentes pour calculer l'inverse d'une matrice // la matrice mat rste inchangée Matrice matrice_inverse (Matrice *mat) ; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // crée un polynôme Polynome polynome_new (int degre) ; // libère un polynôme void polynome_free (Polynome *p) ; // change la valeur d'un coefficient (celui devant le monôme de degré n) void polynome_change (Polynome *p, int n, double val) ; // retourne la valeur d'un coefficient double polynome_donne (Polynome *p, int n) ; // retourne une chaîne char *polynome_ecrit (Polynome *p) ; // multiplie deux polynôme Polynome polynome_produit (Polynome *p1, Polynome *p2) ; // effectue la decomposition d'une fraction rationnelle // resultat contient les resultats // première dimension : facteur // deuxième dimension : puissance [n] // résultat doit déjà être alloué void polynome_decomposition (Polynome *numerateur, int facteur, Polynome *element, int *puissance, Polynome partie_entiere, Polynome **resultat) ; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// Polynome fichier_lecture_polynome (FILE *f) { char buffer [200] ; Polynome r ; fscanf (f, "%s %s %d", buffer, buffer, &r.Degre) ; r = polynome_new (r.Degre) ; double d ; int n ; for (n = 0 ; n <= r.Degre ; n++) { fscanf (f, "%s %lf", buffer, &d) ; polynome_change (&r, n, d) ; } return r ; } // pour écrire dans un fichier FILE *Sortie = NULL ; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// void main (int argc, char *param []) { char *c = "fraction.txt" ; char *res = "decompo.txt" ; if (argc > 1) c = param [1] ; if (argc > 2) res = param [2] ; // on lit le fichier FILE *f = fopen (c, "r") ; if (f == NULL) printf ("impossible de lire le fichier %s\n", c) ; else { char buffer [200] ; // lecture du numérateur Polynome Numerateur = fichier_lecture_polynome (f) ; // lecture du nombre de polynôme au dénominateur int Denominateur ; fscanf (f, "%s %s %d", buffer, buffer, &Denominateur) ; int *Puissance = new int [Denominateur] ; Polynome *Element = new Polynome [Denominateur] ; // lecture de ces polynôme int n ; for (n = 0 ; n < Denominateur ; n++) { fscanf (f, "%s %s %d", buffer, buffer, &Puissance [n]) ; Element [n] = fichier_lecture_polynome (f) ; } fclose (f) ; // vérification de la lecture char *s = polynome_ecrit (&Numerateur) ; printf ("numerateur : %s\n",s) ; delete [] s ; printf ("\nnombre de terme au denominateur : %d\n",Denominateur) ; for (n = 0 ; n < Denominateur ; n++) { s = polynome_ecrit (&(Element [n])) ; printf ("terme %d puissance %d : %s\n", n+1, Puissance [n], s) ; delete [] s ; } // création de la structure de résultat // degré total du dénominateur int degre = 0 ; for (n = 0 ; n < Denominateur ; n++) degre += Puissance [n] * Element [n].Degre ; // degré de la partie entière int degre_ent = Numerateur.Degre - degre ; if (degre_ent < 0) degre_ent = -1 ; // pas de partie entère int k ; Polynome PartieEntiere = polynome_new (degre_ent) ; Polynome **Resultat = new Polynome* [Denominateur] ; for (n = 0 ; n < Denominateur ; n++) { Resultat [n] = new Polynome [Puissance [n]] ; for (k = 0 ; k < Puissance [n] ; k++) Resultat [n][k] = polynome_new (Element [n].Degre - 1) ; // les coefficients des éléments // simple sont des polynômes de degré 0 (constante) pour un élément simple de 1° espèce // et de degré 1 pour des éléments simples de 2° espèce } // traitement de la décomposition FILE *g = fopen (res, "w") ; Sortie = g ; polynome_decomposition (&Numerateur, Denominateur, Element, Puissance, PartieEntiere, Resultat) ; // écriture du résultat // précision sur la fraction à décomposer s = polynome_ecrit (&Numerateur) ; fprintf (g, "fraction à décomposer : \n\n") ; fprintf (g, "numerateur : %s\n",s) ; delete [] s ; fprintf (g, "\nnombre de terme au denominateur : %d\n",Denominateur) ; for (n = 0 ; n < Denominateur ; n++) { s = polynome_ecrit (&(Element [n])) ; if (Puissance [n] > 1) fprintf (g, "terme %d : (%s)^%d\n", n+1, s, Puissance [n]) ; else fprintf (g, "terme %d : (%s)\n", n+1, s) ; delete [] s ; } fprintf (g, "\n\ndécomposition en éléments simples \n\n") ; // partie entière s = polynome_ecrit (&PartieEntiere) ; fprintf (g, "partie entière : \t\t%s\n",s) ; delete [] s ; // les autres termes for (n = 0 ; n < Denominateur ; n++) { for (k = 0 ; k < Puissance [n] ; k++) { s = polynome_ecrit (&(Element [n])) ; if (k == 0) fprintf (g, "terme en (%s) : \t", s) ; else fprintf (g, "terme en (%s)^%d : \t", s, k+1) ; delete [] s ; s = polynome_ecrit (&(Resultat [n][k])) ; fprintf (g, "%s\n",s) ; delete [] s ; } } // fin du programme Sortie = NULL ; fclose (g) ; polynome_free (&Numerateur) ; for (n = 0 ; n < Denominateur ; n++) polynome_free (&(Element [n])) ; delete [] Element ; polynome_free (&PartieEntiere) ; for (n = 0 ; n < Denominateur ; n++) { for (k = 0 ; k < Puissance [n] ; k++) polynome_free (&(Resultat [n][k])) ; delete [] Resultat [n] ; } delete [] Puissance ; delete [] Resultat ; // fin // getchar () ; } } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// Matrice matrice_new (int ligne, int colonne) { if (ligne * colonne > 0) { Matrice r ; r.Ligne = ligne ; r.Colonne = colonne ; r.C = new double [r.Ligne * r.Colonne] ; return r ; } else { Matrice r ; r.Ligne = 0 ; r.Colonne = 0 ; return r ; } } Matrice matrice_new_identite (int ligne) { Matrice r = matrice_new (ligne, ligne) ; int i,j ; for (i = 0 ; i < r.Ligne ; i++) for (j = 0 ; j < r.Colonne ; j++) if (i == j) matrice_change (&r, i,j, 1) ; else matrice_change (&r, i,j, 0) ; return r ; } void matrice_free (Matrice *mat) { if (mat->Ligne * mat->Colonne > 0) { delete [] mat->C ; mat->Ligne = 0 ; mat->Colonne = 0 ; } } void matrice_change (Matrice *mat, int i, int j, double val) { if ((i >= 0) && (i < mat->Ligne) && (j >= 0) && (j < mat->Colonne)) mat->C [i * mat->Colonne + j] = val ; else printf ("erreur matrice change %d %d\n",i,j) ; } double matrice_donne (Matrice *mat, int i, int j) { if ((i >= 0) && (i < mat->Ligne) && (j >= 0) && (j < mat->Colonne)) return mat->C [i * mat->Colonne + j] ; else { printf ("erreur matrice donne %d %d\n",i,j) ; return 0 ; } } Matrice matrice_produit (Matrice *mat1, Matrice *mat2) { if (mat1->Colonne == mat2->Ligne) { Matrice r = matrice_new (mat1->Ligne, mat2->Colonne) ; double d ; int i,j,k ; for (i = 0 ; i < r.Ligne ; i++) for (j = 0 ; j < r.Colonne ; j++) { d = 0 ; for (k = 0 ; k < mat1->Colonne ; k++) d += matrice_donne (mat1, i,k) * matrice_donne (mat2, k,j) ; matrice_change (&r, i,j, d) ; } return r ; } else { Matrice r ; r.Ligne = 0 ; r.Colonne = 0 ; return r ; } } char *matrice_ecrit (Matrice *mat) { char *res = new char [mat->Ligne * mat->Colonne * 20] ; *res = 0 ; char *c ; int i,j ; for (i = 0 ; i < mat->Ligne ; i++) { for (j = 0 ; j < mat->Colonne ; j++) { c = res + strlen (res) ; sprintf (c, "%g\t",matrice_donne (mat, i,j)) ; } c = res + strlen (res) ; sprintf (c, "\n") ; } return res ; } Matrice matrice_copie (Matrice *mat) { Matrice r = matrice_new (mat->Ligne, mat->Colonne) ; int i,j ; for (i = 0 ; i < mat->Ligne ; i++) for (j = 0 ; j < mat->Colonne ; j++) matrice_change (&r, i,j, matrice_donne (mat, i,j)) ; return r ; } Matrice matrice_pivot_gauss (Matrice *mat) { // la matrice de passage est carrée et est l'identité au début Matrice passage = matrice_new_identite (mat->Ligne) ; // pivot int n,k,l ; double d,div,fact ; int pos ; bool faire_pivot ; // nombre de lignes sur lesquels il faut faire le pivot // car le rang d'une matrice M est vérifié r (M) <= MIN (Ligne, Colonne) int ligne = mat->Ligne ; if (mat->Colonne < ligne) ligne = mat->Colonne ; // pivot sur toutes les lignes for (n = 0 ; n < ligne ; n++) { // on teste le terme diagonale faire_pivot = true ; // par défaut, on effectue le pivot sur la colonne n d = matrice_donne (mat, n,n) ; if (d == 0) { // si ce terme est nul, on regarde si un terme dans la même colonne ne l'est pas pos = n ; while ((pos < mat->Ligne) && (matrice_donne (mat, pos, n) == 0)) pos++ ; if (pos >= mat->Ligne) faire_pivot = false ; // car tous les termes de la colonne sont nuls else { // sinon, on ajoute la ligne pos à la ligne n for (k = n ; k < mat->Colonne ; k++) { d = matrice_donne (mat, n, k) ; d += matrice_donne (mat, pos, k) ; matrice_change (mat, n, k, d) ; } for (k = 0 ; k < passage.Colonne ; k++) { // on répercute également ces changements dans la matrice de passage // sur toute la ligne cette fois d = matrice_donne (&passage, n, k) ; d += matrice_donne (&passage, pos, k) ; matrice_change (&passage, n, k, d) ; } } } if (faire_pivot) { fact = matrice_donne (mat, n,n) ; // on est sûr que fact != 0 // on fait le pivot sur toutes les lignes après n for (l = n+1 ; l < mat->Ligne ; l++) { div = matrice_donne (mat, l, n) ; // si ce coefficient n'est pas nul if (div != 0) { for (k = n ; k < mat->Colonne ; k++) { d = matrice_donne (mat, l, k) ; d -= matrice_donne (mat, n, k)*div/fact ; matrice_change (mat, l, k, d) ; } for (k = 0 ; k < passage.Colonne ; k++) { // on répercute également ces changements dans la matrice de passage // sur toute la ligne d = matrice_donne (&passage, l, k) ; d -= matrice_donne (&passage, n, k)*div/fact ; matrice_change (&passage, l, k, d) ; } } } } } return passage ; } Matrice matrice_pivot_gauss_inverse (Matrice *mat) { // la matrice de passage est carrée et est l'identité au début Matrice passage = matrice_new_identite (mat->Ligne) ; // pivot int n,k,l ; double d,div,fact ; int ligne = mat->Ligne ; // l'inversibilité ne s'applique qu'à des matrices carrées bool inversible = mat->Ligne == mat->Colonne ; // on s'arrange pour n'avoir que des uns sur les diagonales for (n = 0 ; n < ligne ; n++) { fact = matrice_donne (mat, n,n) ; inversible &= fact != 0 ; if (inversible) { for (k = n ; k < mat->Colonne ; k++) { d = matrice_donne (mat, n, k) ; d /= fact ; matrice_change (mat, n, k, d) ; } for (k = 0 ; k < passage.Colonne ; k++) { // on répercute également ces changements dans la matrice de passage d = matrice_donne (&passage, n, k) ; d /= fact ; matrice_change (&passage, n, k, d) ; } } else break ; } // pivot remontant sur toutes les lignes si la matrice est inversible if (inversible) { for (n = ligne-1 ; n >= 0 ; n--) { fact = matrice_donne (mat, n,n) ; // on est sûr que fact != 0 // même, c'est forcément 1 maintenant // on fait le pivot sur toutes les lignes après n for (l = n-1 ; l >= 0 ; l--) { div = matrice_donne (mat, l, n) ; // si ce coefficient n'est pas nul if (div != 0) { for (k = n ; k < mat->Colonne ; k++) { d = matrice_donne (mat, l, k) ; d -= matrice_donne (mat, n, k)*div/fact ; matrice_change (mat, l, k, d) ; } for (k = 0 ; k < passage.Colonne ; k++) { // on répercute également ces changements dans la matrice de passage // sur toute la ligne d = matrice_donne (&passage, l, k) ; d -= matrice_donne (&passage, n, k)*div/fact ; matrice_change (&passage, l, k, d) ; } } } } } return passage ; } Matrice matrice_inverse (Matrice *mat) { Matrice copie = matrice_copie (mat) ; Matrice pas1 = matrice_pivot_gauss (&copie) ; Matrice pas2 = matrice_pivot_gauss_inverse (&copie) ; Matrice prod = matrice_produit (&pas2, &pas1) ; matrice_free (&copie) ; matrice_free (&pas2) ; matrice_free (&pas1) ; return prod ; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// Polynome polynome_new (int degre) { if (degre >= 0) { Polynome r ; r.Degre = degre ; r.C = new double [degre+1] ; return r ; } else { Polynome r ; r.Degre = -1 ; return r ; } } void polynome_free (Polynome *p) { if (p->Degre >= 0) { delete [] p->C ; p->Degre = -1 ; } } void polynome_change (Polynome *p, int n, double val) { if ((n >= 0) && (n <= p->Degre)) p->C [n] = val ; else printf ("erreur polynome_change %d\n",n) ; } double polynome_donne (Polynome *p, int n) { if ((n >= 0) && (n <= p->Degre)) return p->C [n] ; else { printf ("erreur polynome_donne %d\n",n) ; return 0 ; } } char *polynome_ecrit (Polynome *p) { if (p->Degre >= 0) { char *res = new char [p->Degre * 20 + 20] ; *res = 0 ; char *c = res ; int n ; for (n = 0 ; n <= p->Degre ; n++) { if (polynome_donne (p, n) != 0) { if ((c > res) && (polynome_donne (p, n) > 0)) sprintf (c, " + ") ; else sprintf (c, " ") ; c = res + strlen (res) ; if (n == 0) sprintf (c, "%g", polynome_donne (p, n)) ; else if (n == 1) { if (polynome_donne (p, n) != 1) sprintf (c, "%g*X", polynome_donne (p, n)) ; else sprintf (c, "X") ; } else { if (polynome_donne (p, n) != 1) sprintf (c, "%g*X^%d", polynome_donne (p, n), n) ; else sprintf (c, "X^%d",n) ; } } c = res + strlen (res) ; } return res ; } else { char *res = new char [20] ; strcpy (res, "nul") ; return res ; } } Polynome polynome_produit (Polynome *p1, Polynome *p2) { Polynome p = polynome_new (p1->Degre + p2->Degre) ; int n ; int k ; double d ; // mise à zéro du polynôme produit for (n = 0 ; n <= p.Degre ; n++) polynome_change (&p, n, 0) ; // calcul du produit for (n = 0 ; n <= p1->Degre ; n++) { for (k = 0 ; k <= p2->Degre ; k++) { d = polynome_donne (&p, n+k) ; d += polynome_donne (p1, n) * polynome_donne (p2, k) ; polynome_change (&p, n+k, d) ; } } return p ; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // méthode consacrée à la décomposition // calcul le produit de tous les polynômes du dénominateur // en évitant la puissance evite_puissance de l'élément evite_el // si evite_puissance == -1, calcule tous les produits Polynome polynome_produit_denominateur (int facteur, Polynome *element, int *puissance, int evite_el, int evite_puissance) { // c'est la constante égale à un Polynome prod = polynome_new (0) ; polynome_change (&prod, 0, 1) ; Polynome temp ; int n ; int k ; int fin ; for (n = 0 ; n < facteur ; n++) { if (evite_el == n) fin = puissance [n] - evite_puissance ; else fin = puissance [n] ; for (k = 0 ; k < fin ; k++) { temp = polynome_produit (&prod, &(element [n])) ; polynome_free (&prod) ; prod = temp ; } } return prod ; } void polynome_decale_puissance (Polynome *p, int k) { if (k > 0) { Polynome res = polynome_new (p->Degre+k) ; int n ; for (n = 0 ; n <= res.Degre ; n++) { if (n < k) polynome_change (&res, n, 0) ; else polynome_change (&res, n, polynome_donne (p, n-k)) ; } polynome_free (p) ; *p = res ; } } void polynome_decomposition (Polynome *numerateur, int facteur, Polynome *element, int *puissance, Polynome partie_entiere, Polynome **resultat) { // calcul du nombre de coefficient et du degré maximal int nb_coef = partie_entiere.Degre + 1 ; int n ; for (n = 0 ; n < facteur ; n++) nb_coef += element [n].Degre * puissance [n] ; // pour stocker les produits de polynômes Polynome *stock = new Polynome [nb_coef] ; // on fait les produits int k ; // on numérote les coefficients en prenant les éléments simpels les uns après les autres // par ordre de puissances croissantes // et par ordre de monômes de degré croissant // la partie entière for (k = 0 ; k <= partie_entiere.Degre ; k++) { stock [k] = polynome_produit_denominateur (facteur, element, puissance, -1, -1) ; // on décale les coefficients vers la droite de k pas // pour une multiplicateur de X^k polynome_decale_puissance (&(stock [k]), k) ; } // suite des calculs int numcoef = partie_entiere.Degre + 1 ; int l ; for (n = 0 ; n < facteur ; n++) { for (k = 0 ; k < puissance [n] ; k++) { // boucle sur 1 ou 2 coefficients for (l = 0 ; l < element [n].Degre ; l++) { stock [numcoef] = polynome_produit_denominateur ( facteur, element, puissance, n, k+1) ; polynome_decale_puissance (&(stock [numcoef]), l) ; numcoef++ ; } } } // construction de la matrice du système linéaire // ressemble à une transposition Matrice systeme = matrice_new (nb_coef, nb_coef) ; for (n = 0 ; n < nb_coef ; n++) { for (k = 0 ; k < nb_coef ; k++) { if (n <= stock [k].Degre) matrice_change (&systeme, n,k, polynome_donne (&(stock [k]), n)) ; else matrice_change (&systeme, n,k,0) ; } } // inversion de la matrice Matrice inverse = matrice_inverse (&systeme) ; // calcul des coefficients Matrice constante = matrice_new (nb_coef, 1) ; for (n = 0 ; n < nb_coef ; n++) if (n <= numerateur->Degre) matrice_change (&constante, n, 0, polynome_donne (numerateur, n)) ; else matrice_change (&constante, n, 0, 0) ; // résolution du système Matrice solution = matrice_produit (&inverse, &constante) ; // on place les solutions dans la structure censée les recevoir // partie entière for (n = 0 ; n <= partie_entiere.Degre ; n++) polynome_change (&partie_entiere, n, matrice_donne (&solution, n, 0)) ; // les autres coefficients numcoef = partie_entiere.Degre + 1 ; for (n = 0 ; n < facteur ; n++) for (k = 0 ; k < puissance [n] ; k++) for (l = 0 ; l < element [n].Degre ; l++) { polynome_change (&(resultat [n][k]), l, matrice_donne (&solution, numcoef, 0)) ; numcoef++ ; } // fin matrice_free (&inverse) ; matrice_free (&constante) ; matrice_free (&systeme) ; matrice_free (&solution) ; for (n = 0 ; n < nb_coef ; n++) polynome_free (&(stock [n])) ; delete [] stock ; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
fichier texte contenant la description d'une fraction
numérateur degré 9 d0 0 d1 0 d2 0 d3 0 d4 0 d5 0 d6 0 d7 0 d8 0 d9 1 ..................dénominateur produit 2 dénominateur puissance 3 dénominateur degré 1 d0 1 d1 1 dénominateur puissance 2 dénominateur degré 2 d0 2 d1 1 d2 1
suite de Syracuse
def syracuse (u0) : suite = [ ] ops = [ ] u = u0 while u != 1 : suite.append (u) if u % 2 == 0 : ops.append (1) u = u/2 else : u = (3*u+1) / 2 ops.append (0) suite.append(u) suite.append(0) ops.reverse() return suite, ops def base2 (ops) : s = 0.0 i = 1 for k,v in enumerate(ops) : if v == 1 : s += i i *= 2 return s if __name__ == "__main__" : for i in range (1,30) : s,o = syracuse(i) t = max ( [ _ for _ in s if _%2 == 1] ) n = base2(o) print "% 3d len % 3d %d %d suite" % (i,len(s), t, n), o,s
File: syracuse.tex, line 111
1 len 1 suite [1] 2 len 2 suite [2, 1] 3 len 6 suite [3, 5, 8, 4, 2, 1] 4 len 3 suite [4, 2, 1] 5 len 5 suite [5, 8, 4, 2, 1] 6 len 7 suite [6, 3, 5, 8, 4, 2, 1] 7 len 12 suite [7, 11, 17, 26, 13, 20, 10, 5, 8, 4, 2, 1] 8 len 4 suite [8, 4, 2, 1] 9 len 14 suite [9, 14, 7, 11, 17, 26, 13, 20, 10, 5, 8, 4, 2, 1] 10 len 6 suite [10, 5, 8, 4, 2, 1] 11 len 11 suite [11, 17, 26, 13, 20, 10, 5, 8, 4, 2, 1] 12 len 8 suite [12, 6, 3, 5, 8, 4, 2, 1] 13 len 8 suite [13, 20, 10, 5, 8, 4, 2, 1] 14 len 13 suite [14, 7, 11, 17, 26, 13, 20, 10, 5, 8, 4, 2, 1] 15 len 13 suite [15, 23, 35, 53, 80, 40, 20, 10, 5, 8, 4, 2, 1] 16 len 5 suite [16, 8, 4, 2, 1]
File: plus_court_chemin.tex, line 81
# coding: cp1252 import random # pour tirer aléatoirement des nombres import Matrix as mat # pour les matrices import UserArray as ua # pour les matrices import math # fonction sqrt import PIL.Image as Im # pour les images import PIL.ImageDraw as Id # pour dessiner def construit_ville(n, x =500, y = 500): """tire aléatoirement n villes dans un carrée x * y""" l = [] for i in range(0,n): xx = x * random.random () yy = y * random.random () l.append ((xx,yy)) return l def distance_ville (l,i,j): """calcule la distance entre deux villes i et j de la liste l""" x = l [i][0] - l [j][0] y = l [i][1] - l [j][1] return math.sqrt (float (x*x+y*y)) def construit_arete (l,part = 0.15): """tire aléatoirement part * len (l) arêtes et construit la matrice d'adjacence""" nb = len (l) m = mat.Matrix ( [ 0 for i in range(0,nb) ]) # crée un vecteur de nb zéros m = ua.transpose (m) * m # effectue une multiplication du vecteur # précédent avec son vecteur transposé # pour obtenir une matrice carrée nulle are = int (part * nb * nb) while are > 0: i = random.randint (0,nb-1) j = random.randint (0,nb-1) if m [i,j] > 0: continue # si l'arête existe déjà, on recommence m [i,j] = int (distance_ville (l,i,j)) # on affecte comme poids à l'arête # la distance entre les deux villes are -= 1 return m def dessin_ville_arete (l,m,chemin): """dessine la ville et les routes dans une image""" mx, my = 0,0 for i in l: mx = max (mx, i [0]) my = max (my, i [1]) mx += 25 my += 25 mx, my = int (mx), int (my) im = Im.new ("RGB", (mx, my), (255,255,255)) # création d'une image blanche draw = Id.Draw(im) # dessin des villes for i in l: j = (int (i [0]), int (i[1])) j2 = (j [0] + 10, j [1] + 10) draw.ellipse ((j,j2), fill = (0,0,0)) # dessin des arêtes for i in range (0,len(l)): for j in range (0,len(l)): if m [i,j] > 0: a = (int (l [i][0]+5), int (l [i][1]+5)) b = (int (l [j][0]+5), int (l [j][1]+5)) draw.line ((a,b),fill=(255,0,0)) # dessin des villes de départ et d'arrivée v1 = chemin [0] v2 = chemin [ len (chemin)-1] a = (int (l [v1][0]), int (l [v1][1])) b = (int (l [v1][0]+10), int (l [v1][1]+10)) draw.ellipse ((a,b), fill = (0,255,0)) a = (int (l [v2][0]), int (l [v2][1])) b = (int (l [v2][0]+10), int (l [v2][1]+10)) draw.ellipse ((a,b), fill = (0,255,0)) # dessin du chemin for c in range (0,len(chemin)-1): i = chemin [c] j = chemin [c+1] print i,j if m [i,j] > 0: a = (int (l [i][0]+5), int (l [i][1]+5)) b = (int (l [j][0]+5), int (l [j][1]+5)) draw.line ((a,b),fill=(0,0,255)) else: a = (int (l [i][0]+5), int (l [i][1]+5)) b = (int (l [j][0]+5), int (l [j][1]+5)) draw.line ((a,b),fill=(0,0,50)) # on retourne l'image return im # programme principal # construction des villes l = construit_ville (10) print l # construction des arêtes m = construit_arete (l) print m # choix de la ville de départ de d'arrivée a,b = 0,0 while a == b: a = random.randint (0,len(l)-1) b = random.randint (0,len(l)-1) print "ville de départ et d'arrivée : ",a,b # construction de l'image du résultat im = dessin_ville_arete(l,m,[a,b]) im.show () # on affiche l'image
plus court chemin dans un graphe
# coding: cp1252 import random # pour tirer aléatoirement des nombres import math # fonction sqrt import PIL.Image as Im # pour les images import PIL.ImageDraw as Id # pour dessiner infini = 10000000 # l'infini est égal à dix millions, c'est une variable globale def construit_ville(n, x =1000, y = 800): """tire aléatoirement n villes dans un carrée x * y, on choisit ces villes de sortent qu'elles ne soient pas trop proches""" # deux villes ne pourront pas être plus proches que mind mind = math.sqrt (x*x+y*y) / (n * 0.75) # liste vide l = [] while n > 0: # on tire aléatoirement les coordonnées d'une ville xx = x * random.random () yy = y * random.random () # on vérifie qu'elle n'est pas trop proche d'aucune autre ville ajout = True for t in l : d1 = t [0] - xx d2 = t [1] - yy d = math.sqrt (d1*d1+d2*d2) if d < mind : ajout = False # ville trop proche # si la ville n'est pas trop proche des autres, on l'ajoute à la liste if ajout: l.append ((xx,yy)) n -= 1 # une ville en moins à choisir return l def distance_ville (l,i,j): """calcule la distance entre deux villes i et j de la liste l""" x = l [i][0] - l [j][0] y = l [i][1] - l [j][1] return math.sqrt (float (x*x+y*y)) def construit_arete (l,part = 0.15): """tire aléatoirement part * len (l) arêtes et construit la matrice d'adjacence""" global infini nb = len (l) m = [ [ 0 for i in range(0,nb) ] for i in range (0,nb) ] # crée un vecteur de nb zéros are = int (part * nb * nb) while are > 0: i = random.randint (0,nb-1) # première ville j = random.randint (0,nb-1) # seconde ville if i == j : continue # pas besoin d'arête entre i et i if m [i][j] > 0: continue # si l'arête existe déjà, on recommence m [i][j] = int (distance_ville (l,i,j)) # on affecte comme poids à l'arête # la distance entre les deux villes m [j][i] = m [i][j] # symétrie de la matrice car le graphe est non orienté are -= 2 # deux cases de la matrice ne sont plus nulles # on associe à toutes les arêtes nulles de poids nul, donc inexistantes, # une valeur égale à l'infini pour signifier qu'elles ne sont pas reliées global infini for i in range (0, nb): for j in range (0, nb): if m [i][j] == 0: m [i][j] = infini return m def dessin_ville_arete (l,m,chemin): """dessine la ville et les routes dans une image""" # on prend les coordonnées maximales mx, my = 0,0 for i in l: mx = max (mx, i [0]) my = max (my, i [1]) mx += 25 my += 25 mx, my = int (mx), int (my) im = Im.new ("RGB", (mx, my), (255,255,255)) # création d'une image blanche draw = Id.Draw(im) # dessin des villes for i in l: j = (int (i [0]), int (i[1])) j2 = (j [0] + 10, j [1] + 10) draw.ellipse ((j,j2), fill = (0,0,0)) # dessin des arêtes global infini for i in range (0,len(l)): for j in range (0,len(l)): if m [i][j] > 0 and m [i][j] < infini : a = (int (l [i][0]+5), int (l [i][1]+5)) b = (int (l [j][0]+5), int (l [j][1]+5)) draw.line ((a,b),fill=(255,0,0)) # dessin des villes de départ et d'arrivée en vert v1 = chemin [0] v2 = chemin [ len (chemin)-1] a = (int (l [v1][0]), int (l [v1][1])) b = (int (l [v1][0]+10), int (l [v1][1]+10)) draw.ellipse ((a,b), fill = (0,255,0)) a = (int (l [v2][0]), int (l [v2][1])) b = (int (l [v2][0]+10), int (l [v2][1]+10)) draw.ellipse ((a,b), fill = (0,255,0)) # dessin du chemin, arêtes en bleu for c in range (0,len(chemin)-1): i = chemin [c] j = chemin [c+1] if m [i][j] > 0 and m [i][j] < infini : a = (int (l [i][0]+5), int (l [i][1]+5)) b = (int (l [j][0]+5), int (l [j][1]+5)) draw.line ((a,b),fill=(0,0,255)) else: a = (int (l [i][0]+5), int (l [i][1]+5)) b = (int (l [j][0]+5), int (l [j][1]+5)) draw.line ((a,b),fill=(0,0,50)) # on retourne l'image return im def meilleur_chemin (n,m,a,b): """détermine le meilleur chemin, n est le nombre de villes, m est la matrice d'adjacence, a est la ville de départ, b la ville d'arrivée""" # création d'un tableau, d [i] contient la meilleure distance minimale actuelle # séparant la ville i de la ville a d = [ 10000000 for i in range(0,n) ] # p [i] contient la ville prédécesseur qui permet d'atteindre la ville i # avec la distance d [i] p = [ -1 for i in range(0,n) ] # au départ, seul la distance d[a] est nulle d [a] = 0 # cette boucle s'exécute tant qu'on effectue des mises à jour # dans le tableau d[i] modif = 1 while modif > 0: modif = 0 # on parcourt toutes les arêtes for i in range(0,n): for j in range (0,n): # nouvelle distance t = d [i] + m [i][j] if t < d [j] : # si on a trouvé une meilleure distance minimale d [j] = t # on met à jour p [j] = i modif += 1 # une mise à jour de plus # on récupère le meilleur chemin l = [] while b != -1: l.append (b) b = p [b] # on le retourne l.reverse () return l def choix_villes_depart_arrive(nb,m): """cette fonction choisit deux villes aléatoirement, départ et arrivée, elle évite que la ville et départ et d'arrivée soient les mêmes, elle évite que ces deux villes soient reliés par un seul arc, elle choisit deux villes pour lesquelles il existe un meilleur chemin""" global infini a,b = -1,-1 tour = 0 while True: a = random.randint (0,nb-1) # première ville au hasard b = random.randint (0,nb-1) # seconde ville au hasard if a == b: continue # villes identiques, on recommence if m [a][b] != infini : continue # villes reliées, on recommence l = meilleur_chemin (nb,m,a,b) if l != None and len(l) > 3 : return a,b # si le meilleur chemin existe, # et n'est pas trop court (4 villes minimum, # soit deux étapes entre a et b), alors # on retourne le résultat else: tour += 1 if tour > 120 : return 0,0 # au bout de 120 essais, on s'arrête ############################################################################### # programme principal # construction des villes l = construit_ville (15) # construction des arêtes print "adjacence" m = construit_arete (l) # choix de la ville de départ de d'arrivée print "départ" a,b = choix_villes_depart_arrive(len(l),m) print "recherche du meilleur chemin" chemin = meilleur_chemin (len(l), m, a,b) if chemin != None and len(chemin) > 0: print "meilleur chemin ", a, " --> ", b, " : ", chemin # construction de l'image du résultat im = dessin_ville_arete(l,m,chemin) im.save ("image.png") im.show () # on affiche l'image else : print "il n'existe pas de meilleur chemin"
distance d'édition
# coding: latin-1 def get_lines (file) : """retourne toutes les lignes d'un fichier, nettoie les fins de lignes et les espaces""" f = open (file, "r") li = f.readlines () f.close () return [ l.strip ("\r\n") for l in li ] def distance (line1, line2) : """construit une distance entre deux tableaux de lignes""" d = { (-1,-1):(0,(-1,-1), "") } for i in xrange (0, len (line1)) : d [ i,-1 ] = (i+1, (i-1,-1), "+ " + line1 [i]) for j in xrange (0, len (line2)) : d [ -1,j ] = (j+1, (-1,j-1), "- " + line2 [j]) for i in xrange (0, len (line1)) : l1 = line1 [i] for j in xrange (0, len (line2)) : l2 = line2 [j] c = abs (cmp (l1, l2)) i1 = d [i-1,j][0] + 1 i2 = d [i,j-1][0] + 1 i3 = d [i-1,j-1][0] + 2*c if i1 <= min (i2, i3) : d [i,j] = (i1, (i-1,j), "+ " + l1) elif i2 <= min (i1, i3) : d [i,j] = (i2, (i,j-1), "- " + l2) else : d [i,j] = (i3, (i-1,j-1), " " + l1) last = (len (line1)-1, len (line2)-1) pos = [d [last]] pn = pos [0][1] while pn != (-1,-1) : p = pos [len (pos)-1] pn = p [1] pos.append (d [pn]) pos.pop () pos.reverse () return [ p [2] for p in pos ] def distance_file (file1, file2) : line1 = get_lines (file1) line2 = get_lines (file2) return distance (line1, line2) if __name__ == "__main__" : file1 = "filedistance.py" file2 = "filedistance2.py" res = distance_file (file1, file2) for r in res : print r
File: plus_court_chemin.tex, line 469
def distance (line1, line2) : """construit une distance entre deux tableaux de lignes""" - d = { (-1,-1):(0,(-1,-1)) } + d = { (-1,-1):(0,(-1,-1), "") } + for i in xrange (0, len (line1)) : + d [ i,-1 ] = (i+1, (i-1,-1), "+ " + line1 [i]) + for j in xrange (0, len (line2)) : + d [ -1,j ] = (j+1, (-1,j-1), "- " + line2 [j]) for i in xrange (0, len (line1)) : l1 = line1 [i] for j in xrange (0, len (line2)) :
algorithme de Kohonen
# coding: cp1252 import random # pour tirer aléatoirement des nombres import math # fonctions cos, sin import pygame # pour les affichages def construit_ville(n, x =1000, y = 700): """tire aléatoirement n villes dans un carrée x * y, on choisit ces villes de sortent qu'elles ne soient pas trop proches""" # deux villes ne pourront pas être plus proches que mind mind = math.sqrt (x*x+y*y) / (n * 0.75) # liste vide l = [] while n > 0: # on tire aléatoirement les coordonnées d'une ville xx = x * random.random () yy = y * random.random () # on vérifie qu'elle n'est pas trop proche d'aucune autre ville ajout = True for t in l : d1 = t [0] - xx d2 = t [1] - yy d = math.sqrt (d1*d1+d2*d2) if d < mind : ajout = False # ville trop proche # si la ville n'est pas trop proche des autres, on l'ajoute à la liste if ajout: l.append ((xx,yy)) n -= 1 # une ville en moins à choisir return l def display_ville(villes,screen,bv): """dessine les villes à l'écran""" color = 255,0,0 color2 = 0,255,0 for v in villes: pygame.draw.circle (screen, color, v, 10) pygame.draw.circle (screen, color2, villes [bv], 10) def construit_liste_neurones (villes, nb = 0): """place les neurones sur l'écran, il y a autant de neurones que de villes, le paramètre villes est la liste des villes""" if nb == 0 : nb = len (villes) # coordonnées maximale maxx,maxy = 0,0 for v in villes: if v [0] > maxx : maxx = v [0] if v [1] > maxy : maxy = v [1] maxx /= 2 maxy /= 2 if nb > 1 : # dispose les neurones en ellipse n = [] for i in range (0, nb): x = maxx + maxx * math.cos (math.pi * 2 * float (i) / nb) / 4 y = maxy + maxy * math.sin (math.pi * 2 * float (i) / nb) / 4 n.append ((x,y)) return n else : n = [ (maxx, maxy) ] return n def distance_euclidienne_carree (p1,p2): """calcule la distance euclidienne entre deux points""" x = p1[0] - p2[0] y = p1[1] - p2[1] return x*x+y*y def ajoute_vecteur (v,n): """ajoute deux vecteurs entre eux""" return ( v [0] + n [0], v [1] + n [1]) def soustrait_vecteur (v,n): """soustrait deux vecteurs""" return ( v [0] - n [0], v [1] - n [1]) def multiplie_vecteur (v,f): """multiplie un vecteur par un scalaire""" return ( v [0] * f, v [1] * f) def poids_attirance(p,dist): """calcul le poids d'attraction d'une neurone vers une ville""" d = p [0] * p [0] + p [1] * p [1] d = math.sqrt (d) d = dist / (d + dist) return d def vecteur_norme(p): """calcul la norme d'un vecteur""" return math.sqrt (p [0] * p [0] + p [1] * p [1]) def deplace_neurone (n,villes,neurones, dist_w, forces, compte): """déplace le neurone de plus proche de la ville n, déplace ses voisins @param villes liste des villes @param neurones liste des neurones @param dist distance d'attirance @param forces force de déplacement des voisins du neurones @param compte incrémente compte [n] où n est l'indice du neurone choisi @return indice du neurone le plus proche""" # recherche du neurone le plus proche v = villes [n] proche = 0 dist = distance_euclidienne_carree(v, neurones [0]) for i in xrange(1,len(neurones)): d = distance_euclidienne_carree (v, neurones [i]) if d < dist : dist = d proche = i # vecteur de déplacement i = proche compte [i] += 1 n = neurones [i] vec = soustrait_vecteur (v,n) poids = poids_attirance (vec, dist_w) vec = multiplie_vecteur (vec, poids) n = ajoute_vecteur (n, vec) neurones [i] = n # déplacement des voisins for k in xrange(0,len (forces)): i1 = (i + k + 1) % len (neurones) i2 = (i - k - 1 + len (neurones)) % len (neurones) n1 = neurones [i1] n2 = neurones [i2] vec = soustrait_vecteur (n, n1) poids = poids_attirance (vec, dist_w) vec = multiplie_vecteur (vec, poids) vec = multiplie_vecteur (vec, forces [k]) n1 = ajoute_vecteur (n1, vec) vec = soustrait_vecteur (n, n2) poids = poids_attirance (vec, dist_w) vec = multiplie_vecteur (vec, poids) vec = multiplie_vecteur (vec, forces [k]) n2 = ajoute_vecteur (n2, vec) neurones [i1] = n1 neurones [i2] = n2 return proche def iteration (villes,neurones, dist, forces, compte_v, compte_n): """choisit une ville aléatoirement et attire le neurones le plus proche, choisit cette ville parmi les villes les moins fréquemment choisies @param villes liste des villes @param neurones liste des neurones @param dist distance d'attirance @param forces force de déplacement des voisins du neurones @param compte_v incrémente compte_v [n] où n est l'indice de la ville choisie @param compte_n incrémente compte_n [n] où n est l'indice du neurone choisi @return indices de la ville et du neurone le plus proche""" m = min (compte_v) ind = [i for i in xrange (0,len (villes)) if compte_v [i] == m] n = random.randint (0,len(ind)-1) n = ind [n] compte_v [n] += 1 return n, deplace_neurone (n,villes,neurones,dist, forces, compte_n) def display_neurone(neurones,screen,bn): """dessine les neurones à l'écran""" color = 0,0,255 color2 = 0,255,0 for n in neurones : pygame.draw.circle (screen, color, n, 5) pygame.draw.circle (screen, color2, neurones [bn], 5) if len (neurones) > 1: pygame.draw.lines (screen, color, True, neurones, 2) def modifie_structure(neurones,compte, nb_sel): """modifie la structure des neurones, supprime les neurones jamais déplacés, et ajoute des neurones lorsque certains sont trop sollicités""" def cmp_add (i,j): return cmp (i [0], j [0]) if nb_sel > 0 : # supprime les neurones les moins sollicités sup = [i for i in xrange (0, len(neurones)) if compte [i] == 0 ] if len(sup) > 0: sup.sort () sup.reverse () for i in sup: del compte [i] del neurones [i] # on ajoute un neurone lorsque max (compte) >= 2 * min (compte) add = [] for i in xrange (0,len(compte)): if compte [i] > nb_sel: d1 = math.sqrt ( distance_euclidienne_carree (neurones [i], \ neurones [(i+1) % len (neurones)] )) d2 = math.sqrt ( distance_euclidienne_carree (neurones [i], \ neurones [(i-1 + len (neurones)) % len (neurones)] )) if d1 > d2 : d1 = d2 p = neurones [i] p = (p[0] + random.randint (0, int (d1 / 2)) , \ p [1] + random.randint (0, int (d1 / 2)) ) add.append ((i,p,0)) add.sort (cmp_add) add.reverse () for a in add: neurones.insert (a [0], a [1]) compte.insert (a [0], a [2]) # on remet les compteurs à zéros for i in xrange (0, len (compte)) : compte [i] = 0 def moyenne_proximite (villes): """retourne la distance moyenne entre deux villes les plus proches""" c = 0 m = 0 for v in villes: mn = 100000000 for vv in villes: if v == vv : continue d = distance_euclidienne_carree (v,vv) if d < mn : mn = d c += 1 m += math.sqrt (mn) m /= float (c) return m def attendre_clic (screen,x,y): """dessine une croix sur l'écran et attend la pression d'un clic de souris""" color = 0,0,0 pygame.draw.line (screen, color, (0,0), (x-1,y-1)) pygame.draw.line (screen, color, (x-1,0), (0,y-1)) pygame.display.flip () 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 = 800, 500 black = 0, 0, 0 white = 255,255,255 screen = pygame.display.set_mode(size) villes = construit_ville (30, x,y) neurones = construit_liste_neurones (villes, 3) compte_n = [0 for i in neurones] compte_v = [0 for i in villes] tour = 2 maj = tour * len (villes) dist = moyenne_proximite (villes) * 4 fs = [ 1.5, 1, 0.75, 0.5, 0.25 ] iter = 0 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.MOUSEBUTTONUP: attendre_clic (screen,x,y) iter += 1 if iter % maj == 0 : modifie_structure (neurones,compte_n, tour) dist *= 0.99 f2 = [ w * 0.90 for w in fs] fs = f2 bv, bn = iteration (villes,neurones, dist, fs, compte_v, compte_n) screen.fill (white) display_ville (villes, screen, bv) display_neurone (neurones, screen, bn) if iter == 1: attendre_clic (screen,x,y) pygame.display.flip ()
voyageur de commerce et algorithme de Kruskal
# coding: cp1252 import random # pour tirer aléatoirement des nombres import math # fonctions cos, sin import pygame # pour les affichages import copy # pour copier des résultats intermédiaires import bresenham_ligne as brl # pour dessiner les arêtes dans l'écran des zones #import psyco # pour accélérer le programme def attendre_clic (screen,x,y): """dessine une croix sur l'écran et attend la pression d'un clic de souris""" color = 0,0,0 pygame.draw.line (screen, color, (0,0), (x-1,y-1)) pygame.draw.line (screen, color, (x-1,0), (0,y-1)) pygame.display.flip () reste = True while reste: for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONUP : reste = False break def construit_ville(n, x =1000, y = 700): """tire aléatoirement n villes dans un carrée x * y, on choisit ces villes de sortent qu'elles ne soient pas trop proches""" # deux villes ne pourront pas être plus proches que mind mind = math.sqrt (x*x+y*y) / (n * 0.75) # liste vide l = [] while n > 0: # on tire aléatoirement les coordonnées d'une ville xx = x * random.random () yy = y * random.random () # on vérifie qu'elle n'est pas trop proche d'aucune autre ville ajout = True for t in l : d1 = t [0] - xx d2 = t [1] - yy d = math.sqrt (d1*d1+d2*d2) if d < mind : ajout = False # ville trop proche # si la ville n'est pas trop proche des autres, on l'ajoute à la liste if ajout: l.append ((xx,yy)) n -= 1 # une ville en moins à choisir return l def display_ville(villes,screen,bv): """dessine les villes à l'écran""" color = 255,0,0 color2 = 0,255,0 for v in villes: pygame.draw.circle (screen, color, v, 3) pygame.draw.circle (screen, color2, villes [bv], 3) def display_neurone(neurones,screen,bn): """dessine les neurones à l'écran""" color = 0,0,255 color2 = 0,255,0 for n in neurones : pygame.draw.circle (screen, color, n, 3) pygame.draw.circle (screen, color2, neurones [bn], 3) if len (neurones) > 1: pygame.draw.lines (screen, color, True, neurones, 2) def distance (p1,p2): """calcule la distance entre deux villes""" x = p1 [0] - p2[0] y = p1 [1] - p2[1] return math.sqrt (x*x + y*y) def repartition_zone (villes, zone_taille, ask_zone = False) : """répartit les villes en zones, retourne les villes rangées par zones, chaque éléments zones [z][k] contient : - les coordonnées de la ville - ses coordonnées en zone, (zx, zy) - son indice dans la liste villes la fonction retourne également le nombre de zones selon l'axe des abscisses et l'axe des ordonnées, retourne aussi le nombre de zones, si ask_zone est True, retourne un paramètre supplémentaire : zone""" print "gestion des zones" X,Y = 0,0 for v in villes: X = max (v [0] // zone_taille, X) Y = max (v [1] // zone_taille, Y) X += 1 Y += 1 # attribution des zones zone = [] nb = len (villes) Zmax = 0 for i in xrange (0,len (villes)): v = villes [i] x = int (v [0] // zone_taille) y = int (v [1] // zone_taille) z = int (y * X + x) Zmax = max (z,Zmax) zone.append ((z, v, (x,y), i)) # rangement par zone Zmax += 1 zones = [ [] for i in xrange (0,Zmax) ] for z in zone: zones [ z [0] ].append ((z [1], z [2], z [3])) if ask_zone : return zones,X,Y,Zmax,zone else : return zones,X,Y,Zmax def voisinage_zone (z,Zmax,X,Y): """retourne la liste des voisins d'une zone z sachant qu'il y a X zones sur l'axe des abscisses et Y zones sur l'axe des ordonnées, Zmax est le nombre de zones, inclus z dans cette liste""" x = z % X y = z // X voisin_ = [z] if x > 0: voisin_.append (z-1) if x < X: voisin_.append (z+1) if y > 0: voisin_.append (z-X) if y < Y: voisin_.append (z+X) if x > 0 and y > 0 : voisin_.append (z-1-X) if x > 0 and y < Y : voisin_.append (z-1+X) if x < X and y > 0 : voisin_.append (z+1-X) if x < X and y < Y : voisin_.append (z+1+X) voisin = [ int (i) for i in voisin_ if i >= 0 and i < Zmax ] return voisin def arbre_poids_minimal(villes, zone_taille): """construit l'arbre de poids minimal, retourne une liste de listes, chaque sous-liste associée à une ville contient la liste des ses voisins, zone_taille permet de découper l'image en zones, les distances ne seront calculées que si deux éléments sont dans la même zone ou dans une zone voisine""" def tri_distance (u,v): if u [2] < v [2] : return -1 elif u [2] > v [2] : return 1 else : return 0 zones,X,Y,Zmax = repartition_zone (villes, zone_taille) # calcul des distances print "calcul des distances" li = [] for z in xrange (0,len (zones)): if z % 1000 == 0 : print "zone ", z, len(zones) voisin = voisinage_zone (z,Zmax,X,Y) for v in zones [z]: for zz in voisin: for u in zones [zz]: d = distance (v [0], u [0]) li.append ((v [2], u [2], d)) print "tri ", len(li) li.sort (tri_distance) # composantes connexes print "construction de l'arbre" # nombre de composantes connexes nb_comp = len (villes) # indice de la composante d'une ville num_comp = [ i for i in xrange(0,len(villes)) ] # liste des voisins pour chaque ville arbre = [ [] for i in xrange(0,len(villes)) ] # liste des villes par composante connexe list_comp = [ [i] for i in xrange(0,len(villes)) ] iii = 0 for c in li: if iii % 10000 == 0 : print "arête ", iii, len(li) iii += 1 i,j = c [0], c [1] if num_comp [i] != num_comp [j]: # on relie les villes i et j car elles appartiennent # à des composantes connexes différentes arbre [i].append (j) # i est voisine de j arbre [j].append (i) # j est voisine de i cl = num_comp [i] # composante connexe restante ki = num_comp [j] # composante connexe à aggréger à la précédente for k in list_comp [ki]: num_comp [k] = cl list_comp [cl].append (k) list_comp [ki] = [] nb_comp -= 1 # une composante connexe en moins if nb_comp == 0: break # il n'y a plus qu'une seule composante connexe, inutile de continuer return arbre def display_arbre (villes, arbre, mult = 1): """dessine le graphe de poids minimal défini par arbre""" if mult == 2 : color = 0,255,0 l = 4 else : l = 1 color = 0,0,255 for i in xrange (0, len (villes)): for j in arbre [i]: v = (villes [i][0] * mult, villes [i][1] * mult) vv = (villes [j][0] * mult, villes [j][1] * mult) pygame.draw.line (screen, color, v, vv, l) def vecteur_points (p1,p2): """retourne le vecteur entre les points p1 et p2""" return ( p2 [0] - p1 [0], p2 [1] - p1 [1]) def vecteur_norme (vec): """retourne la norme d'un vecteur""" return math.sqrt (vec [0] * vec [0] + vec [1] * vec [1]) def vecteur_cosinus (vec1, vec2): """retourne le cosinus entre deux vecteurs, utilise le produit scalaire""" norm1 = vecteur_norme (vec1) norm2 = vecteur_norme (vec2) if norm1 == 0: return 1 if norm2 == 0: return 1 scal = vec1 [0] * vec2 [0] + vec1 [1] * vec2 [1] return scal / (norm1 * norm2) def vecteur_sinus (vec1, vec2): """retourne le sinus entre deux vecteurs, utilise le produit vectoriel""" norm1 = vecteur_norme (vec1) norm2 = vecteur_norme (vec2) if norm1 == 0: return 0 if norm2 == 0: return 0 scal = vec1 [0] * vec2 [1] - vec1 [1] * vec2 [0] return scal / (norm1 * norm2) def oppose_vecteur (vec): """retourne le vecteur opposé""" return (- vec [0], - vec [1]) def circuit_eulerien (villes, arbre): """définit un circuit eulérien, villes contient la liste des villes, tandis que arbre est une liste de listes, arbre [i] est la liste des villes connectées à la ville i, on suppose que arbre est un graphe de poids minimal non orienté, l'algorithme ne marche pas s'il existe des villes confondues""" # on choisit une ville qui est une extrémité et parmi celle-là on la choisit au hasard has = [] for i in xrange (0,len (villes)): n = len (arbre [i]) if n == 1: has.append (i) bm = random.randint (0, len (has) -1) bm = has [bm] # vecteur, le circuit eulérien contient # nécessairement 2 * len (villes) noeuds puisque c'est # le graphe eulérien d'un arbre de poids minimal non orienté vec = (1,1) chemin = [bm] while len (chemin) < 2 * len (villes)-1 : v = villes [bm] ma = - math.pi - 1 bvec = vec opvec = oppose_vecteur (vec) for k in xrange (0, len (arbre [bm])) : l = arbre [bm][k] vec2 = vecteur_points (v, villes [l]) if opvec == vec2 : angle = -math.pi else : cos = vecteur_cosinus (vec, vec2) sin = vecteur_sinus (vec, vec2) angle = math.atan2 (sin, cos) if angle > ma : ma = angle bl = k bvec = vec2 b = arbre [bm][bl] chemin.append (b) del arbre [bm][bl] # on supprime l'arc pour ne plus l'utiliser bm = b vec = bvec return chemin def circuit_hamiltonien (chemin): """extrait un circuit hamiltonien depuis un circuit eurlérien""" nb = max (chemin) + 1 res = [] coche = [ False for i in xrange (0, nb) ] for c in chemin : if coche [c] : continue res.append (c) coche [c] = True return res def equation_droite (p1,p2) : """retourne l'équation d'une droite passant par p1 et p2, ax + by + c = 0, retourne les coefficients a,b,c""" vec = vecteur_points (p1,p2) a = vec [1] b = - vec [0] c = - a * p1 [0] - b * p1 [1] return a,b,c def evaluation_droite (a,b,c,p): """l'équation d'une droite est : ax + by + c, retourne la valeur de cette expression au point p""" return a * p [0] + b * p [1] + c def intersection_segment (p1,p2,p3,p4): """dit si les segments [p1 p2] et [p3 p4] ont une intersection, ne retourne pas l'intersection""" # équation de la droite (p1 p2) a1,b1,c1 = equation_droite (p1,p2) a2,b2,c2 = equation_droite (p3,p4) s1 = evaluation_droite (a2,b2,c2,p1) s2 = evaluation_droite (a2,b2,c2,p2) s3 = evaluation_droite (a1,b1,c1,p3) s4 = evaluation_droite (a1,b1,c1,p4) if s1 * s2 <= 0 and s3 * s4 <= 0 : return True else : return False def longueur_chemin (chemin): """retourne la longueur d'un chemin""" s = 0 nb = len (chemin) for i in xrange (0,nb) : s += distance ( chemin [i], chemin [ (i+1) % nb ]) return s def retournement_essai (chemin, i,j, negligeable = 1e-5): """dit s'il est judicieux de parcourir le chemin entre les sommets i et j en sens inverse, si c'est judicieux, change le chemin et retourne True, sinon, retourne False, si j < i, alors la partie à inverser est i, i+1, i+2, ..., len(chemin) -1, 0, 1, ..., j""" nb = len (chemin) if i == j : return False if j - i == -1 : return False if j - i - nb == -1 : return False ia = (i - 1 + nb) % nb ja = (j + 1 ) % nb # arcs enlevés d_ia_i = distance (chemin [ia], chemin [i]) d_j_ja = distance (chemin [j], chemin [ja]) # arcs ajoutés d_ia_j = distance (chemin [ia], chemin [j]) d_i_ja = distance (chemin [i], chemin [ja]) # amélioration ? d = d_ia_j + d_i_ja - d_j_ja - d_ia_i if d >= - negligeable : return False # si amélioration, il faut retourner le chemin entre les indices i et j jp = j if jp < i : jp = j + nb ip = i while ip < jp : i = ip % nb j = jp % nb ech = chemin [i] chemin [i] = chemin [j] chemin [j] = ech ip = ip+1 jp = jp-1 return True def retournement (chemin, taille) : """amélioration du chemin par un algorithme simple, utilise des retournements de taille au plus <taille>, retourne le nombre de modifications""" # traitement des petits retournements nb = len (chemin) nb_change = 1 nbtout = 0 retour = { } while nb_change > 0 : nb_change = 0 for t in xrange (1,taille+1): retour [t] = 0 for i in xrange (0, nb) : j = (i + t) % nb b = retournement_essai (chemin, i, j) if b : retour [t] += 1 nb_change += 1 nbtout += nb_change print "nombre de retournements %d longueur : \t %10.0f détail \t" \ % (nbtout, longueur_chemin (chemin)), " détail : ", retour return nbtout def echange_position_essai (chemin, a,b, x, inversion, negligeable = 1e-5): """échange la place des villes ka à kb pour les placer entre les villes i et i+1, si inversion est True, on inverse également le chemin inséré, si inversion est False, on ne l'inverse pas, si cela améliore, déplace les villes et retourne True, sinon, retourne False""" nb = len(chemin) xa = (x + 1) % nb ka = (a - 1 + nb) % nb kb = (b + 1 ) % nb if not inversion : if x == ka : return False if x == kb : return False if xa == ka : return False if b < a : if a <= x <= b + nb : return False elif a <= x <= b : return False if b < a : if a <= x + nb <= b + nb : return False elif a <= x + nb <= b : return False # arcs enlevés d_x_xa = distance (chemin [x], chemin [xa]) d_ka_a = distance (chemin [ka], chemin [a]) d_b_kb = distance (chemin [b], chemin [kb]) # arcs ajoutés d_ka_kb = distance (chemin [ka], chemin [kb]) d_x_a = distance (chemin [x], chemin [a]) d_b_xa = distance (chemin [b], chemin [xa]) d = d_ka_kb + d_x_a + d_b_xa - d_x_xa - d_ka_a - d_b_kb if d >= -negligeable : return False # villes à déplacer ech = [] bp = b if bp < a : bp = b + nb for i in xrange (a,bp+1): ech.append (chemin [i % nb] ) diff = bp - a + 1 xp = x if xp < b : xp += nb for l in xrange (b+1,xp+1) : ll = l % nb bp = (a + l - b-1) % nb chemin [bp] = chemin [ll] for l in xrange (0,len(ech)) : chemin [ (x+l-diff+1 + nb) % nb ] = ech [l] return True else : if x == ka : return False if x == kb : return False if xa == ka : return False if b < a : if a <= x <= b + nb : return False elif a <= x <= b : return False if b < a : if a <= x + nb <= b + nb : return False elif a <= x + nb <= b : return False # arcs enlevés d_x_xa = distance (chemin [x], chemin [xa]) d_ka_a = distance (chemin [ka], chemin [a]) d_b_kb = distance (chemin [b], chemin [kb]) # arcs ajoutés d_ka_kb = distance (chemin [ka], chemin [kb]) d_x_b = distance (chemin [x], chemin [b]) d_a_xa = distance (chemin [a], chemin [xa]) d = d_ka_kb + d_x_b + d_a_xa - d_x_xa - d_ka_a - d_b_kb if d >= -negligeable : return False # villes à déplacer ech = [] bp = b if bp < a : bp = b + nb for i in xrange (a,bp+1): ech.append (chemin [i % nb] ) ech.reverse () diff = bp - a + 1 cop = copy.copy (chemin) xp = x if xp < b : xp += nb for l in xrange (b+1,xp+1) : ll = l % nb bp = (a + l - b-1) % nb chemin [bp] = chemin [ll] for l in xrange (0,len(ech)) : chemin [ (x+l-diff+1 + nb) % nb ] = ech [l] return True def dessin_arete_zone (chemin, taille_zone, X,Y): """retourne une liste de listes de listes, res [i][j] est une liste des arêtes passant près de la zone (x,y) = [i][j], si k in res [i][j], alors l'arête k,k+1 est dans la zone (i,j), X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur du côté du carré d'une zone""" res = [ [ [] for j in xrange (0,Y+1) ] for i in xrange (0,X+1) ] nb = len (chemin) for i in xrange (0,nb): a = chemin [i] b = chemin [(i+1) % nb] x1,x2 = int (a [0] // taille_zone), int (b [0] // taille_zone) y1,y2 = int (a [1] // taille_zone), int (b [1] // taille_zone) line = brl.trace_ligne (x1,y1,x2,y2) for x,y in line: res [x][y].append (i) return res def voisinage_zone_xy (x,y,X,Y): """retourne la liste des voisins d'une zone (x,y) sachant qu'il y a X zones sur l'axe des abscisses et Y zones sur l'axe des ordonnées, inclus z dans cette liste""" voisin = [(x,y)] if x > 0 : voisin.append ((x-1,y)) if x < X-1 : voisin.append ((x+1,y)) if y > 0 : voisin.append ((x,y-1)) if y < Y-1 : voisin.append ((x,y+1)) if x > 0 and y > 0 : voisin.append ((x-1,y-1)) if x > 0 and y < Y-1 : voisin.append ((x-1,y+1)) if x < X-1 and y > 0 : voisin.append ((x+1,y-1)) if x < X-1 and y < Y-1 : voisin.append ((x+1,y+1)) return voisin def echange_position (chemin, taille, taille_zone, X,Y, grande = 0.5) : """regarde si on ne peut pas déplacer un segment de longueur taille pour supprimer les arêtes les plus longues, au maximum <grande> longues arêtes, retourne le nombre de changement effectués, X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur d'un côté du carré d'une zone""" nb = len(chemin) def tri_arete (x,y): """pour trier la liste l par ordre décroissant""" if x [2] < y [2] : return 1 elif x [2] > y [2] : return -1 else : return 0 # list des arêtes triés par ordre décroissant la = [] for i in xrange (0,nb) : im = (i+1) % nb la.append ( (i, im, distance (chemin [i], chemin [im]) ) ) la.sort (tri_arete) # zone associé à chaque arête zone = dessin_arete_zone (chemin, taille_zone, X, Y) dseuil = la [ int (nb * grande) ] [ 2 ] nbtout = 0 nb_change = 0 iarete = 0 retour = { } for t in xrange (1, taille+1): retour [t] = 0 while iarete < nb : nb_change = 0 arete = la [iarete] iarete += 1 x = arete [0] xm = arete [1] a = chemin [x] b = chemin [xm] d = distance ( a,b ) if d < dseuil : break # arête trop petite # zone traversée par la ligne x1,x2 = int (a [0] // taille_zone), int (b [0] // taille_zone) y1,y2 = int (a [1] // taille_zone), int (b [1] // taille_zone) ens = brl.trace_ligne (x1,y1,x2,y2) ville = [] for k,l in ens: voisin = voisinage_zone_xy (k,l,X,Y) for u,v in voisin : ville.extend (zone [u][v]) # on supprime les doubles ville.sort () if len (ville) == 0 : continue sup = [] mx = -1 for v in ville: if v == mx : sup.append (v) mx = v for s in sup: ville.remove (s) # on étudie les possibilités de casser l'arête (x,xm) aux alentours des villes # comprise dans l'ensemble ville for t in xrange (1, taille+1): for i in ville: # on essaye d'insérer le sous-chemin (x- t + 1 + nb) --> x # au milieu de l'arête i,i+1 b = echange_position_essai (chemin, (x- t + 1 + nb) % nb,x, i, False) if b : nb_change += 1 retour [t] += 1 continue # on essaye d'insérer le sous-chemin (xm+ t - 1) --> xm # au milieu de l'arête i,i+1 b = echange_position_essai (chemin, (xm + t - 1) % nb, xm, i, False) if b : nb_change += 1 retour [t] += 1 continue # on essaye de casser l'arête x,xm en insérant # le sous-chemin i --> (i+t) % nb b = echange_position_essai (chemin, i, (i+t) % nb, x, False) if b : nb_change += 1 retour [t] += 1 continue # idem b = echange_position_essai (chemin, i, (i+t) % nb, x, True) if b : retour [t] += 1 nb_change += 1 continue # idem b = echange_position_essai (chemin, (i-t+nb) % nb, i, x, False) if b : nb_change += 1 retour [t] += 1 continue # idem b = echange_position_essai (chemin, (i-t + nb) % nb, i, x, True) if b : retour [t] += 1 nb_change += 1 continue nbtout += nb_change print "nombre de déplacements %d longueur : \t %10.0f détail \t" \ % (nbtout, longueur_chemin (chemin)), " détail : ", retour return nbtout def supprime_croisement (chemin, taille_zone, X,Y) : """supprime les croisements d'arêtes, retourne le nombre de changement effectués, X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur d'un côté du carré d'une zone""" nb = len(chemin) # zone associé à chaque arête zone = dessin_arete_zone (chemin, taille_zone, X, Y) nbtout = 0 for i in xrange (0,nb) : im = (i+1) % nb a = chemin [i] b = chemin [im] # zone traversée par la ligne x1,x2 = int (a [0] // taille_zone), int (b [0] // taille_zone) y1,y2 = int (a [1] // taille_zone), int (b [1] // taille_zone) ens = brl.trace_ligne (x1,y1,x2,y2) ville = [] for k,l in ens: voisin = voisinage_zone_xy (k,l,X,Y) for u,v in voisin : ville.extend (zone [u][v]) # on supprime les doubles ville.sort () if len (ville) == 0 : continue sup = [] mx = -1 for v in ville: if v == mx : sup.append (v) mx = v for s in sup: ville.remove (s) nb_change = 0 for v in ville : b = retournement_essai (chemin, i,v) if b : nb_change += 1 continue b = retournement_essai (chemin, im,v) if b : nb_change += 1 continue nbtout += nb_change print "nombre de croisements %d longueur : \t %10.0f détail \t" \ % (nbtout, longueur_chemin (chemin)) return nbtout def amelioration_chemin (chemin, taille_zone, X, Y, taille = 10, screen = None): """amélioration du chemin par un algorithme simple, utilise des retournements de taille au plus taille, traite les arcs qui se croisent, traite les grands arcs, utilise un quadrillage de taille window, X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur d'un côté du carré d'une zone""" white = 255,255,255 #première étape rapide nb = 1 while nb > 0: nb = retournement (chemin, taille) if screen != None: screen.fill (white) display_neurone(chemin, screen, 0) pygame.display.flip () # amélioration nb = 1 while nb > 0: nb = retournement (chemin, taille) if screen != None: screen.fill (white) display_neurone(chemin, screen, 0) pygame.display.flip () nb += echange_position (chemin, taille / 2, taille_zone, X, Y) if screen != None: screen.fill (white) display_neurone(chemin, screen, 0) pygame.display.flip () nb += supprime_croisement (chemin, taille_zone,X,Y) if screen != None: screen.fill (white) display_neurone(chemin, screen, 0) pygame.display.flip () if screen != None : for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONUP : print "attendre......................................................" attendre_clic (screen,0,0) print "reprise" break ################################################################################ if __name__ == "__main__" : pygame.init () # pysco.full () # pour accélérer le programme, va trois à quatre fois plus vite nb_ville = 500 partie = 10 size = width, height = x,y = 800, 500 dec = size [0] black = 0, 0, 0 white = 255,255,255 screen = pygame.display.set_mode(size) villes = construit_ville (nb_ville, x, y) taille_zone = 20 X = int (x // taille_zone) Y = int (y // taille_zone) print "taille de l'image : ", size print "nombre de villes : ", len(villes) screen.fill (white) display_ville (villes, screen, 0) pygame.display.flip () attendre_clic(screen,0,0) print "calcul" window = int (math.sqrt (x*y / len(villes)) * 2) arbre = arbre_poids_minimal (villes, window) arbre2 = copy.deepcopy (arbre) print "dessin" ,window display_arbre (villes, arbre) attendre_clic(screen,0,0) print "circuit eulérien" chemin = circuit_eulerien (villes ,arbre) print "circuit hamiltonien" neurone = circuit_hamiltonien (chemin) print "dessin" neurones = [ villes [i] for i in neurone ] display_neurone(neurones, screen, 0) attendre_clic(screen,0,0) print "amelioration_chemin et dessin" amelioration_chemin (neurones, taille_zone, X, Y, partie, screen) screen.fill (white) display_ville (villes, screen, 0) display_neurone(neurones, screen, 0) attendre_clic(screen,0,0) # taille double print "taille double" size = (size [0], size [1]) screen = pygame.display.set_mode(size) screen.fill (white) #display_arbre (villes, arbre2, 2) display_neurone (neurones, screen, 2) attendre_clic(screen,0,0)
edit distance and sequence alignment
class EditDistanceAlignment_Element : """ element used during the computation of an edit distance """ def __init__ (self, pos, cost, el1, el2, op) : """ constructor @param pos (tuple) position @param cost cost @param el1 first element @param el2 second element @param op operation (cmp, ins1, ins2, None) """ self.pos = pos self.el1 = el1 self.el2 = el2 self.cost = cost self.op = op # "cmp", "ins1", "ins2", None def __str__ (self) : """ usual """ return "pos1=%d pos2=%d cost=%s op=%s el1=%s el2=%s" % \ (self.pos[0], self.pos[1], "%1.3f" % self.cost if self.cost != None else "None", self.op, self.el1, self.el2) def EditDistanceAlignment ( exp1, exp2, cmpinsFunction = lambda x,y : 0.0 if x == y else 1.0, constantEpsilon = 1e-5, constantInfinite = 1e5, setPosition = [ (-1,-1), (-1,0), (0,-1), ], returnDistance = True) : """ computes the edit distance and the alignment between two expressions or strings @param exp1 first sequence @param exp2 second sequence @param cmpinsFunction function which returns a cost for a comparison or an insertion (None for the other element), example: @code lambda x,y : 0.0 if x == y else 1.0 @endcode @param constantEpsilon unused @param constantInfinite a weight for impossible configuration @param setPosition direction to consider while running the edit distance @param returnDistance if True, the function returns a float, otherwise, a path @return a float (if returnDistance is True) or a sequence of @see cl EditDistanceAlignment_Element) """ if len(exp1) == 0 : return 0 if len(exp2) == 0 else sum ( [ cmpinsFunction (None, e) for e in exp2] ) if len(exp2) == 0 : return sum ( [ cmpinsFunction (e, None) for e in exp1] ) l1 = len(exp1) + 1 l2 = len(exp2) + 1 l = l1*l2 pa = { } pred = { } for n,el in enumerate (exp1) : pa [n,0] = cmpinsFunction(el,None) pred[n,0] = (n-1,0) for n,el in enumerate (exp2) : pa [0,n] = cmpinsFunction(None,el) pred[0,n] = (0,n-1) pa[0,0] = 0.0 for n1,el1 in enumerate (exp1) : for n2,el2 in enumerate (exp2) : cost = [ ] for dx,dy in setPosition : c = pa.get ( (n1+dx+1, n2+dy+1), constantInfinite) if dx == 0 : if dy == -1 : cost.append ( (c+cmpinsFunction (None, el2), (dx,dy) ) ) else : raise NotImplementedError ("unable to deal with with case yet %d,%d" %(dx,dy)) elif dy == 0 : if dx == -1 : cost.append ( (c+cmpinsFunction (el1, None), (dx,dy) ) ) else : raise NotImplementedError ("unable to deal with with case yet %d,%d" %(dx,dy)) else : if dx == -1 and dy == -1: cost.append ( (c+cmpinsFunction (el1, el2), (dx,dy) ) ) else : raise NotImplementedError ("unable to deal with with case yet %d,%d" %(dx,dy)) mn = min ( cost ) pa [n1+1,n2+1] = mn[0] pred [n1+1,n2+1] = (n1+mn[1][0]+1,n2+mn[1][1]+1) if returnDistance : return pa [ l1-1,l2-1 ] else : align = [ ] p = l1-1,l2-1 while p[0] != -1 and p[1] != -1 : e = EditDistanceAlignment_Element (p, pa[p], None,None,None) align.append (e) p = pred[p] align.pop() align.reverse() for n,th in enumerate(align) : pr = None if n == 0 else align[n-1] th.pos = (th.pos[0]-1,th.pos[1]-1) if pr == None : if th.pos == (0,0) : kind = "cmp" elif th.pos[1] == -1 : kind = "ins1" else : kind = "ins2" else : if th.pos == (pr.pos[0]+1, pr.pos[1]+1) : kind = "cmp" elif th.pos[0] == pr.pos[0] : kind = "ins2" else : kind = "ins1" th.op = kind if kind == "cmp" : th.el1 = exp1[th.pos[0]] th.el2 = exp2[th.pos[1]] elif kind == "ins1" : th.el1 = exp1[th.pos[0]] th.el2 = None elif kind == "ins2" : th.el1 = None th.el2 = exp2[th.pos[1]] return align def EditDistanceAlignmentNormalized ( exp1, exp2, cmpinsFunction = lambda x,y : 0.0 if x == y else 1.0, constantEpsilon = 1e-5, constantInfinite = 1e5, setPosition = [ (-1,-1), (-1,0), (0,-1), ], returnDistance = True) : def function (x,y) : if x == y : return 0 l1 = 0 if x == None else len(x) l2 = 0 if y == None else len(y) if l1 > l2 : return l2*(0.5 / len(exp1) + 0.5 / len(exp2)) + (l1-l2)*1.0 / len(exp1) elif l2 > l1 : return l1*(0.5 / len(exp1) + 0.5 / len(exp2)) + (l2-l1)*1.0 / len(exp2) else : return l1*(0.5 / len(exp1) + 0.5 / len(exp2)) return EditDistanceAlignment(exp1, exp2, function, constantEpsilon, constantInfinite, setPosition, returnDistance) def EditDistanceAlignmentWordSequenceInString (exp1, exp2, cmpinsFunction = lambda x,y : 0.0 if x == y else 1.0, constantEpsilon = 1e-5, constantInfinite = 1e5, setPosition = [ (-1,-1), (-1,0), (0,-1), ], returnDistance = True) : spl1 = exp1.split(' ') spl2 = exp2.split(' ') def function (x,y) : if x == y : return 0 if x == None : return len(spl2) if y == None : return len(spl1) return EditDistanceAlignment(x,y, cmpinsFunction, constantEpsilon, constantInfinite, setPosition, True) return EditDistanceAlignment(spl1, spl2, function, constantEpsilon, constantInfinite, setPosition, returnDistance) if __name__ == "__main__" : def cmpins (x,y) : if x == y : return 0 if x in ("n","m") and y in ("n","m") : return 0.25 if (x == "s" and y == None) or (x == None and y == "s") : return 0.5 return 1 # alignment res = EditDistanceAlignment ("cmp", "cmps", cmpins, returnDistance = False) for _ in res : print (_) # only distance res = EditDistanceAlignment ("cmp", "cmps", cmpins) print (res) # alignment # other writing res = EditDistanceAlignment (list("cmp"), list("cmps"), cmpins, returnDistance = False) for _ in res : print (_) # numbers def cmpins_int (x,y) : if x == y : return 0. if x in (8,9) and y in (8,9) : return 0.25 return 1. res = EditDistanceAlignment ([1,2,8,7], [1,2,9,7], cmpins_int) print (res) res = EditDistanceAlignment ([1,2,8,7], [1,2,9,7], cmpins_int, returnDistance = False) for _ in res : print (_)
distance entre graphes
#coding:latin-1 """ @file @brief This modules gathers classes which describe a graph. The main method is DistanceMatchingGraphsPaths which does a kind of alignments between acyclic graphs. """ import os, sys, copy, re if sys.version_info.major >= 3 : fileprint = print else : def pprint(*x) : print (x) fileprint = pprint try : import importme except ImportError : pass class Vertex : """ defines a vertex of a graph """ def __init__ (self, nb, label, weight) : """ constructor @param nb (int) index of the vertex @param label (str) label @para weight (float) """ self.nb = nb # kind of id self.label = label # label self.pair = (None,None) self.edges = { } self.predE = { } self.succE = { } self.weight = weight #~ def __str__ (self) : #~ """ #~ usual #~ """ #~ li = [ "V %s l:%s nbSucc:%d" % (str(self.nb), self.label, len (self.succE)) ] #~ if self.pair != (None,None) : #~ li.append ( " (%s,%s)" % (str(self.pair[0]), str (self.pair[1])) ) #~ if self.edges != None : #~ li.extend ( [ " %s->%s" % (k,str(v)) for k,v in self.edges.items() ] ) #~ if self.predE != None : #~ li.extend ( [ " prev %s %s" % (k,"") for k,v in self.predE.items() ] ) #~ return "\n".join(li) def __str__(self) : """ usual """ return self.Label() def isVertex (self) : """ returns True """ return True def isEdge (self) : """ returns False """ return False def Label(self) : """ returns the label """ return self.label class Edge : """ defines an edge """ def __init__ (self,from_, to, label, weight) : """ constructor @param from_ (int) @param to (int) @param label (str) @param weight (float) """ self.from_, self.to = from_,to self.nb = from_, to self.label = label self.pair = (None,None) self.weight = weight if self.from_ == "00" and self.to == "00" : raise AssertionError ("should not happen") if self.from_ == "11" and self.to == "11" : raise AssertionError ("should not happen") #~ def __str__ (self) : #~ """ #~ usual #~ """ #~ li = [ "E %s->%s l:%s" % (str(self.from_), str(self.to), self.label) ] #~ if self.pair != (None,None) : #~ li.append (" (%s,%s)" % (str(self.pair[0]), str (self.pair[1])) ) #~ return "\n".join(li) def __str__(self) : """ usual """ return self.Label() def isVertex (self) : """ returns False """ return False def isEdge (self) : """ returns True """ return True def Label(self) : """ returns the label """ return self.label class Graph : """ defines a graph """ # graph is a dictionary def GetListOfVertices (graph) : edges = [ edge[:2] for edge in graph ] unique = { } for i,j in edges : unique [i] = unique [j] = 1 vertices = list(unique.keys()) vertices.sort() return vertices GetListOfVertices = staticmethod(GetListOfVertices) def __init__ (self, edgeList, vertexLabel = { }, addLoop = False, weightVertex = 1., weightEdge = 1.) : """ constructor @param edgeList list of edges @param addLoop automatically add a loop on each vertex (an edge from a vertex to itself) @param weightVertex weight for every vertex @param weightEdge weight for every edge """ if type(edgeList) is str : self.load_from_file(edgeList, addLoop) else : self.vertices = { } self.edges = { } self.labelBegin = "00" self.labelEnd = "11" vid = Graph.GetListOfVertices (edgeList) for u in vid : self.vertices [ u ] = Vertex (u, vertexLabel.get(u, str(u)), weightVertex) for e in edgeList : i,j = e[:2] l = "" if len(e) < 3 else e[2] self.edges [ i,j ] = Edge (i,j, str(l), weightEdge) self.private__init__(addLoop, weightVertex, weightEdge) def __getitem__ (self, index) : """ returns a vertex or an edge if no vertex with the given index was found @param index id (index) to look for @return Vertex or Edge """ if isinstance (index, str) : return self.vertices[index] elif isinstance (index, tuple) : return self.edges[index] else : raise KeyError("unable to get element " + str(index)) def load_from_file (self, filename, addLoop) : """ loads a graph from a file @param filename file name @param addLoop @see me __init__ """ lines = open(filename, "r").readlines () regV = re.compile("\\\"?([a-z0-9_]+)\\\"? *[[]label=\\\"(.*)\\\"[]]") regE = re.compile("\\\"?([a-z0-9_]+)\\\"? *-> *\\\"?" + \ "([a-z0-9_]+)\\\"? *[[]label=\\\"(.*)\\\"[]]") edgeList = [] vertexLabel = { } for line in lines : line = line.strip("\r\n ;") ed = regE.search(line) ve = regV.search(line) if ed : g = ed.groups() edgeList.append ( (g[0], g[1], g[2] ) ) elif ve : g = ve.groups() vertexLabel [g[0]] = g[1] if len(vertexLabel) == 0 or len(edgeList) == 0 : raise OSError("unable to parse file " + filename) self.__init__(edgeList, vertexLabel, addLoop) def private__init__(self, addLoop, weightVertex, weightEdge) : if addLoop : for k,v in self.vertices.items () : if k != self.labelBegin and k != self.labelEnd : self.edges [k,k] = Edge (k,k, "", weightEdge) self.ConnectRootAndLeave(weightVertex, weightEdge) self.ComputePredecessor() self.ComputeSuccessor() def ConnectRootAndLeave (self, weightVertex, weightEdge) : order = self.GetOrderVertices() roots = [ v for v,k in order.items () if k == 0 ] vert = { } for o in order : vert [o] = 0 for k,v in self.edges.items () : if k[0] != k[1] : vert[k[0]] += 1 for r in roots : if self.labelBegin not in self.vertices : self.vertices [ self.labelBegin ] = \ Vertex ( self.labelBegin, self.labelBegin, weightVertex) if r != self.labelBegin : self.edges [ self.labelBegin, r ] = \ Edge ( self.labelBegin, r, "", weightEdge ) leaves = [ k for k,v in vert.items () if v == 0 ] for r in leaves: if self.labelEnd not in self.vertices : self.vertices [ self.labelEnd ] = \ Vertex ( self.labelEnd, self.labelEnd, weightVertex) if r != self.labelEnd : self.edges [ r, self.labelEnd ] = \ Edge ( r, self.labelEnd, "", weightEdge ) def GetOrderVertices (self) : edges = self.edges order = { } for k,v in edges.items () : order[k[0]] = 0 order[k[1]] = 0 modif = 1 while modif > 0 : modif = 0 for k,v in edges.items () : i,j = k if i != j and order[j] <= order[i] : order [j] = order[i]+1 modif += 1 return order def __str__(self) : li = [] for k,v in self.vertices.items() : li.append ( str (v) ) for k,e in self.edges.items() : li.append ( str(e) ) return "\n".join(li) def ComputePredecessor (self) : """ usual """ pred = { } for i,j in self.edges : if j not in pred : pred[j] = { } pred [j][i,j] = 0 for k,v in pred.items () : for n in v : self.vertices[k].predE [n] = self.edges [n] def ComputeSuccessor (self) : succ = { } for i,j in self.edges : if i not in succ : succ[i] = { } succ [i][i,j] = i,j for k,v in succ.items () : for n in v : self.vertices[k].succE[n] = self.edges[n] def GetMatchingFunctions(self, functionMatchVertices, fonctionMatchEdges, cost = False) : """ returns default matching functions between two vertices and two edges @param functionMatchVertices if not None, this function is returned, othewise, it returns a new fonction. Example if cost is False: @code lambda v1,v2,g1,g2,w1,w2 : v1.label == v2.label @endcode Example if cost is True: @code def tempF1 (v1,v2,g1,g2,w1,w2) : if v1 != None and not v1.isVertex() : raise TypeError("should be a vertex") if v2 != None and not v2.isVertex() : raise TypeError("should be a vertex") if v1 == None and v2 == None : return 0 elif v1 == None or v2 == None : return v2.weight*w2 if v1 == None else v1.weight*w1 else : return 0 if v1.label == v2.label else 0.5*(v1.weight*w1 + v2.weight*w2) @endcode @param fonctionMatchEdges if not None, this function is returned, othewise, it returns a new fonction. Example if cost is False: @code lambda e1,e2,g1,g2,w1,w2 : e1.label == e2.label and (e1.from_ != e1.to or e2.from_ != e2.to) and (e1.from_ != self.labelBegin or e1.to != self.labelBegin) and (e1.from_ != self.labelEnd or e1.to != self.labelEnd) @endcode Example if cost is True: @code def tempF2 (e1,e2,g1,g2,w1,w2) : if e1 != None and not e1.isEdge() : raise TypeError("should be an edge") if e2 != None and not e2.isEdge() : raise TypeError("should be an edge") if e1 == None and e2 == None : return 0 elif e1 == None or e2 == None : return e2.weight*w2 if e1 == None else e1.weight*w1 elif e1.label != e2.label : return 0.5*(e1.weight*w1 + e2.weight*w2) else : lab1 = g1.vertices [e1.from_].label == g2.vertices [e2.from_].label lab2 = g1.vertices [e1.to].label == g2.vertices [e2.to].label if lab1 and lab2 : return 0 else : return e1.weight*w1 + e2.weight*w2 @endcode @param cost if True, the returned function should return a float, otherwise a boolean @return a pair of functions """ if cost : if functionMatchVertices == None : def tempF1 (v1,v2,g1,g2,w1,w2) : if v1 != None and not v1.isVertex() : raise TypeError("should be a vertex") if v2 != None and not v2.isVertex() : raise TypeError("should be a vertex") if v1 == None and v2 == None : return 0 elif v1 == None or v2 == None : return v2.weight*w2 if v1 == None else v1.weight*w1 else : return 0 if v1.label == v2.label else 0.5*(v1.weight*w1 + v2.weight*w2) functionMatchVertices = tempF1 if fonctionMatchEdges == None : def tempF2 (e1,e2,g1,g2,w1,w2) : if e1 != None and not e1.isEdge() : raise TypeError("should be an edge") if e2 != None and not e2.isEdge() : raise TypeError("should be an edge") if e1 == None and e2 == None : return 0 elif e1 == None or e2 == None : return e2.weight*w2 if e1 == None else e1.weight*w1 elif e1.label != e2.label : return 0.5*(e1.weight*w1 + e2.weight*w2) else : lab1 = g1.vertices [e1.from_].label == g2.vertices [e2.from_].label lab2 = g1.vertices [e1.to].label == g2.vertices [e2.to].label if lab1 and lab2 : return 0 else : return e1.weight*w1 + e2.weight*w2 fonctionMatchEdges = tempF2 else : if functionMatchVertices == None : functionMatchVertices = lambda v1,v2,g1,g2,w1,w2 : v1.label == v2.label if fonctionMatchEdges == None : fonctionMatchEdges = lambda e1,e2,g1,g2,w1,w2 : e1.label == e2.label and \ (e1.from_ != e1.to or e2.from_ != e2.to) and \ (e1.from_ != self.labelBegin or e1.to != self.labelBegin) and \ (e1.from_ != self.labelEnd or e1.to != self.labelEnd) return functionMatchVertices, fonctionMatchEdges def CommonPaths (self, graph2, functionMatchVertices = None, fonctionMatchEdges = None, noClean = False) : functionMatchVertices, fonctionMatchEdges = \ self.GetMatchingFunctions(functionMatchVertices, fonctionMatchEdges) g = Graph ( [] ) vfirst = Vertex ( self.labelBegin, "%s-%s" % (self.labelBegin, self.labelBegin), (self.vertices[self.labelBegin].weight + graph2.vertices[self.labelBegin].weight)/2) g.vertices [ self.labelBegin ] = vfirst vfirst.pair = self.vertices [ self.labelBegin ], graph2.vertices [ self.labelBegin ] modif = 1 while modif > 0 : modif = 0 add = { } for k,v in g.vertices.items () : v1,v2 = v.pair if len(v.succE) == 0 : for e1 in v1.succE : for e2 in v2.succE : oe1 = self.edges[e1] oe2 = graph2.edges[e2] if fonctionMatchEdges(oe1,oe2,self,graph2,1.,1.) : tv1 = self.vertices [oe1.to] tv2 = graph2.vertices [oe2.to] if functionMatchVertices (tv1, tv2, self, graph2, 1., 1.) : # we have a match ii = "%s-%s" % (tv1.nb, tv2.nb) if tv1.nb == self.labelEnd and tv2.nb == self.labelEnd : ii = self.labelEnd lab = "%s-%s" % (tv1.label, tv2.label) \ if tv1.label != tv2.label else tv1.label tv = Vertex (ii, lab, (tv1.weight+tv2.weight)/2) lab = "%s-%s" % (oe1.label, oe2.label) \ if oe1.label != oe2.label else oe1.label ne = Edge (v.nb, tv.nb, lab, (oe1.weight + oe2.weight)/2) add [ tv.nb ] = tv g.edges [ ne.from_, ne.to ] = ne ne.pair = oe1,oe2 tv.pair = tv1,tv2 v.succE [ ne.from_, ne.to ] = ne modif += 1 for k,v in add.items () : g.vertices[k] = v if not noClean : #g.ConnectRootAndLeave() g.ComputePredecessor() g.CleanDeadEnds() return g def CleanDeadEnds (self) : edgesToKeep = { } verticesToKeep = { } if self.labelEnd in self.vertices : v = self.vertices [ self.labelEnd ] verticesToKeep [v.nb] = False modif = 1 while modif > 0 : modif = 0 add = { } for k,v in verticesToKeep.items() : if v : continue modif += 1 verticesToKeep [k] = True for pred,vv in self.vertices[k].predE.items() : edgesToKeep [ pred ] = True add [ vv.from_ ] = verticesToKeep.get ( vv.from_, False ) for k,v in add.items () : verticesToKeep [k] = v remove = {} for k in self.vertices : if k not in verticesToKeep : remove[k] = True for k in remove : del self.vertices[k] remove = {} for k in self.edges: if k not in edgesToKeep : remove[k] = True for k in remove : del self.edges[k] else : self.vertices = {} self.edges = { } def EnumerateAllPaths (self, edgesAndVertices, begin = []) : if len(self.vertices) > 0 and len(self.edges) > 0 : if edgesAndVertices : last = begin[-1] if len(begin) > 0 \ else self.vertices [self.labelBegin] else : last = self.vertices[begin[-1].to] if len(begin) > 0 \ else self.vertices [self.labelBegin] if edgesAndVertices and len(begin) == 0 : begin = [ last ] for ef in last.succE : e = self.edges[ef] path = copy.copy(begin) v = self.vertices[e.to] if e.to == e.from_ : # cycle continue else : path.append (e) if edgesAndVertices : path.append (v) if v.label == self.labelEnd : yield path else : for p in self.EnumerateAllPaths(edgesAndVertices, path) : yield p def EditDistancePath (self, p1, p2, g1, g2, functionMatchVertices = None, fonctionMatchEdges = None, useMin = False, debug = False) : """ Tries to align two paths from two graphs @param p1 path 1 (from g1) @param p2 path 2 (from g2) @param g1 graph 1 @param g2 graph 2 @param functionMatchVertices function which gives a distance bewteen two vertices, if None, it take the output of @see me GetMatchingFunctions @param fonctionMatchEdges function which gives a distance bewteen two edges, if None, it take the output of @see me GetMatchingFunctions @param useMin the returned is based on a edit distance, if this parameter is True, the returned value will be: @code if useMin : n = min (len(p1), len(p2)) d = d*1.0 / n if n > 0 else 0 @endcode @param debug unused @return 2-uple: distance, aligned path """ functionMatchVertices, fonctionMatchEdges = \ self.GetMatchingFunctions(functionMatchVertices, fonctionMatchEdges, True) dist = { (-1,-1) : (0,None,None) } w1 = 1.0 / len(p1) if useMin else 1. w2 = 1.0 / len(p2) if useMin else 1. for i1,eorv1 in enumerate (p1) : for i2,eorv2 in enumerate (p2) : np = i1,i2 posit = [ ((i1-1,i2), (eorv1, None)), ((i1,i2-1), (None, eorv2)), ((i1-1,i2-1),(eorv1,eorv2)), ] if eorv1.isEdge() and eorv2.isEdge() : func = fonctionMatchEdges elif eorv1.isVertex() and eorv2.isVertex() : func = functionMatchVertices else : func = lambda x,y,g1,g2,w1,w2 : \ 0.5*(x.weight*w1 + y.weight*w2) if x != None and y != None \ else (x.weight*w1 if y == None else y.weight*w2) for p,co in posit : if p in dist : c0 = dist [p][0] c1 = func (co[0], co[1], g1, g2, w1, w2) c = c0 + c1 if np not in dist : dist[np] = (c, p, co, (c0, c1)) elif c < dist[np][0] : dist[np] = (c, p, co, (c0, c1)) last = dist [len(p1)-1, len(p2)-1] path = [ ] while last[1] != None : path.append (last) last = dist [ last[1] ] path.reverse() d = dist [len(p1)-1, len(p2)-1][0] if useMin : n = min (len(p1), len(p2)) d = d*1.0 / n if n > 0 else 0 return d, path def privateCountLeftRight (self, valuesInList) : countLeft = { } countRight = { } for k,v in valuesInList : i,j = v if i not in countRight : countRight [i] = { } countRight [i][j] = countRight [i].get (j, 0) + 1 if j not in countLeft : countLeft [j] = { } countLeft [j][i] = countLeft [j].get (i, 0) + 1 return countLeft, countRight def privateKruskalMatrix (self, matrix, reverse) : countLeft, countRight = self.privateCountLeftRight(matrix) cleft, cright = len(countLeft), len(countRight) cold = len(matrix) matrix.sort (reverse = reverse) count = max ( max ( [ sum (_.values()) for _ in countRight.values() ] ), max ( [ sum (_.values()) for _ in countLeft.values() ] ) ) oldcount = count while count > 1 : k,v = matrix.pop() i,j = v countRight[i][j] -= 1 countLeft [j][i] -= 1 count = max ( max ( [ max (_.values()) for _ in countRight.values() ] ), max ( [ max (_.values()) for _ in countLeft.values() ] ) ) mini = min(cleft, cright) if len(matrix) < mini : raise Exception("impossible: the smallest set should get all" + \ "its element associated to at least one coming from the other set") def privateStringPathMatching (self, path, skipEdge = False) : temp = [] for p in path : u,v = p[2] if skipEdge and ( (u != None and u.isEdge()) \ or (v != None and v.isEdge())) : continue su = "-" if u == None else str(u.nb) sv = "-" if v == None else str(v.nb) s = "(%s,%s)" % (su,sv) temp.append (s) return " ".join(temp) def DistanceMatchingGraphsPaths (self, graph2, functionMatchVertices = None, fonctionMatchEdges = None, noClean = False, store = None, useMin = True, weightVertex = 1., weightEdge = 1.) : """ compute an alignment between two graphs @param graph2 the other graph @param functionMatchVertices function which gives a distance bewteen two vertices, if None, it take the output of @see me GetMatchingFunctions @param fonctionMatchEdges function which gives a distance bewteen two edges, if None, it take the output of @see me GetMatchingFunctions @param noClean if True, clean unmatched vertices and edges @param store if None, does nothing, if it is a dictionary, the function will store here various information about how th matching was operated @param useMin @see me EditDistancePath @param weightVertex a weight for every vertex @param weightEdge a weight for every edge @return 2 tuple: - a distance - a graph containing the aligned paths between the two graphs """ functionMatchVertices, fonctionMatchEdges = \ self.GetMatchingFunctions(functionMatchVertices, fonctionMatchEdges, True) paths1 = list(self.EnumerateAllPaths (True)) paths2 = list(graph2.EnumerateAllPaths (True)) if store != None : store ["nbpath1"] = len (paths1) store ["nbpath2"] = len (paths2) matrix_distance = { } for i1,p1 in enumerate(paths1) : for i2,p2 in enumerate(paths2) : matrix_distance [i1,i2] = self.EditDistancePath (p1,p2, self, graph2, functionMatchVertices, fonctionMatchEdges, useMin = useMin) if store != None : store ["matrix_distance"] = matrix_distance reduction = [ (v[0], k) for k,v in matrix_distance.items() ] if store != None : store ["path_mat1"] = copy.deepcopy(reduction) self.privateKruskalMatrix(reduction, False) if store != None : store ["path_mat2"] = copy.deepcopy(reduction) pairCountEdge = { } pairCountVertex = { } for k,v in reduction : res,path = matrix_distance [v] for el in path : n1,n2 = el[2] if n1 != None and n2 != None : if n1.isEdge () and n2.isEdge() : add = n1.nb, n2.nb pairCountEdge[add] = pairCountEdge.get(add,0) + 1 elif n1.isVertex () and n2.isVertex() : add = n1.nb, n2.nb pairCountVertex[add] = pairCountVertex.get(add,0) + 1 if store != None : store["pairCountVertex"] = pairCountVertex store["pairCountEdge"] = pairCountEdge reductionEdge = [ (v, k) for k,v in pairCountEdge.items() ] if store != None : store ["edge_mat1"] = copy.copy (reductionEdge) self.privateKruskalMatrix(reductionEdge, True) if store != None : store ["edge_mat2"] = copy.copy (reductionEdge) reductionVertex = [ (v, k) for k,v in pairCountVertex.items() ] if store != None : store ["vertex_mat1"] = copy.copy (reductionVertex) self.privateKruskalMatrix(reductionVertex, True) if store != None : store ["vertex_mat2"] = copy.copy (reductionVertex) countEdgeLeft, countEdgeRight = self.privateCountLeftRight(reductionEdge) countVertexLeft, countVertexRight = self.privateCountLeftRight(reductionVertex) resGraph = Graph ([]) doneVertex = { } doneEdge = { } for k,v in self.vertices.items() : newv = Vertex (v.nb, v.label, weightVertex) resGraph.vertices [k] = newv if v.nb in countVertexRight : ind = list(countVertexRight[v.nb].keys())[0] newv.pair = ( v, graph2.vertices[ ind ] ) doneVertex[ ind ] = newv if newv.pair[0].label != newv.pair[1].label : newv.label = "%s|%s" % (newv.pair[0].label, newv.pair[1].label) else : newv.pair = ( v, None ) for k,v in graph2.vertices.items() : if k in doneVertex : continue newv = Vertex ("2a.%s" % v.nb, v.label, weightVertex) resGraph.vertices [newv.nb] = newv newv.pair = ( None, v ) for k,e in self.edges.items() : newe = Edge (e.from_, e.to, e.label, weightEdge) resGraph.edges [k] = newe if e.nb in countEdgeRight : ind = list(countEdgeRight[e.nb].keys())[0] newe.pair = ( e, graph2.edges[ ind ] ) doneEdge[ ind ] = newe else : newe.pair = ( e, None ) for k,e in graph2.edges.items() : if k in doneEdge : continue from_ = list(countVertexLeft[e.from_].keys())[0] if e.from_ in countVertexLeft \ else "2a.%s" % e.from_ to = list(countVertexLeft[e.to].keys())[0] if e.to in countVertexLeft \ else "2a.%s" % e.to if from_ not in resGraph.vertices : raise RuntimeError("should not happen " + from_) if to not in resGraph.vertices : raise RuntimeError("should not happen " + to) newe = Edge (from_, to, e.label, weightEdge) resGraph.edges [newe.nb] = newe newe.pair = ( None, e ) resGraph.ComputePredecessor() resGraph.ComputeSuccessor() allPaths = list(resGraph.EnumerateAllPaths(True)) temp = [ sum ( [ 0 if None in _.pair else 1 for _ in p ] ) * 1.0 / len(p) \ for p in allPaths ] distance = 1.0 - 1.0 * sum(temp) / len(allPaths) return distance,resGraph def DrawVerticesEdges(self) : vertices = [] edges = [] for k,v in self.vertices.items() : if v.pair == (None, None) or (v.pair[0] != None and v.pair[1] != None) : vertices.append ( (k, v.label) ) elif v.pair[1] == None : vertices.append ( (k, "-" + v.label, "red") ) elif v.pair[0] == None : vertices.append ( (k, "+" + v.label, "green") ) else : raise Exception("?") for k,v in self.edges.items() : if v.pair == (None, None) or (v.pair[0] != None and v.pair[1] != None) : edges.append ( (v.from_, v.to, v.label) ) elif v.pair[1] == None : edges.append ( (v.from_, v.to, "-" + v.label, "red") ) elif v.pair[0] == None : edges.append ( (v.from_, v.to, "+" + v.label, "green") ) else : raise Exception("?") return vertices,edges def unittest_GraphDistance2 (self, debug = False) : graph1 = [ ("a","b"), ("b","c"), ("b","X"), ("X","c"), \ ("c","d"), ("d","e"), ("0","b") ] graph2 = [ ("a","b"), ("b","c"), ("b","X"), ("X","c"), \ ("c","t"), ("t","d"), ("d","e"), ("d","g") ] graph1 = Graph(graph1) graph2 = Graph(graph2) store = { } distance,graph = graph1.DistanceMatchingGraphsPaths(graph2, useMin = False, store = store) if distance == None : raise TypeError("expecting something different from None") allPaths = list(graph.EnumerateAllPaths(True)) if len(allPaths) == 0 : raise ValueError("the number of paths should not be null") if distance == 0 : raise ValueError("expecting a distance > 0") vertices,edges = graph.DrawVerticesEdges() #GV.drawGraphEdgesVertices (vertices,edges, "unittest_GraphDistance2.png") node = graph.vertices["X"] if None in node.pair : raise RuntimeError("unexpected, this node should be part of the common set") if False : print ("distance",distance) for k,v in store.items() : print (k, len(v)) for _ in v : print (" ",_) vertices,edges = graph1.DrawVerticesEdges() #GV.drawGraphEdgesVertices (vertices,edges, "unittest_GraphDistance2_sub1.png") vertices,edges = graph2.DrawVerticesEdges() #GV.drawGraphEdgesVertices (vertices,edges, "unittest_GraphDistance2_sub2.png") if __name__ == "__main__" : fold = os.path.split(__file__) [0] fold = os.path.join(fold, "temp_gaph") if not os.path.exists (fold) : os.mkdir (fold) GV = importme.import_module ("use_graphviz", whereTo = fold) outfile1 = os.path.join(fold, "unittest_GraphDistance4_sub1.png") outfile2 = os.path.join(fold, "unittest_GraphDistance4_sub2.png") outfilef = os.path.join(fold, "unittest_GraphDistance4_subf.png") for f in [ outfile1, outfile2, outfilef ] : if os.path.exists (f) : os.remove (f) graph1 = [ ("a","b"), ("b","c"), ("b","d"), ("d","e"), \ ("e","f"), ("b","f"), ("b","g"), ("f", "g"), ("a","g"), ("a","g"), ("c","d"), ("d", "g"), ("d","h"), ("aa","h"), ("aa","c"), ("f", "h"), ] graph2 = copy.deepcopy(graph1) + \ [ ("h", "m"), ("m", "l"), ("l", "C"), ("C", "r"), ("a", "k"), ("k", "l"), ("k", "C"), ] graph1 = Graph(graph1) graph2 = Graph(graph2) graph2["C"].label = "c" store = { } if len(list(graph1.EnumerateAllPaths(True))) != 17 : raise Exception("expecting 17 here") if len(list(graph2.EnumerateAllPaths(True))) != 19 : raise Exception("expecting 19 here") distance,graph = graph1.DistanceMatchingGraphsPaths(graph2, useMin = False, store = store) if graph["h"].Label() != "h": raise Exception("we expect this node to be merged in the process") if distance == None : raise Exception("expecting something different from None") vertices,edges = graph1.DrawVerticesEdges() GV.drawGraphEdgesVertices (vertices,edges, outfile1, tempFolder = fold, moduleImport = importme) assert os.path.exists (outfile1) vertices,edges = graph2.DrawVerticesEdges() GV.drawGraphEdgesVertices (vertices,edges, outfile2, tempFolder = fold, moduleImport = importme) assert os.path.exists (outfile2) vertices,edges = graph.DrawVerticesEdges() GV.drawGraphEdgesVertices (vertices,edges, outfilef, tempFolder = fold, moduleImport = importme) assert os.path.exists (outfilef)
File: optimisation.tex, line 774
def fonction (x, a,b,c) : return x [0]**4 + a * x[0]**3 + b * x[1]**2 + c * x [1] def derivee (x, a,b,c) : return Num.array ( [4 * x[0]**3 + 3 * a * x[0]**2, b * 2 * x [1] + c] )
File: optimisation.tex, line 783
opt = optimisation_bfgs (fonction, derivee, (1,0.01,0.01)) x0 = Num.array ( [ 3, 4] ) x = opt.optimise (x0)
algorithme BFGS
# coding: cp1252 import numpy as Num # pour les tableaux import psyco class optimisation_bfgs (object) : """optimisation à l'aide de l'algorithme BFGS""" def __init__ (self, f, derivee, args = None, \ epsilon = 0.1, erreur = 1e-5, maxiter = 100) : """initialisation @param f fonction à minimiser --> f (x, args) où x est un vecteur (Numeric.array) @param derivee dérivée de f --> derivee (x, args) @param args autres paramètres de la fonction @param epsilon coefficient devant le gradient @param erreur on s'arrête lorsque l'erreur ne décroît plus @param maxiter nombre d'itérations maximum """ self._f = f self._derivee = derivee self._epsilon = epsilon self._erreur = erreur self._maxiter = maxiter self._args = args def erreur (self, x) : """calcule l'erreur""" return self._f (x, *self._args) def gradient (self, x) : """calcule le gradient""" return self._derivee (x, *self._args) def identite (self, dim) : """retourne la matrice identité""" b = Num.array ( [ [ 0 for i in xrange (0, dim) ] for j in xrange (0,dim) ] ) for i in xrange (0, dim) : b [(i,i)] = 1 return b def optimise (self, xO, classic = False, pr = True) : """optimisation selon l'algorithme BFGS, x0 est le vecteur initiale, retourne la meilleure solution, si pr == True, affiche des résultats intermédiaires, classic == True, la matrice bt est mise à jour à chaque itération, équivaut à une descente de gradient du premier degré""" dim = len (self.gradient (xO)) stop = 1e-12 err = self.erreur (xO) bt = self.identite (dim) id = True t = 0 iter = 0 old = err * (1.0 + self._erreur * 2) * 2 x = xO gt_ = self.gradient (xO) xt_ = xO nbt = 0 while (abs ((old - err) / err) > self._erreur or t == 0) and \ iter < self._maxiter : if pr : print "itération ", iter, " (", \ t,nbt, ") \t erreur : ", err, " (", old, ")" iter = iter + 1 gt = self.gradient (x) ct = Num.dot (bt, gt) e = abs (err) * 2 + 1 eps = self._epsilon * 2 while e > err and eps > stop : eps = eps / 2 xt = x - ct * eps e = self.erreur (xt) if eps < 1e-12 and t > 0 : bt = self.identite (dim) if t == 0 : nbt += 1 else : nbt = 0 t = 0 else : old = err x = xt err = e if not classic : gt = self.gradient (x) dt = gt - gt_ gbtg = Num.dot (Num.transpose (gt), Num.dot (bt, gt)) gbtd = Num.dot (Num.transpose (gt), Num.dot (bt, dt)) if (gbtg <= 0 or gbtd <= 0) and nbt < 2 : if t == 0 : nbt += 1 else : nbt = 0 bt = self.identite (dim) t = 0 else : t = t + 1 st = xt - xt_ dtbtdt = Num.dot (Num.transpose (dt), Num.dot (bt, dt)) dtst = Num.dot (Num.transpose (dt), st) stdt = Num.dot (Num.transpose (st), dt) stst = Num.outer (st, st) stdtbt = Num.dot (Num.outer (st, dt), bt) btdtst = Num.dot (bt, Num.outer (dt, st)) c = 1.0 + dtbtdt / dtst b = stst * (c / stdt) b -= (stdtbt + btdtst) / dtst bt = bt + b gt_ = gt xt_ = x return x if __name__ == "__main__" : psyco.full () def fonction (x, a,b,c) : return x [0]**4 + a * x[0]**3 + b * x[1]**2 + c * x [1] def derivee (x, a,b,c) : return Num.array ( [4 * x[0]**3 + 3 * a * x[0]**2, b * 2 * x [1] + c] ) opt = optimisation_bfgs (fonction, derivee, (1,0.01,0.01), \ maxiter = 2000, epsilon = 0.2, erreur = 1e-10) x0 = Num.array ( [ 3, 4] ) print "solution initiale : ", x0 x = opt.optimise (x0, classic = False) print "solution finale : ", x
File: optimisation.tex, line 797
x = opt.optimise (x0, classic = False)
File: optimisation.tex, line 803
x = opt.optimise (x0, classic = True)
simulation de tailles de poissons
# coding: cp1252 import random import math class poisson_loi (object) : """loi de distribution de la taille des poissons""" def __init__(self, alpha = 0.5, mm = 1, sm = 1, mf = 1, sf = 1) : """initialisation des paramètres de la loi""" self.alpha = alpha self.mm = mm self.sm = sm self.mf = mf self.sf = sf def init (self, l) : """initialisation de la classe avec une liste de variables""" m = 0 s = 0 for x in l : m += x s += x*x m /= len (l) s /= len (l) s -= m*m self.alpha = 0.5 self.sm = s / 2 self.sf = s / 2 self.sm = math.sqrt (self.sm) self.sf = math.sqrt (self.sf) self.mm = m + self.sm * 2 self.mf = m - self.sf * 2 def __str__(self) : """affichage""" s = "classe poisson_loi\n" s += "alpha = " + str (self.alpha) + "\n" s += "moyenne male = " + str (self.mm) + "\n" s += "sigma male = " + str (self.sm) + "\n" s += "moyenne femelle = " + str (self.mf) + "\n" s += "sigma femelle = " + str (self.sf) + "\n" return s def simulation (self) : """simule une taille de poisson""" u = random.uniform (0,1) v = random.gauss (0,1) if u <= self.alpha : return v * self.sm + self.mm else : return v * self.sf + self.mf def generate (self,N) : """simule N tailles de poisson""" return [ self.simulation () for i in xrange (0,N) ] def trace_densite (self, autre = None) : """trace la courbe de la densité, si autre != None, en trace une autre""" xa = min (self.mm, self.mf) - 3.0 * max (self.sm, self.sf) xb = max (self.mm, self.mf) + 3.0 * max (self.sm, self.sf) n = 100 x = [ xa + (xb - xa) * i / n for i in xrange (0,n+1) ] y = [ self.densite (xa + (xb - xa) * i / n) for i in xrange (0,n+1) ] import pylab as pl pl.plot ( x, y, "b" ) if autre != None : xa = min (autre.mm, autre.mf) - 3.0 * max (autre.sm, autre.sf) xb = max (autre.mm, autre.mf) + 3.0 * max (autre.sm, autre.sf) n = 100 x = [ xa + (xb - xa) * i / n for i in xrange (0,n+1) ] y = [ autre.densite (xa + (xb - xa) * i / n) for i in xrange (0,n+1) ] pl.plot (x, y, "r") pl.title ("Distribution des tailles de poisson") pl.xlabel ("x") pl.ylabel ("y") pl.show() def densite (self, x) : """calcule de la densité au point x""" dpi = 1.0 / math.sqrt (math.pi * 2) xm = (x - self.mm) ** 2 / (2 * self.sm * self.sm) xm = math.exp (- xm) xf = (x - self.mf) ** 2 / (2 * self.sf * self.sf) xf = math.exp (- xf) return self.alpha * xm / self.sm + (1.0 - self.alpha) * xf / self.sf def log_densite (self, x) : """calcule de la log-densité au point x""" try : return math.log (self.densite (x)) except : print "---------- erreur -------------------------------------------" print x return 0 def log_densite_list (self, l) : """calcule la somme des log-densités au point x de l""" s = 0 for x in l : s += self.log_densite (x) s /= len (l) return s def gradient (self, x) : """calcul le gradient au point x, retourne un t-uple""" unpim = 1.0 / (math.sqrt (2 * math.pi) * self.sm) unpif = 1.0 / (math.sqrt (2 * math.pi) * self.sf) expm = math.exp ( - ( x - self.mm)**2 / (2 * (self.sm**2))) expf = math.exp ( - ( x - self.mf)**2 / (2 * (self.sf**2))) grada = unpim * expm - unpif * expf gradmm = (x - self.mm) / (self.sm** 2) * self.alpha * unpim * expm gradmf = (x - self.mf) / (self.sf** 2) * (1.0 - self.alpha) * unpif * expf gradsm = self.alpha * unpim * (x - self.mm) ** 2 / (self.sm ** 3) - \ self.alpha * unpim / self.sm gradsm *= expm gradsf = (1.0 - self.alpha) * unpif * (x - self.mf) ** 2 / (self.sf ** 3) - \ self.alpha * unpif / self.sf gradsf *= expf f = self.densite (x) return (grada / f, gradmm / f, gradsm / f, gradmf / f, gradsf / f) def gradient_total (self, l) : """calcul la somme des gradients pour tous les x de l""" g = [ 0.0 for i in range (0,5) ] for x in l : (a,b,c,d,e) = self.gradient (x) g [0] += a g [1] += b g [2] += c g [3] += d g [4] += e for i in range (0,len (g)) : g [i] /= len (l) return ( g [0], g [1], g [2], g [3], g [4] ) def optimisation (self, l, epsilon = 0.001, erreur = 1e-5) : """recherche du maximum de la fonction f""" self.init (l) de = self.log_densite_list (l) print "première densité : ", de dold = de / 2 nb = 0 while abs (dold - de) / de > erreur : (a,b,c,d,e) = self.gradient_total (l) self.alpha += epsilon * a self.mm += epsilon * b self.sm += epsilon * c self.mf += epsilon * d self.sf += epsilon * e dold = de de = self.log_densite_list (l) nb += 1 print "itération ", nb, " densité ", de, " (", dold, ") ", \ abs (dold - de) / de, " epsilon = ", epsilon if __name__ == "__main__" : # création d'une instance de la classe cl = poisson_loi (0.55, 0.40, 0.020, 0.35, 0.015) print cl # affichage #cl.trace_densite () # courbe densité l = cl.generate (10000) cl2 = poisson_loi () print "-----------------------------------------------------------" print "log densité maximale ", cl.log_densite_list (l) (a,b,c,d,e) = cl.gradient_total (l) print "gradient idéal ", (a,b,c,d,e) print "-----------------------------------------------------------" (a,b,c,d,e) = cl2.gradient_total (l) print "gradient avant", (a,b,c,d,e) cl2.optimisation (l) (a,b,c,d,e) = cl2.gradient_total (l) print "gradient après ", (a,b,c,d,e) print "-----------------------------------------------------------" print cl2 cl2.trace_densite (cl) print "log vraisemblance : ", cl2.log_densite_list (l)
File: optimisation.tex, line 924
import psyco psyco.full ()
déterminer la taille des poissons
# coding: cp1252 import poisson #import scipy.optimize.lbfgsb as Opt # optimisation import bfgs # optimisation import numpy as Num # pour les tableaux import psyco def fonction_bfgs (x, cl, l) : """fonction retournant l'opposé de la log-vraisemblance de l'instance cl, fonction à minimiser""" cl.set (x) f = - cl.log_densite_list (l) #print f, "\t", x return f def fonction_derivee_bfgs (x, cl, l) : """fonction retournant l'opposé de la log-vraisemblance de l'instance cl, fonction à minimiser""" cl.set (x) f = cl.gradient_total (l) return - Num.array (f) class poisson_loi_bfgs (poisson.poisson_loi) : """loi de distribution de la taille des poissons, optimisation à l'aide de l'algorithme BFGS""" def __init__(self, alpha = 0.5, mm = 1, sm = 1, mf = 1, sf = 1) : """initialisation des paramètres de la loi""" poisson.poisson_loi.__init__(self, alpha, mm, sm, mf, sf) def set (self, x) : """initialisation avec un tableau""" self.alpha = x [0] self.mm = x [1] self.sm = abs (x [2]) self.mf = x [3] self.sf = abs (x [4]) def get (self) : """retourne un tableau contenant les paramètres""" return Num.array ( (self.alpha, self.mm, self.sm, self.mf, self.sf) ) def __str__(self) : """affichage""" s = "classe poisson_loi BFGS\n" s += "alpha = " + str (self.alpha) + "\n" s += "moyenne male = " + str (self.mm) + "\n" s += "sigma male = " + str (self.sm) + "\n" s += "moyenne femelle = " + str (self.mf) + "\n" s += "sigma femelle = " + str (self.sf) + "\n" return s def optimisation (self, l, epsilon = 0.001) : """recherche du maximum de la fonction f""" self.init (l) x0 = self.get () print x0 opt = bfgs.optimisation_bfgs (fonction_bfgs, \ fonction_derivee_bfgs, \ args = (self, l)) x = opt.optimise (x0) #x = bfgs.Opt.fmin_l_bfgs_b ( fonction_bfgs, \ # x0, \ # fonction_derivee_bfgs, \ # args = (self, l)) self.set (x) print "optimisation terminée" print "valeur maximale : ", self.log_densite_list (l) print "message ", d if __name__ == "__main__" : psyco.full () # création d'une instance de la classe cl = poisson.poisson_loi (0.55, 0.40, 0.020, 0.35, 0.015) print cl # affichage #cl.trace_densite () # courbe densité l = cl.generate (10000) cl2 = poisson_loi_bfgs () print "-----------------------------------------------------------" print "log densité maximale ", cl.log_densite_list (l) (a,b,c,d,e) = cl.gradient_total (l) print "gradient idéal ", (a,b,c,d,e) print "-----------------------------------------------------------" (a,b,c,d,e) = cl2.gradient_total (l) print "gradient avant", (a,b,c,d,e) cl2.optimisation (l) (a,b,c,d,e) = cl2.gradient_total (l) print "gradient après ", (a,b,c,d,e) print "-----------------------------------------------------------" print cl2 cl2.trace_densite (cl) print "log vraisemblance : ", cl2.log_densite_list (l)
optimisation en fonction d'une donnée aléatoire
import math def factorielle(x): if x == 0: return 1 else: return x * factorielle(x-1) def profit (N,X,p,q,s) : if X <= N : return X * (q-p) else : return X * (s-p) + N * (q-s) def proba_poisson (l, i) : return math.exp (-l) * (l ** i) / factorielle (i) def esperance (X,p,q,s,l) : res = 0.0 for i in range (0,l*2) : res += profit (float (i),X,p,q,s) * proba_poisson (l,i) return res def maximum (p,q,s,l) : res = [] for X in range (0, 2 * l) : r = esperance (X,p,q,s,l) res.append ((X,r)) return res def find_maximum (res) : m = (0,0) for r in res : if r [1] > m [1] : m = r return m if __name__ == "__main__" : res = maximum (2,5,1,80) m = find_maximum (res) print m # dessin d'une courbe from pylab import * plot ( [ r [1] for r in res] ) show ()
File: strategie_avec_alea.tex, line 149
def exponentielle (l) : u = random.random () return - 1.0 / l * math.log (1.0 - u) def poisson (l) : s = 0 i = 0 while s <= 1 : s += exponentielle (l) i += 1 return i-1
File: strategie_avec_alea.tex, line 166
def histogramme_poisson (l, n = 1000) : h = [ 0.0 for i in range (0,4*l+1) ] for i in range (0, n) : x = poisson (l) if x < len (h) : h [x] += 1 s = sum (h) for i in range (0, len (h)) : h [i] = float (h [i]) / s return h h = histogramme_poisson (10) from pylab import * plot (h, "r") plot ([ proba_poisson (10, i) for i in range (0, len (h))]) legend ( ["histogramme", u"densité" ] ) show ()
File: strategie_avec_alea.tex, line 198
def poisson_melange (params, coef) : s = 0 for i in range (0, len (params)) : p = poisson (params [i]) s += p * coef [i] return s
File: strategie_avec_alea.tex, line 210
def histogramme_poisson_melange (params, coef, n = 1000) : h = [ 0.0 for i in range (0, 4*sum(params)+1) ] for i in range (0, n) : x = poisson_melange (params, coef) if x < len (h) : h [x] += 1 s = sum (h) for i in range (0, len (h)) : h [i] = float (h [i]) / s return h h = histogramme_poisson_melange ([48,10,4], [1,2,3]) from pylab import * plot (h, "r") plot ([ proba_poisson (80, i) for i in range (0, len (h))]) legend ( [u"N1 + 2 N2 + 3 N3", u"Poisson (80)" ], "right") show ()
optimisation en fonction d'une donnée aléatoire selon un mélange de lois
# coding: cp1252 import math import random import psyco psyco.full () proba_poisson_melange_tableau = [] def exponentielle (l) : u = random.random () return - 1.0 / l * math.log (1.0 - u) def poisson (l) : s = 0 i = 0 while s <= 1 : s += exponentielle (l) i += 1 return i-1 def poisson_melange (params, coef) : s = 0 for i in range (0, len (params)) : p = poisson (params [i]) s += p * coef [i] return s def histogramme_poisson_melange (params, coef, n = 100000) : h = [ 0.0 for i in range (0, 4*max(params)) ] for i in range (0, n) : x = poisson_melange (params, coef) if x < len (h) : h [x] += 1 s = sum (h) for i in range (0, len (h)) : h [i] = float (h [i]) / s return h def profit (N,X,p,q,s) : if X <= N : return X * (q-p) else : return X * (s-p) + N * (q-s) def proba_poisson_melange (params, coef, i) : global proba_poisson_melange_tableau if len (proba_poisson_melange_tableau) == 0 : proba_poisson_melange_tableau = histogramme_poisson_melange (params, coef) if i >= len (proba_poisson_melange_tableau) : return 0.0 else : return proba_poisson_melange_tableau [i] def esperance (X,p,q,s,params, coef) : res = 0.0 for i in range (0,4*sum(params)) : res += profit (float (i),X,p,q,s) * proba_poisson_melange (params, coef,i) return res def maximum (p,q,s,params, coef) : res = [] for X in range (0, 4*sum (params)) : r = esperance (X,p,q,s,params, coef) res.append ((X,r)) return res def find_maximum (res) : m = (0,0) for r in res : if r [1] > m [1] : m = r return m if __name__ == "__main__" : res = maximum (2,5,1,[48,10,4], [1,2,3]) m = find_maximum (res) print m # dessin d'une courbe from pylab import * plot ( [ r [1] for r in res] ) show ()
File: finance_autostrat.tex, line 490
date time Open High Low Close Volume 07/11/2007 19:42 7822 7823 7818 7819.5 1130 07/11/2007 19:48 7819.5 7830 7819.5 7822.5 1543 07/11/2007 19:54 7823 7827.5 7819.5 7824 1244 07/11/2007 20:00 7824 7825.5 7822.5 7824.5 216 # 20.00 07/11/2007 20:24 7828 7833 7825.5 7830 640 # 20.24, il manque 3 périodes 07/11/2007 20:30 7829.5 7831.5 7827 7829.5 478 07/11/2007 20:36 7830 7830.5 7821 7829 716 07/11/2007 20:42 7829.5 7834.5 7826 7828 681
File: finance_autostrat.tex, line 860
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 14/03/08 60.27 60.78 59.00 59.53 2105500 13/03/08 59.01 60.47 59.00 60.15 2702700 12/03/08 60.84 60.85 59.35 60.02 2982400 11/03/08 61.12 61.56 60.00 60.47 2480900
graphe d'une série financière
#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')
simulation d'un pendule
#!/usr/bin/env pythonw2.3 # lignes utilisees pour matplotlib import matplotlib matplotlib.use("WXAgg") import matplotlib.pylab as pylab import numpy as N import math ############################################################################# # debut du programme ############################################################################# def pendule_lineaire (tt, vt, at, gR, dt) : """calcule t (t+1), v(t+1), a(t+1) t'' + gR t = 0""" at = - gR * tt vt += at * dt tt += vt * dt return tt,vt,at def pendule_non_lineaire (tt, vt, at, gR, dt) : """calcule t (t+1), v(t+1), a(t+1) t'' + gR t = 0""" at = - gR * math.sin (tt) vt += at * dt tt += vt * dt return tt,vt,at def periode (courbe,dt) : """estime la période d'une courbe dont on sait qu'elle est cyclique""" lp = [] p = 0 for i in range (1, len (courbe)-1) : if courbe [i-1] <= courbe [i] and courbe [i] >= courbe [i+1] : # maximum lp.append (i) # moyenne entre les durees entre deux maximas s = 0 for l in range (1,len (lp)) : s += lp [l] - lp [l-1] return float (s) / (len (lp)-1) * dt # initialisation : un angle t0 != 0, pas de vitesse, pas d'accélération t0 = 1 tt,vt,at = t0,0,0 stt,svt,sat = t0,0,0 dt = 0.01 gR = 0.5 t = 0 T = [] th = [] sth = [] cth = [] # boucle print "simultation" for i in range (0,4000) : T.append (t) th.append (tt) sth.append (stt) ctt = t0 * math.cos (math.sqrt (gR) * t) cth.append (ctt) t = t + dt tt,vt,at = pendule_lineaire (tt, vt, at, gR, dt) stt,svt,sat = pendule_non_lineaire (stt, svt, sat, gR, dt) print "periode theorique : ", math.pi * 2 / math.sqrt (gR) print "periode courbe theorique ", periode (cth, dt) print "periode courbe lineaire ", periode (th, dt) print "periode courbe non lineaire ", periode (sth, dt) # pour calculer l'angle a partir duquel la solution lineaire # n'est plus viable, il faut calculer la difference entre les periodes # et choisir un seuil au dela duquel la difference est trop grande # affichage des premieres valeurs print "premieres valeurs " print "angle initial : ", t0 * 180 / math.pi for i in range (0,10) : print T[i], " : ", th[i], "\t", cth [i], "\t", sth [i] # matplotlib n'accepte que des donnees stockees dans un type de tableau # definies dans le package Numeric aT = N.array (T) ath = N.array (th) acth = N.array (cth) asth = N.array (sth) # dessin de la courbe print "dessin de la courbe" pylab.title("Oscillation d'un pendule") pylab.xlabel("t") pylab.ylabel("theta") pylab.grid (True) pylab.plot (aT, ath, linewidth=1.0, color = "blue") pylab.plot (aT, acth, linewidth=1.0, color = "red") pylab.plot (aT, asth, linewidth=1.0, color = "green") pylab.show ()
simulation d'une corde en chute libre
# coding: cp1252 import pygame # pour les affichages import math # pour les racines carrées class point (object) : """définition d'un point : deux coordonnées et une masse""" __slots__ = "x","y","m" def __init__ (self, x,y,m) : """définit un point de la corde, de coordonnées (x,y) et de masse m""" self.x, self.y, self.m = float (x), float (y), float (m) def deplace (self, dep, dt) : """déplace un point""" self.x += dep [0] * dt self.y += dep [1] * dt def deplace_point (self, dep, dt) : """déplace un point""" self.x += dep.x * dt self.y += dep.y * dt def difference (self, p) : """retourne le vecteur qui relie deux points, retourne le couple de ses coordonnées""" return p.x - self.x, p.y - self.y def __str__ (self) : """afficher le point""" return "(x,y) = (%4.1f,%4.1f) masse %f" % (self.x,self.y,self.m) class corde (object) : """définition d'une corde, une liste de points""" def __init__(self, nb, p1, p2, m, k, g, f, l) : """initialisation d'une corde @param nb nombre de points @param p1 = x1,y1 coordoonnées du premier point (fixe) @param p2 = x2,y2 coordoonnées du dernier point (fixe) @param m masse de la corde, répartie entre tous les pointstous les points @param k raideur de l'élastique @param g intensité de l'apesanteur, valeur positive @param f vitesse de freinage @param l longueur de la corde""" x1,y1 = p1[0], p1[1] x2,y2 = p2[0], p2[1] self.list = [] self.vitesse = [] for i in range (0,nb) : x = x1 + float (i) * (x2 - x1) / float (nb - 1) y = y1 + float (i) * (y2 - y1) / float (nb - 1) self.list.append ( point (x,y, float (m) / nb)) self.vitesse.append (point (0,0,0)) self.k = k * nb self.g = g self.l = float (l) / (nb-1) self.f = f def display (self, screen) : """affichage de la corde à l'aide du module pyagame""" self.display_courbe_theorique (screen) x,y = screen.get_size () color = (0,0,0) for p in self.list : pygame.draw.circle (screen, color, (int (p.x), int (y - p.y)), int (p.m+1)) for i in xrange (0,len (self.list)-1) : pygame.draw.line (screen, color, \ (int (self.list [i].x), int (y - self.list [i].y)), \ (int (self.list [i+1].x), int (y - self.list [i+1].y))) def display_courbe_theorique (self, screen) : def cosh (x) : """retourne le cosinus hyperbolique de x""" return math.cosh (x) def sinh (x) : """retourne le sinus hyperbolique de x""" return math.sinh (x) def asinh (x) : """retourne la réciproque du sinus hyperbolique de x""" t = x + math.sqrt (x*x + 1) return math.log (t) def acosh (x) : """retourne la réciproque du cosinus hyperbolique de x""" t = abs (x) + math.sqrt (x*x - 1) return math.log (t) def trouve_alpha (x2, L) : """détermine la valeur de alpha une seule fois""" if self.__dict__.has_key ("alpha") : return self.alpha def fonction (a,x2,L) : if a == 0.0 : return 0.0 else : return 1.0 / a * sinh (a * x2) - L / 2 a1 = 1.0 / x2 a2 = 1.0 / x2 m = 1.0 / x2 diff = fonction (m, x2, L) while abs (diff) > 1e-3 : if diff > 0 : # faire décroître alpha if fonction (a1, x2, L) > 0 : a1 /= 2.0 else : a2 = m else : if fonction (a2, x2, L) < 0 : a2 *= 2.0 else : a1 = m m = (a1 + a2) / 2 diff = fonction (m, x2, L) self.alpha = m return m p1 = self.list [0] p2 = self.list [ len (self.list) - 1 ] if p1.y != p2.y : return None # cas non prévu # on trace la courbe y = cosh (alpha x) L = self.l * (len (self.list) - 1) mx = (p1.x + p2.x) / 2 x1 = p1.x - mx x2 = p2.x - mx alpha = trouve_alpha (x2, L) # est solution de 1/alpha sinh (alpha x1) = L/2 C = - 1.0 / alpha * cosh (alpha * x2) sx,sy = screen.get_size () color = (0,0,255) ix1 = int (x1) ix2 = int (x2) x0,y0 = p1.x,p1.y for i in xrange (ix1, ix2+1) : x = int (mx + i) y = 1.0 / alpha * cosh (alpha * float (i)) + C + p1.y if 0 < y < sy and 0 < y0 < sy : pygame.draw.line (screen, color, (x0,sy-y0), (x, sy-y), 2) x0,y0 = x,y def force_point (self, i) : """calcule les forces qui s'exerce en un point, retourne un couple x,y""" x,y = 0,0 # poids y -= self.g * self.list [i].m # voisin de gauche dx, dy = self.list [i].difference (self.list [i-1]) d = math.sqrt (dx *dx + dy *dy) if d > self.l : dx = (d - self.l) / d * dx dy = (d - self.l) / d * dy x += self.k * dx y += self.k * dy # voisin de droite dx, dy = self.list [i].difference (self.list [i+1]) d = math.sqrt (dx *dx + dy *dy) if d > self.l : dx = (d - self.l) / d * dx dy = (d - self.l) / d * dy x += self.k * dx y += self.k * dy # freinage x += - self.f * self.vitesse [i].x y += - self.f * self.vitesse [i].y return x,y def iteration (self, dt) : """calcule les déplacements de chaque point et les met à jour, on ne déplace pas les points situés aux extrémités, retourne la somme des vitesses et des accélérations au carré""" force = [ (0,0) ] for i in xrange (1, len (self.list)-1) : x,y = self.force_point (i) force.append ((x,y)) force.append ((0,0)) # déplacement for i in xrange (1, len (self.list)-1) : self.vitesse [i].deplace ( force [i], dt ) self.list [i].deplace_point ( self.vitesse [i], dt ) d = 0 for f in force : d += self.vitesse [i].x ** 2 + force [i][0] **2 d += self.vitesse [i].y ** 2 + force [i][1] **2 return d def __str__ (self): """affiche chaque point de la corde""" s = "" l = 0 for i in xrange (0, len (self.list)) : s += "point " + str (i) + " : " + str (self.list [i]) if i < len (self.list) -1 : x,y = self.list [i].difference (self.list [i+1]) d = math.sqrt (x*x + y*y) s += "\t segment : %4.0f" % d s += " ( %4.0f )" % self.l if i != 0 and i != len (self.list)-1 : x,y = self.force_point (i) s += "\t force en ce point (%f,%f) " % (x,y) s += "\n" if i > 0 : x,y = self.list [i].difference (self.list [i-1]) l += math.sqrt (x*x + y*y) s += "longueur de la corde " + str (l) + "\n" s += "longueur attendue " + str ((len (self.list)-1) * self.l) + "\n" return s def attendre_clic (screen,x,y): """dessine un rectangle rouge sur l'écran et attend la pression d'un clic de souris""" color = 255,0,0 pygame.draw.line (screen, color, (10,10), (x-10,10), 2) pygame.draw.line (screen, color, (x-10,10), (x-10,y-10), 2) pygame.draw.line (screen, color, (x-10,y-10), (10,y-10), 2) pygame.draw.line (screen, color, (10,y-10), (10,10), 2) pygame.display.flip () 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 = 800, 500 black = 0, 0, 0 white = 255,255,255 screen = pygame.display.set_mode(size) nb = 10 c = corde (nb, (100,450), (700,450), 100, 1, 0.1, 0.05, 800) dt = 0.1 print "corde initial" print c iter = 0 dep = len (c.list) * (x*x + y*y) while True and dep > 1e-6 : for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.MOUSEBUTTONUP: print c attendre_clic (screen,x,y) if iter % 10 == 0 : screen.fill (white) c.display (screen) pygame.display.flip () iter += 1 if iter == 1: attendre_clic (screen,x,y) dep = c.iteration (dt) #print "dep =", dep pygame.display.flip () print c attendre_clic (screen,x,y)
filtrage d'un signal sonore
import pygame import pygame.mixer import pygame.sndarray import FFT import math import numpy as Numeric import string import copy import pylab import numpy pygame.mixer.init () pygame.init () fourier = None indice = None def get_sound (): """charge le son sound010.wav""" s = pygame.mixer.Sound ("sound010.wav") t = pygame.sndarray.array (s) return s def play_sound(s): """joue un son""" s.play () def convert_array(t, s): """joue un son decrit dans un tableau a une dimension""" s = pygame.sndarray.array (s) for i in range (0, len (s)) : s [i]= t [i] #tt = Numeric.array ([ [x, x] for x in t] ) #print tt [0:10] s = pygame.sndarray.make_sound (s) return s def array_sound(s): """convertit un son en un tableau d'entiers""" a = pygame.sndarray.array(s) t = Numeric.array([i for i in xrange(0,len(a))]) for i in xrange(0,len(a)): t [i] = a [i][0] return t def dessine_son(mem,t,fourier,ind,a,b): """dessine une partie du son, limite la taille a 512""" m = len (mem) if m > 256 : m = 256 x = [ i for i in xrange (ind,ind+m) ] y1 = [ mem[i] for i in xrange (ind,ind+m) ] y2 = [ t[i] for i in xrange (ind,ind+m) ] pylab.figure (1) p1 = pylab.plot (x,y1) p2 = pylab.plot (x,y2) pylab.title ("Fourier") pylab.xlabel ("frequence") pylab.ylabel ("amplitude") pylab.legend ( ("son", "son + filtre")) m = len (fourier) if m > 256 : m = 256 #x = [ i for i in xrange (0,m) ] pylab.figure (2) x = [ i for i in xrange (0,m) ] y1 = [ abs(fourier[i]) for i in xrange (0,m) ] y2 = [] for i in x : if a <= i <= b : y2.append (450000.0) else : y2.append (0.0) p3 = pylab.plot (x,y1) p4 = pylab.plot (x,y2) pylab.legend ( ("fourrier", "filtre")) pylab.show() def filtre_son_extrait(t,a,b): """calcul de la transformee de Fourier, application du filtre [a,b], recomposition du signal""" fft = FFT.fft (t) global fourier if fourier == None and indice != None : fourier = copy.copy(fft) for i in xrange(0,len(t)): if a <= i <= b: pass else: fft [i] = complex(0,0) tt = FFT.inverse_fft(fft) for i in xrange(0,len(t)): t [i] = int(tt [i].real) def filtre_son(t,a,b,div = 256): """filtre un son par tranche de div frequences, ne garde que les frequences comprises entre a et b""" global indice nb = len (t) / div for i in xrange (0,nb): if i == nb / 2 : indice = i * div ext = t [i * div : (i+1) * div] filtre_son_extrait (ext,a,b) def essai(): print "chargement du son" s = get_sound () print "duree : ", s.get_length (), " secondes" print "musique" play_sound (s) pygame.time.delay (6000) t = array_sound (s) mem = copy.copy(t) print "nombre de donnees ", len (t) print "duree d'une donnee ", s.get_length () * 1000 / len (t), "millisecondes" rep = "" if rep != "n" : #rep = string.split (rep, ",") #a = int (rep [0]) #b = int (rep [1]) a,b = 10,100 print "filtrage [%d,%d]" % (a,b) filtre_son (t,a,b) print "dessin des premiers instants, son filtre" dessine_son (mem,t,fourier,indice, a,b) print "son filtre" s = convert_array (t, s) play_sound (s) pygame.time.delay (6000) essai ()
image de synthèse, base
# coding: cp1252 """définition des objets permettant de construire une image de synthèse""" import math import copy class vecteur (object) : """définit ce qu'est un point""" __slots__ = "x","y","z" def __str__ (self): """pour l'affichage""" return "(%3.2f,%3.2f,%3.2f)" % (self.x, self.y, self.z) def __init__(self,x,y,z): """initialisation""" self.x, self.y, self.z = float (x), float (y), float (z) def __add__ (self,p): """addition de deux points""" return vecteur (self.x + p.x, self.y + p.y, self.z + p.z) def __neg__ (self): """retourne l'opposé d'un vecteur""" return vecteur (-self.x,-self.y,-self.z) def __iadd__ (self,p): """addition de deux points""" self.x += p.x self.y += p.y self.z += p.z return self def __sub__ (self,p): """soustraction de deux points""" return vecteur (self.x - p.x, self.y - p.y, self.z - p.z) def __isub__ (self,p): """soustraction de deux points""" self.x -= p.x self.y -= p.y self.z -= p.z return self def __mul__ (self,x): """multiplication par un scalaire""" return vecteur (self.x * x, self.y * x, self.z * x) def __imul__ (self,x): """multiplication par un scalaire""" self.x *= x self.y *= x self.z *= x return self def __div__ (self,x): """division par un scalaire""" return vecteur (self.x / x, self.y / x, self.z / x) def __idiv__ (self,x): """division par un scalaire""" self.x /= x self.y /= x self.z /= x return self def norme2 (self) : """retourne la norme du vecteur au carrée""" return self.x * self.x + self.y * self.y + self.z * self.z def scalaire (self, v) : """calcule le produit scalaire entre self et v""" return self.x * v.x + self.y * v.y + self.z * v.z def vectoriel (self, v) : """calcule le produit vectoriel entre self et v""" res = vecteur (0,0,0) res.x = self.y * v.z - self.z * v.y res.y = self.z * v.x - self.x * v.z res.z = self.x * v.y - self.y * v.x return res def norme (self) : """retourne la norme du vecteur""" return math.sqrt (self.norme2 ()) def renorme (self) : """renorme ce vecteur""" n = self.norme () if n > 0 : return self / n else : return copy.copy (self) def cosinus (self, v) : """retourne le cosinus de entre le vecteur self et le vecteur r""" sc = self.scalaire (v) n1 = self.norme () n2 = v.norme () n = n1 * n2 if n == 0 : return 0 return float (sc) / float (n) def sinus (self, v, norm) : """retourne le sinus de entre le vecteur self et le vecteur r, norm est un vecteur normal et de norme 1 permettant d'orienter le plan dans lequel se trouve les deux vecteurs dont il faut mesurer le sinus""" sc = self.vectoriel (v) n1 = self.norme () n2 = v.norme () n = n1 * n2 if n == 0 : return 0 return sc.scalaire (norm) / float (n) def angle (self, v, norm) : """retourne l'angle entre les vecteur self et v, retourne un angle compris entre -pi et pi, norm est la direction du vecteur normal au plan des deux vecteurs""" cos = self.cosinus (v) sin = self.sinus (v, norm) angle = math.atan2 (sin, cos) if angle > math.pi : angle -= math.pi * 2 return angle def diff_abs (self, v): """retourne la somme des valeurs absolues des différentes entre coordonnées""" r = abs (self.x - v.x) r += abs (self.y - v.y) r += abs (self.z - v.z) return r def __eq__ (self, v) : """définit l'égalité entre deux vecteurs""" if v == None : return False return self.diff_abs (v) < 1e-10 def __ne__ (self, v) : """définit l'égalité entre deux vecteurs""" if v == None : return True return self.diff_abs (v) > 1e-10 class couleur (vecteur) : """une couleur est un vecteur dont les coordonnées sont comprises entre 0 et 1, x <--> rouge, y <--> vert, z <--> bleu""" def __init__ (self, x,y,z) : vecteur.__init__(self, x,y,z) self.borne () def borne (self) : """si une couleur est hors bornes, réajuste la couleur, prend le maximum devient 1, les autres intensités sont ajustées selon ce facteur d'échelle""" if self.x < 0 : self.x = 0 if self.y < 0 : self.y = 0 if self.z < 0 : self.z = 0 m = max (self.x, self.y) m = max (m, self.z) if m > 1 : self.x /= m self.y /= m self.z /= m def __add__ (self,p): """addition de deux couleurs""" return couleur (self.x + p.x, self.y + p.y, self.z + p.z) def produit_terme (self, v) : """effectue un produit terme à terme""" return couleur (self.x * v.x, self.y * v.y, self.z * v.z) def __mul__ (self,x): """multiplication par un scalaire""" return couleur (self.x * x, self.y * x, self.z * x) class repere (object) : """définition d'un repère orthonormé""" def __init__ (self, origine = vecteur (0,0,0), \ axex = vecteur (1,0,0), \ axey = vecteur (0,1,0), \ axez = vecteur (0,0,1)) : """initialisation, origine et les trois axes""" self.origine = origine self.x = axex self.y = axey self.z = axez def coordonnees (self, v) : """on suppose que les coordonnées de v sont exprimées dans ce repère, calcule les coordonnées de v dans le repère d'origine""" res = copy.copy (self.origine) res.x += v.x * self.x.x + v.y * self.y.x + v.z * self.z.x res.y += v.x * self.x.y + v.y * self.y.y + v.z * self.z.y res.z += v.x * self.x.z + v.y * self.y.z + v.z * self.z.z return res def __str__ (self): """affichage""" s = "origine : " + str (self.origine) + "\n" s += "axe des x : " + str (self.x) + "\n" s += "axe des y : " + str (self.y) + "\n" s += "axe des z : " + str (self.z) + "\n" return s class pixel (object) : """définit ce qu'est un pixel""" __slots__ = "x","y" def __init__(self,x,y): """initialisation""" self.x, self.y = int (x), int (y) def __str__ (self): """pour l'affichage""" return "(%d, %d)" % (self.x, self.y) class rayon (object) : """définit ce qu'est un rayon""" __slots__ = "origine", "direction", "pixel", "couleur" def __init__ (self, origine, direction, pixel, couleur): """initialisation""" self.origine, self.direction, self.pixel, self.couleur = \ origine, direction, pixel, couleur def __str__ (self): """pour l'affichage""" s = "origine : " + str (self.origine) s += " direction : " + str (self.direction) s += " pixel : " + str (self.pixel) s += " couleur : " + str (self.couleur) return s class objet (object): """définit l'interface pour un objet à dessiner dans une image de synthese""" def intersection (self, r) : """retourne le point d'intersection avec le rayon r, retourne None s'il n'y pas d'intersection""" return None def normale (self, p, rayon) : """retourne la normale au point de coordonnée p, et connaissant le rayon""" return None def couleur_point (self, p) : """retourne la couleur au point de coordonnée p""" return None def rayon_refracte (self, rayon, p) : """retourne le rayon réfracté au point p de la surface, si aucune, retourne None""" return None def rayon_reflechi (self, rayon, p) : """retourne le rayon réfléchi au point p de la surface, si aucune, retourne None""" return None def phong_coefficient (self): """retourne un coefficient propre à l'objet pour le modèle d'illumination de Phong""" return float (0) class source (object) : """définition d'une source ponctuelle""" __slots__ = "origine", "couleur" def __init__ (self, origine, couleur): """initialisation""" self.origine, self.couleur = origine, couleur def __str__ (self) : """affichage""" return "source : " + str (self.origine) + " couleur : " + str (self.couleur) if __name__ == "__main__" : v = vecteur (0,1,2) u = vecteur (0,1,2) w = u + v print (u,v,w) print (w * 6) p = pixel (5,5) print (p) c = couleur (1,1,1) print (c) r = rayon (u,w,p,c) print (r) s = source (v, c) print (s)
image de synthèse, sphère
# coding: cp1252 """définition d'une sphère""" import image_synthese_base as base import math class sphere (base.objet): """définit une sphère""" __slots__ = "centre", "rayon", "couleur" def __init__ (self, centre, rayon, couleur): """initialisation""" self.centre, self.rayon, self.couleur = centre, float (rayon), couleur def intersection (self, r) : """retourne le point d'intersection avec le rayon r, retourne None s'il n'y pas d'intersection""" oc = self.centre - r.origine vn = r.direction.norme2 () s = r.direction.scalaire (oc) delta = s*s - vn * (oc.norme2 () - self.rayon * self.rayon) if delta < 0 : return None delta = math.sqrt (delta) l1 = (s - delta) / vn l2 = (s + delta) / vn if 0 < l1 < l2 : l = l1 elif l1 < 0 < l2 : l = l2 elif 0 < l2 < l1 : l = l2 elif l2 < 0 < l1 : l = l1 else : l = None if l == None : return None v = r.origine + r.direction * l return v def normale (self, p, rayon) : """retourne la normale au point de coordonnée p""" v = (p - self.centre) / self.rayon return v def couleur_point (self, p) : """retourne la couleur au point de coordonnée p""" return self.couleur def __str__ (self): """affichage""" s = "sphère --- centre : " + str (self.centre) s += " rayon : " + str (self.rayon) s += " couleur : " + str (self.couleur) return s if __name__ == "__main__" : s = sphere (base.vecteur (0,0,0), 5, base.couleur (0,1,0)) r = base.rayon ( base.vecteur (10,0,0), base.vecteur (1,0,0), \ base.pixel (0,0), base.couleur (0,0,0)) print (s) print (r) p = s.intersection (r) print (p)
image de synthèse, scène
# coding: cp1252 """définition d'une scène""" import image_synthese_base as base import image_synthese_sphere as obj import math import pygame class scene (object): """définit une scène, les axes x,y sont ceux de l'écran, z-1 est la distance à l'écran du point (x,y,z)""" def __init__ (self, repere, alpha, x,y) : """définit la position de l'oeil, l'angle d'ouverture, et la taille de l'écran""" self.repere = repere self.alpha = float (alpha) self.dim = (int (x), int (y)) def ajoute_source (self, source): """ajoute une source ponctuelle de lumière""" if "sources" not in self.__dict__: self.sources = [] self.sources.append (source) def ajoute_objet (self, objet): """ajoute un objet à la scène""" if "objets" not in self.__dict__: self.objets = [] self.objets.append (objet) def __str__ (self) : """affichage""" s = "scène ----------------------------\n" s += "repère : " + str (self.repere) + "\n" s += "angle d'ouverture : " + str (self.alpha) + "\n" s += "dimension de l'écran : " + str (self.dim) + "\n" if "sources" in self.__dict__: for a in self.sources : s += " " +str (a) + "\n" if "objets" in self.__dict__: for a in self.objets : s += " " + str (a) + "\n" return s def intersection (self, rayon) : """calcule le point d'intersection entre un rayon et le plus proche des objets, retourne l'objet et le point d'intersection""" if "objets" not in self.__dict__: return None, None p = rayon.origine sp,so = None, None for o in self.objets : i = o.intersection (rayon) if i == None : continue if rayon.direction.scalaire (i - p) <= 0 : continue if i == rayon.origine : continue if sp == None : sp = i so = o else : v = i - p d = sp - p if v.norme2 () < d.norme2 () : sp = i so = o return so, sp def sources_atteintes (self, p) : """retourne la liste des sources atteintes depuis une position p de l'espace, vérifie qu'aucun objet ne fait obstacle""" res = [] for s in self.sources: r = base.rayon (s.origine, p - s.origine, base.pixel (0,0), s.couleur) o,i = self.intersection (r) if i == None : continue if (i - p).norme2 () < 1e-10 : # possible problème d'arrondi res.append (s) continue return res def construit_rayon (self, pixel) : """construit le rayon correspondant au pixel pixel""" x = (pixel.x - self.dim [0] / 2) * math.tan (self.alpha / 2) / min (self.dim) y = (pixel.y - self.dim [1] / 2) * math.tan (self.alpha / 2) / min (self.dim) v = base.vecteur (x,y,1) r = base.rayon (self.repere.origine, self.repere.coordonnees (v), \ pixel, base.couleur (1,1,1)) return r def modele_illumination (self, rayon, p, obj, source) : """calcule la couleur pour un rayon donné, un point p, un objet obj, et une source de lumière source""" n = obj.normale (p, rayon) cos = n.cosinus (source.origine - p) cl = obj.couleur_point (p) * cos cl = cl.produit_terme (rayon.couleur) return cl def couleur_fond (self) : """retourne la couleur du fond""" return base.couleur (0,0,0) def rayon_couleur (self, rayon, ref = True) : """retourne la couleur d'un rayon connaissant les objets, cette fonction doit être surchargée pour chaque modèle d'illumination, si ref == True, on tient compte des rayons réfracté et réfléchi""" list_rayon = [ rayon ] c = base.couleur (0,0,0) b = False while len (list_rayon) > 0 : r = list_rayon.pop () o,p = self.intersection (r) if p == None : continue if ref : t = o.rayon_refracte (r, p) if t != None : list_rayon.append (t) t = o.rayon_reflechi (r, p) if t != None : list_rayon.append (t) sources = self.sources_atteintes (p) if len (sources) == 0 : return base.couleur (0,0,0) for s in sources : cl = self.modele_illumination (r, p, o, s) c += cl b = True if not b : c = self.couleur_fond () else : c.borne () return c def construit_image (self, screen): """construit l'image de synthèse où screen est un objet du module pygame""" count = 0 nbpixel = int (self.dim [0] * self.dim [1] / 100) for y in range (0, self.dim [1]) : for x in range (0, self.dim [0]) : p = base.pixel (x,y) r = self.construit_rayon (p) c = self.rayon_couleur (r, True) q = (p.x,self.dim [1] - p.y - 1) d = (int (c.x * 255), int (c.y * 255), int (c.z * 255)) pygame.draw.line (screen, d, q,q) count += 1 if count % 150 == 0 : pygame.display.flip () if count % nbpixel == 0 : print ("avancement " , count // nbpixel , "%") pygame.display.flip () def attendre_clic (): """dessine une croix sur l'écran et attend la pression d'un clic de souris""" reste = True while reste: for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONUP : reste = False break if __name__ == "__main__" : s = scene (base.repere (), math.pi / 1.5, 400, 300) s.ajoute_source ( base.source (base.vecteur (0,10,10), \ base.couleur (1,1,1) ) ) s.ajoute_source ( base.source (base.vecteur (10,10,5), \ base.couleur (0.5,0.5,0.5) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,0,12), \ 3, base.couleur (1,0,0) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5) ) ) print (s) screen = pygame.display.set_mode (s.dim) screen.fill ((255,255,255)) s.construit_image (screen) print ("image terminée") attendre_clic ()
image de synthèse, complet
# coding: cp1252 """implémentation du modèle d'illumination de Phong""" import image_synthese_scene as scene import image_synthese_base as base import image_synthese_sphere as obj import math import pygame class scene_phong (scene.scene): """définit une scène et utilise le modèle d'illumination de Phong pour construire l'image de synthèse""" def __init__ (self, repere, alpha, x,y, ka = 0.1, kb = 0.8, kc = 0.3, reflet = 6, fond = base.couleur (200,200,200)) : """définit la position de l'oeil, l'angle d'ouverture, et la taille de l'écran""" scene.scene.__init__ (self, repere, alpha, x, y) self.ka, self.kb, self.kc = ka,kb,kc self.reflet = reflet self.fond = fond self.constante = float (1) def __str__ (self) : """affichage""" s = scene.scene.__str__ (self) s += "ka = %1.3f kb = %1.3f kc = %1.3f\n" % (self.ka,self.kb,self.kc) s += "reflet " + str (self.reflet) + "\n" s += "couleur du fond " + str (self.fond) + "\n" return s def couleur_fond (self) : """retourne la couleur du fond""" return self.fond * self.ka def modele_illumination (self, rayon, p, obj, source) : """calcule la couleur pour un rayon donné, un point p, un objet obj, et une source de lumière source""" n = obj.normale (p, rayon).renorme () vr = rayon.direction.renorme () vr *= float (-1) vs = source.origine - p vs = vs.renorme () bi = vs + vr bi = bi.renorme () # premier terme cos = n.scalaire (vs) couleur = source.couleur.produit_terme (obj.couleur_point (p)) * (cos * self.kb) # second terme : reflet cos = n.scalaire (bi) ** self.reflet couleur += source.couleur.produit_terme (source.couleur) * (cos * self.kc) couleur = couleur.produit_terme (rayon.couleur) return couleur if __name__ == "__main__" : s = scene_phong (base.repere (), math.pi / 1.5, 400, 300) s.ajoute_source ( base.source (base.vecteur (0,10,10), \ base.couleur (1,1,1) ) ) s.ajoute_source ( base.source (base.vecteur (10,10,5), \ base.couleur (0.5,0.5,0.5) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,0,12), \ 3, base.couleur (1,0,0) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5) ) ) print s screen = pygame.display.set_mode (s.dim) screen.fill ((255,255,255)) s.construit_image (screen) print "image terminée" scene.attendre_clic ()
image de synthèse, facette
# coding: cp1252 """définition d'une sphère""" import image_synthese_base as base import image_synthese_sphere as obj import image_synthese_phong as scene import image_synthese_scene as scene_p import pygame import math class facette (base.objet): """définit un triangle dans l'espace""" def __init__ (self, a,b,c, couleur): """initialisation""" self.a, self.b, self.c = a,b,c ab = b - a ac = c - a self.vnorm = ab.vectoriel (ac) self.vnorm = self.vnorm.renorme () self.couleur = couleur def intersection_plan (self, r) : """retourne le point d'intersection entre le plan et le rayon r""" if r.direction.scalaire (self.vnorm) == 0 : return None oa = self.a - r.origine l = self.vnorm.scalaire (oa) / self.vnorm.scalaire (r.direction) p = r.origine + r.direction * l return p def point_interieur (self, p) : """dit si un point appartient à l'intérieur du triangle""" pa = self.a - p pb = self.b - p pc = self.c - p theta = pa.angle (pb, self.vnorm) theta += pb.angle (pc, self.vnorm) theta += pc.angle (pa, self.vnorm) theta = abs (theta) if theta >= math.pi * 0.9 : return True else : return False def intersection (self, r) : """retourne le point d'intersection avec le rayon r, retourne None s'il n'y pas d'intersection""" p = self.intersection_plan (r) if p == None : return None if self.point_interieur (p) : return p else : return None def normale (self, p, rayon) : """retourne la normale au point de coordonnée p et connaissant le rayon""" if rayon.direction.scalaire (self.vnorm) < 0 : return self.vnorm else : return - self.vnorm def couleur_point (self, p) : """retourne la couleur au point de coordonnée p""" return self.couleur def __str__ (self): """affichage""" s = "facette --- a : " + str (self.a) s += " b : " + str (self.b) s += " c : " + str (self.c) s += " couleur : " + str (self.couleur) return s class rectangle (facette): """définit un rectangle dans l'espace""" def __init__ (self, a,b,c,d, couleur): """initialisation, si d == None, d est calculé comme étant le symétrique de b par rapport au milieu du segment [ac]""" facette.__init__(self, a,b,c, couleur) if d != None : self.d = d else : i = (a + c) / 2 self.d = b + (i-b) * 2 def point_interieur (self, p) : """dit si un point appartient à l'intérieur du triangle""" pa = self.a - p pb = self.b - p pc = self.c - p pd = self.d - p theta = pa.angle (pb, self.vnorm) theta += pb.angle (pc, self.vnorm) theta += pc.angle (pd, self.vnorm) theta += pd.angle (pa, self.vnorm) theta = abs (theta) if theta >= math.pi * 0.9 : return True else : return False def __str__ (self): """affichage""" s = "rectangle --- a : " + str (self.a) s += " b : " + str (self.b) s += " c : " + str (self.c) s += " d : " + str (self.d) s += " couleur : " + str (self.couleur) return s if __name__ == "__main__" : s = scene.scene_phong (base.repere (), math.pi / 1.5, 400, 300) s.ajoute_source ( base.source (base.vecteur (0,8,8), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_source ( base.source (base.vecteur (10,0,0), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_source ( base.source (base.vecteur (8,8,4.5), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (1,0,5), \ 1, base.couleur (1,0,0) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5) ) ) s.ajoute_objet (facette ( base.vecteur (0,-2.5,6), \ base.vecteur (-2,-2.5,3), \ base.vecteur (1,-3.5,4.5), \ base.couleur (0.2,0.8,0))) s.ajoute_objet (rectangle ( base.vecteur (0,-2.5,6), \ base.vecteur (-2,-2.5,3), \ base.vecteur (-2,2.8,3.5), \ None, \ base.couleur (0,0,1))) print s screen = pygame.display.set_mode (s.dim) screen.fill ((255,255,255)) s.construit_image (screen) print "image terminée" scene_p.attendre_clic ()
File: file_dattente.tex, line 276
import math import random def generate_expo (mu): x = 0 while x == 0: x = random.random() y = - math.log(1-x) / mu return y
File: file_dattente.tex, line 288
import random def generate_expo (mu): return random.expovariate(mu)
simulation de longévité des ampoules
# coding: cp1252 import math import random def generate_expo (mu): return random.expovariate(mu) S = 10000 iteration = 500 mu = 1.0 / 100 # création d'un tableau de S ampoule qui contient la durée de # vide restante d'une ampoule ampoule = [0 for a in range(0,S)] moyenne_grille = 0 for i in range(0,iteration): grille = 0 mean = 0 for n in range(0,S): mean += ampoule [n] if ampoule[n] == 0: # remplacement d'une ampoule grillée grille += 1 # on détermine la durée de vie de cette ampoule # on arrondit à l'entier le plus proche ampoule [n] = int (generate_expo(mu)) else : # on enlève une heure à la durée de vie de l'ampoule ampoule [n] -= 1 mean /= S if i > 0: moyenne_grille += grille print "itération : ", i, " moyenne durée : ", mean, " grillées :", grille moyenne_grille = float (moyenne_grille) / float (iteration - 1) print "nombre moyen d'ampoules grillées :", moyenne_grille
simulation génétique
import random class Couleur : def __init__ (self, g1,g2) : self.g1 = g1 self.g2 = g2 def couleur (self) : """ deux genes differents : marron, deux genes egaux a marron : marron deux genes egaux a bleu : bleu""" if self.g1 != self.g2 : return "marron" elif self.g1 == "marron" : return "marron" else : return "bleu" def __str__ (self) : return self.couleur () def __add__ (self, autre) : """creation d'un fils, on tire au hasard le premier gene parmi ceux de self, on recommence pour le second gene parmi ceux de autre""" n = random.randint (0,1) if n == 0 : g1 = self.g1 else : g1 = self.g2 n = random.randint (0,1) if n == 0 : g2 = autre.g1 else : g2 = autre.g2 return Couleur (g1,g2) def creation_hasard_couleur (proportion_gene_bleu) : """cree un individu au hasard, proportion_gene_bleu est la proportion du gene bleu""" x = random.random () if x <= proportion_gene_bleu : g1 = "bleu" else : g1 = "marron" x = random.random () if x <= proportion_gene_bleu : g2 = "bleu" else : g2 = "marron" return Couleur (g1,g2) def simulation (proportion_gene_bleu, nb_couleur, nb_iteration) : """effectue une simulation en tenant du nombre d'invidu (nb_couleur), du nombre d'iteration (nb_iteration), de la proportion de gene bleu initiale (proportion_gene_bleu), cette proportion est differente de la proportion de gens aux yeux bleus, proportion_gene_bleu est la probabilite du gene bleu face au gene marron""" l = [ creation_hasard_couleur (proportion_gene_bleu) for i in range (0,nb_couleur) ] # on compte les proportions des couleurs des gens au debut # on utilise un dictionnaire prop_couleur = { "bleu":0 , "marron":0 } for c in l : prop_couleur [ c.couleur () ] += 1 print ("distribution des couleurs d'yeux a la premiere generation ") print (prop_couleur) for it in range (0, nb_iteration) : e = [] for i in range (0, len (l)) : n1 = random.randint (0, len (l)-1) n2 = random.randint (0, len (l)-1) e.append ( l [n1] + l [n2] ) l = e # on compte les proportions des couleurs des gens a la fin # on utilise un dictionnaire prop_couleur_fin = { "bleu":0 , "marron":0 } for c in l : prop_couleur_fin [ c.couleur () ] += 1 print ("\ndistribution des couleurs d'yeux a la derniere generation ") print (prop_couleur_fin) l = [ 0.1 * (i+1) for i in range (0,9) ] for x in l : print ("\nproportion_gene_bleu = ", x) simulation (x,1000,1000) # ce programme effectue une simulation de 1000 iterations pour 1000 individus # pour toutes les proportions de gene bleu [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] # l'objectif est de determiner a partir de quel seuil les gens aux yeux bleus ont une chance # de ne pas disparaitre # # pour chaque seuil, une seule simulation de permet de conclure, il faudrait # faire plusieurs centaines de simulation pour chaque seuil et ne conserver que la moyenne # pour avoir un resultat fiable
calcul de table de mortalité
# colonne 1 : age # colonne 2 : nombre d'hommes en vie a cet age depuis la naissance # colonne 3 : nombre de femmes en vie a cet age depuis la naissance # colonne 4 : nombre de gens en vie a cet age depuis la naissance mortalite = [\ [ 0 , 100000 , 100000 , 100000 ], \ [ 1 , 99571 , 99658 , 99613 ], \ [ 2 , 99537 , 99631 , 99583 ], \ [ 3 , 99514 , 99613 , 99562 ], \ [ 4 , 99495 , 99599 , 99546 ], \ [ 5 , 99479 , 99587 , 99532 ], \ [ 6 , 99465 , 99577 , 99520 ], \ [ 7 , 99453 , 99567 , 99509 ], \ [ 8 , 99442 , 99558 , 99499 ], \ [ 9 , 99433 , 99550 , 99490 ], \ [ 10 , 99422 , 99543 , 99481 ], \ [ 11 , 99411 , 99535 , 99472 ], \ [ 12 , 99400 , 99527 , 99462 ], \ [ 13 , 99387 , 99518 , 99451 ], \ [ 14 , 99371 , 99507 , 99437 ], \ [ 15 , 99350 , 99495 , 99421 ], \ [ 16 , 99320 , 99480 , 99398 ], \ [ 17 , 99280 , 99461 , 99368 ], \ [ 18 , 99227 , 99438 , 99330 ], \ [ 19 , 99157 , 99410 , 99281 ], \ [ 20 , 99076 , 99382 , 99225 ], \ [ 21 , 98989 , 99353 , 99167 ], \ [ 22 , 98899 , 99324 , 99106 ], \ [ 23 , 98808 , 99295 , 99046 ], \ [ 24 , 98718 , 99267 , 98986 ], \ [ 25 , 98632 , 99239 , 98928 ], \ [ 26 , 98545 , 99212 , 98871 ], \ [ 27 , 98455 , 99180 , 98809 ], \ [ 28 , 98367 , 99148 , 98748 ], \ [ 29 , 98279 , 99116 , 98687 ], \ [ 30 , 98187 , 99080 , 98623 ], \ [ 31 , 98085 , 99039 , 98551 ], \ [ 32 , 97979 , 98998 , 98476 ], \ [ 33 , 97871 , 98951 , 98398 ], \ [ 34 , 97756 , 98899 , 98314 ], \ [ 35 , 97633 , 98846 , 98225 ], \ [ 36 , 97500 , 98783 , 98126 ], \ [ 37 , 97355 , 98716 , 98020 ], \ [ 38 , 97201 , 98642 , 97905 ], \ [ 39 , 97033 , 98558 , 97777 ], \ [ 40 , 96849 , 98464 , 97637 ], \ [ 41 , 96645 , 98363 , 97483 ], \ [ 42 , 96427 , 98249 , 97316 ], \ [ 43 , 96186 , 98128 , 97134 ], \ [ 44 , 95912 , 97987 , 96924 ], \ [ 45 , 95606 , 97837 , 96695 ], \ [ 46 , 95272 , 97675 , 96445 ], \ [ 47 , 94901 , 97493 , 96166 ], \ [ 48 , 94483 , 97295 , 95855 ], \ [ 49 , 94024 , 97087 , 95518 ], \ [ 50 , 93532 , 96858 , 95155 ], \ [ 51 , 92993 , 96615 , 94760 ], \ [ 52 , 92428 , 96358 , 94346 ], \ [ 53 , 91835 , 96084 , 93909 ], \ [ 54 , 91201 , 95794 , 93442 ], \ [ 55 , 90533 , 95487 , 92950 ], \ [ 56 , 89824 , 95168 , 92432 ], \ [ 57 , 89070 , 94828 , 91880 ], \ [ 58 , 88266 , 94472 , 91295 ], \ [ 59 , 87407 , 94086 , 90666 ], \ [ 60 , 86496 , 93667 , 89995 ], \ [ 61 , 85546 , 93226 , 89294 ], \ [ 62 , 84556 , 92766 , 88562 ], \ [ 63 , 83504 , 92272 , 87783 ], \ [ 64 , 82388 , 91749 , 86956 ], \ [ 65 , 81202 , 91188 , 86075 ], \ [ 66 , 79938 , 90587 , 85135 ], \ [ 67 , 78599 , 89936 , 84131 ], \ [ 68 , 77184 , 89236 , 83065 ], \ [ 69 , 75653 , 88467 , 81906 ], \ [ 70 , 74012 , 87633 , 80659 ], \ [ 71 , 72245 , 86710 , 79304 ], \ [ 72 , 70350 , 85692 , 77837 ], \ [ 73 , 68317 , 84567 , 76247 ], \ [ 74 , 66155 , 83344 , 74543 ], \ [ 75 , 63859 , 81995 , 72709 ], \ [ 76 , 61404 , 80490 , 70718 ], \ [ 77 , 58802 , 78823 , 68572 ], \ [ 78 , 56060 , 76968 , 66263 ], \ [ 79 , 53165 , 74899 , 63771 ], \ [ 80 , 50171 , 72622 , 61127 ], \ [ 81 , 47013 , 70078 , 58269 ], \ [ 82 , 43733 , 67275 , 55222 ], \ [ 83 , 40329 , 64168 , 51963 ], \ [ 84 , 36830 , 60763 , 48509 ], \ [ 85 , 33321 , 57061 , 44906 ], \ [ 86 , 29785 , 53099 , 41162 ], \ [ 87 , 26244 , 48845 , 37273 ], \ [ 88 , 22775 , 44371 , 33314 ], \ [ 89 , 19407 , 39804 , 29360 ], \ [ 90 , 16252 , 35111 , 25455 ], \ [ 91 , 13351 , 30448 , 21694 ], \ [ 92 , 10752 , 25917 , 18153 ], \ [ 93 , 8489 , 21596 , 14885 ], \ [ 94 , 6563 , 17564 , 11931 ], \ [ 95 , 4919 , 13959 , 9331 ], \ [ 96 , 3588 , 10756 , 7086 ], \ [ 97 , 2562 , 8079 , 5254 ], \ [ 98 , 1791 , 5918 , 3805 ], \ [ 99 , 1254 , 4245 , 2714 ], \ [ 100 , 879 , 3014 , 1921 ], \ [ 101 , 628 , 2110 , 1351 ], \ [ 102 , 467 , 1482 , 962 ], \ [ 103 , 375 , 1056 , 707 ], \ [ 104 , 279 , 752 , 510 ], \ ] def proba_vie_sup (mortalite, age_vie, age_mort) : nb1 = mortalite [age_vie][3] if age_mort < len (mortalite) : nb2 = mortalite [age_mort][3] else : nb2 = 0 return float (nb2) / float (nb1) def proba_mort_egale (mortalite, age_vie, age_mort) : p1 = proba_vie_sup (mortalite, age_vie, age_mort) p2 = proba_vie_sup (mortalite, age_vie, age_mort+1) return p1 - p2 def esperance_vie (mortalite, age_vie) : s = 0.0 w = 0.0 for i in range (age_vie, len (mortalite)) : s += i * proba_mort_egale (mortalite, age_vie, i) w += proba_mort_egale (mortalite, age_vie, i) return s / w - age_vie print proba_vie_sup (mortalite, 20, 40) print esperance_vie (mortalite, 20), esperance_vie (mortalite, 0)
calcul de taux de fécondité
# colonne 1 : age # colonne 2 : nombre d'hommes en vie a cet age depuis la naissance # colonne 3 : nombre de femmes en vie a cet age depuis la naissance # colonne 4 : nombre de gens en vie a cet age depuis la naissance mortalite = [\ [ 0 , 100000 , 100000 , 100000 ], \ [ 1 , 99571 , 99658 , 99613 ], \ [ 2 , 99537 , 99631 , 99583 ], \ [ 3 , 99514 , 99613 , 99562 ], \ [ 4 , 99495 , 99599 , 99546 ], \ [ 5 , 99479 , 99587 , 99532 ], \ [ 6 , 99465 , 99577 , 99520 ], \ [ 7 , 99453 , 99567 , 99509 ], \ [ 8 , 99442 , 99558 , 99499 ], \ [ 9 , 99433 , 99550 , 99490 ], \ [ 10 , 99422 , 99543 , 99481 ], \ [ 11 , 99411 , 99535 , 99472 ], \ [ 12 , 99400 , 99527 , 99462 ], \ [ 13 , 99387 , 99518 , 99451 ], \ [ 14 , 99371 , 99507 , 99437 ], \ [ 15 , 99350 , 99495 , 99421 ], \ [ 16 , 99320 , 99480 , 99398 ], \ [ 17 , 99280 , 99461 , 99368 ], \ [ 18 , 99227 , 99438 , 99330 ], \ [ 19 , 99157 , 99410 , 99281 ], \ [ 20 , 99076 , 99382 , 99225 ], \ [ 21 , 98989 , 99353 , 99167 ], \ [ 22 , 98899 , 99324 , 99106 ], \ [ 23 , 98808 , 99295 , 99046 ], \ [ 24 , 98718 , 99267 , 98986 ], \ [ 25 , 98632 , 99239 , 98928 ], \ [ 26 , 98545 , 99212 , 98871 ], \ [ 27 , 98455 , 99180 , 98809 ], \ [ 28 , 98367 , 99148 , 98748 ], \ [ 29 , 98279 , 99116 , 98687 ], \ [ 30 , 98187 , 99080 , 98623 ], \ [ 31 , 98085 , 99039 , 98551 ], \ [ 32 , 97979 , 98998 , 98476 ], \ [ 33 , 97871 , 98951 , 98398 ], \ [ 34 , 97756 , 98899 , 98314 ], \ [ 35 , 97633 , 98846 , 98225 ], \ [ 36 , 97500 , 98783 , 98126 ], \ [ 37 , 97355 , 98716 , 98020 ], \ [ 38 , 97201 , 98642 , 97905 ], \ [ 39 , 97033 , 98558 , 97777 ], \ [ 40 , 96849 , 98464 , 97637 ], \ [ 41 , 96645 , 98363 , 97483 ], \ [ 42 , 96427 , 98249 , 97316 ], \ [ 43 , 96186 , 98128 , 97134 ], \ [ 44 , 95912 , 97987 , 96924 ], \ [ 45 , 95606 , 97837 , 96695 ], \ [ 46 , 95272 , 97675 , 96445 ], \ [ 47 , 94901 , 97493 , 96166 ], \ [ 48 , 94483 , 97295 , 95855 ], \ [ 49 , 94024 , 97087 , 95518 ], \ [ 50 , 93532 , 96858 , 95155 ], \ [ 51 , 92993 , 96615 , 94760 ], \ [ 52 , 92428 , 96358 , 94346 ], \ [ 53 , 91835 , 96084 , 93909 ], \ [ 54 , 91201 , 95794 , 93442 ], \ [ 55 , 90533 , 95487 , 92950 ], \ [ 56 , 89824 , 95168 , 92432 ], \ [ 57 , 89070 , 94828 , 91880 ], \ [ 58 , 88266 , 94472 , 91295 ], \ [ 59 , 87407 , 94086 , 90666 ], \ [ 60 , 86496 , 93667 , 89995 ], \ [ 61 , 85546 , 93226 , 89294 ], \ [ 62 , 84556 , 92766 , 88562 ], \ [ 63 , 83504 , 92272 , 87783 ], \ [ 64 , 82388 , 91749 , 86956 ], \ [ 65 , 81202 , 91188 , 86075 ], \ [ 66 , 79938 , 90587 , 85135 ], \ [ 67 , 78599 , 89936 , 84131 ], \ [ 68 , 77184 , 89236 , 83065 ], \ [ 69 , 75653 , 88467 , 81906 ], \ [ 70 , 74012 , 87633 , 80659 ], \ [ 71 , 72245 , 86710 , 79304 ], \ [ 72 , 70350 , 85692 , 77837 ], \ [ 73 , 68317 , 84567 , 76247 ], \ [ 74 , 66155 , 83344 , 74543 ], \ [ 75 , 63859 , 81995 , 72709 ], \ [ 76 , 61404 , 80490 , 70718 ], \ [ 77 , 58802 , 78823 , 68572 ], \ [ 78 , 56060 , 76968 , 66263 ], \ [ 79 , 53165 , 74899 , 63771 ], \ [ 80 , 50171 , 72622 , 61127 ], \ [ 81 , 47013 , 70078 , 58269 ], \ [ 82 , 43733 , 67275 , 55222 ], \ [ 83 , 40329 , 64168 , 51963 ], \ [ 84 , 36830 , 60763 , 48509 ], \ [ 85 , 33321 , 57061 , 44906 ], \ [ 86 , 29785 , 53099 , 41162 ], \ [ 87 , 26244 , 48845 , 37273 ], \ [ 88 , 22775 , 44371 , 33314 ], \ [ 89 , 19407 , 39804 , 29360 ], \ [ 90 , 16252 , 35111 , 25455 ], \ [ 91 , 13351 , 30448 , 21694 ], \ [ 92 , 10752 , 25917 , 18153 ], \ [ 93 , 8489 , 21596 , 14885 ], \ [ 94 , 6563 , 17564 , 11931 ], \ [ 95 , 4919 , 13959 , 9331 ], \ [ 96 , 3588 , 10756 , 7086 ], \ [ 97 , 2562 , 8079 , 5254 ], \ [ 98 , 1791 , 5918 , 3805 ], \ [ 99 , 1254 , 4245 , 2714 ], \ [ 100 , 879 , 3014 , 1921 ], \ [ 101 , 628 , 2110 , 1351 ], \ [ 102 , 467 , 1482 , 962 ], \ [ 103 , 375 , 1056 , 707 ], \ [ 104 , 279 , 752 , 510 ], \ ] class Population : def __init__ (self, mortalite) : self.mortalite = mortalite def proba_vie_sup (self, age_vie, age_mort) : nb1 = self.mortalite [age_vie][3] if age_mort < len (mortalite) : nb2 = self.mortalite [age_mort][3] else : nb2 = 0 return float (nb2) / float (nb1) def proba_mortalite_sexuee (self, age_vie, age_mort, indice) : nb1 = self.mortalite [age_vie][indice] if age_mort < len (mortalite) : nb2 = self.mortalite [age_mort][indice] else : nb2 = 0 return 1.0 - float (nb2) / float (nb1) def proba_mort_egale (self, age_vie, age_mort) : p1 = self.proba_vie_sup (age_vie, age_mort) p2 = self.proba_vie_sup (age_vie, age_mort+1) return p1 - p2 def esperance_vie (self, age_vie) : s = 0.0 w = 0.0 for i in range (age_vie, len (mortalite)) : s += i * self.proba_mort_egale (age_vie, i) w += self.proba_mort_egale (age_vie, i) if w == 0 : return 0.0 else : return s / w - age_vie def proportion_femme (self, age_vie) : d1 = self.mortalite [age_vie][3] - self.mortalite [age_vie][1] d2 = self.mortalite [age_vie][2] - self.mortalite [age_vie][1] if d1 == 0 and d2 == 0 : return 0.5 else : return float (d1) / float (d2) def annee_viager (self, i, j) : return self.esperance_vie (i) - self.esperance_vie (j) def proportion_femme_tout (self) : p1f = self.proportion_femme (1) p1h = 1.0 - p1f m1f = self.proba_mortalite_sexuee (0, 1, 1) m1h = self.proba_mortalite_sexuee (0, 1, 2) cf = 1.0 / (1.0 - m1f) ch = 1.0 / (1.0 - m1h) return p1f * cf / ( p1f * cf + p1h * ch ) class PopulationPlus (Population) : def proba_mort_egale (self, age_vie, age_mort) : if age_mort > 0 : return Population.proba_mort_egale (self, age_vie, age_mort) else : p1 = self.proba_vie_sup (age_vie, age_mort) p2 = 1.0 - (1.0 - self.proba_vie_sup (age_vie, age_mort+1)) / 2 return p1 - p2 class Simulation (Population) : def __init__ (self, popu, fecondite = 0.2, age1 = 25, age2 = 34) : Population.__init__ (self, popu) self.fecondite = fecondite self.age1 = age1 self.age2 = age2 def prepare (self) : p = self.proportion_femme_tout () self.sim = [ [ t [1] * p, t [2] * (1.0 - p) ] for t in self.mortalite ] def proportion_bebe_fille (self) : p1 = self.proportion_femme_tout () #p2 = self.proportion_femme (1) return p1 # approximation def bebe (self) : b = 0 for a in range (self.age1, self.age2 + 1) : b += self.sim [a][0] * self.fecondite p = self.proportion_bebe_fille () return int (b * p), int (b * (1.0 - p)) def iteration (self) : for i in range (len (self.sim)-1, 0, -1) : # boucle a l'envers self.sim [i][0] = self.sim [i-1][0] * (1.0 - self.proba_mortalite_sexuee (i-1, i, 1)) self.sim [i][1] = self.sim [i-1][1] * (1.0 - self.proba_mortalite_sexuee (i-1, i, 2)) f,g = self.bebe () self.sim [0][0] = f self.sim [0][1] = g def simulation (self, nb) : self.prepare () for i in range (0, nb) : self.iteration () return self.sim def nb (self, sim) : f,g = 0,0 for i in sim : f += i [0] g += i [1] return int (f), int (g) p = Population (mortalite) print p.proba_vie_sup (20, 40) print p.esperance_vie (20), p.esperance_vie (0) for i in range (0, 5) : print p.proportion_femme (i) print "--------------------" pp = PopulationPlus (mortalite) print pp.esperance_vie (20), pp.esperance_vie (0) print pp.proportion_femme_tout () for x in range (0, 200) : fecondite = 0.2 + x * 0.0001 s = Simulation (mortalite, fecondite = fecondite) r = s.simulation (0) z = s.nb (r) r = s.simulation (100) print "fecondite = ", fecondite, " population H,F ", s.nb (r), " initiale ", z
goûts en commun
import random def genere_fichier_exemple (nom) : """cette fonction cree un fichier d'exemple contenant des prenoms et des reponses, le format est le suivant : prenom, espace, liste des reponses mise bout a bout, passage a la ligne""" prenom = [ "jean", "cecile", "juliette", "daniel", "julie", \ "gerard", "amelie", "charles", "alix", "frederic", \ "claire", "richard" ] f = open (nom, "w") for p in prenom : f.write (p) f.write (" ") for i in range (0,20) : a = random.randint (0,5) + 1 f.write (str (a)) f.write ("\n") f.close () class Personne : """on definit une personne""" def __init__ (self, prenom, reponse) : self.prenom = prenom self.reponse = reponse self.commun = 0 # compte le nombre de points communs def __cmp__ (self, autre) : """operateur de comparaison, reponse a la question 5""" if self.commun == autre.commun : return 0 if self.commun < autre.commun : return -1 return 1 def __str__ (self) : """pour l'affichage""" s = self.prenom + "\t" + str (self.commun) return s def point_commun (self, autre) : """calcul le nombre de points commun entre deux personnes""" s = 0 for i in range (0, len (self.reponse)) : if self.reponse [i] == autre.reponse [i] : s += 1 return s def lit_reponse (nom) : """on relie le fichier ecrit avec la fonction precedente""" f = open (nom, "r") line = f.readlines () f.close () rep = [] for l in line : s = l.replace ("\n", "") # on enleve les fins de ligne spl = s.split () # on coupe la ligne en deux, les deux morceaux # separes par des espaces rep.append ( Personne ( spl [0], spl [1] )) return rep def point_commun (n, rep) : """calcule le nombre de points communs entre rep [n] et rep [i], stocke le resultat dans rep [i].commun""" for r in rep : d = r.point_commun (rep [n]) r.commun = d ########################################################### # debut du programme ########################################################### # creation du fichier genere_fichier_exemple ("reponses.txt") # relecture du fichier rep = lit_reponse ("reponses.txt") # calcule les points communs point_commun (0, rep) # on les trie par ordre croissant rep.sort () print "le ou la plus proche ", rep [len (rep)-1] print "le ou la plus loin ", rep [0] # liste complete for r in rep : print r
File: histogramme_cor.tex, line 7
# coding: cp1252 import random import math n = 10000 hn = dict () for i in xrange (1,n): x = random.gauss (0,1) xx = round (x, 1) if xx not in hn: # si h [xx] n'existe pas encore hn [xx] = 0 hn [xx] += 1 # affichage de l'histogramme for w in hn: print w, " \t", float (hn [w]) / float (n)
File: histogramme_cor.tex, line 45
# coding: cp1252 import random import math n = 10000 hb = dict () k = 400 for i in xrange (1,n): if (i % 500 == 0) : # comme le programme est assez lent, print i # cela permet de suivre l'avancement s = 0 for j in xrange (1,k): a = random.randint (0,1) s += a x = float (s - k/2) / math.sqrt (float (k * 0.25)) xx = round (x, 1) if xx not in hb: hb [xx] = 0 hb [xx] += 1 # affichage de l'histogramme for w in hb: print w, " \t", float (hb [w]) / float (n)
File: histogramme_cor.tex, line 111
x = hn.keys () x.sort () y = [ hn [a] for a in x ] import IaGraph.plot IaGraph.plot(x, y) import Tkinter Tkinter.mainloop ()
File: histogramme_cor.tex, line 135
from scipy import gplt x1 = hn.keys () x1.sort () y = [ hn [a] for a in x1 ] x2 = hb.keys () x2.sort () z = [ hb [a] for a in x2 ] gplt.plot (x1,y,x2,z)
File: histogramme_cor.tex, line 159
x1 = hn.keys () x1.sort () y = [ hn [a] for a in x1 ] x2 = hb.keys () x2.sort () z = [ hb [a] for a in x2 ] import biggles p = biggles.FramedPlot() p.title = "Histogramme" p.xlabel = "x" p.ylabel = "y" p.add( biggles.Curve(x1, y, color="red") ) p.add( biggles.Curve(x2, z, color="blue") ) p.show()
histogramme
# coding: cp1252 import random import math n = 10000 hn = dict () for i in xrange (1,n): x = random.gauss (0,1) xx = round (x, 1) if xx not in hn: # si h [xx] n'existe pas encore hn [xx] = 0 hn [xx] += 1 # affichage de l'histogramme for w in hn: print w, " \t", float (hn [w]) / float (n) n = 10000 hb = dict () k = 400 for i in xrange (1,n): if (i % 500 == 0) : # comme le programme est assez lent, print i # cela permet de suivre l'avancement s = 0 for j in xrange (1,k): a = random.randint (0,1) s += a x = float (s - k/2) / math.sqrt (float (k * 0.25)) xx = round (x, 1) if xx not in hb: hb [xx] = 0 hb [xx] += 1 # affichage de l'histogramme for w in hb: print w, " \t", float (hb [w]) / float (n) x1 = hn.keys () x1.sort () y = [ hn [a] for a in x1 ] x2 = hb.keys () x2.sort () z = [ hb [a] for a in x2 ] import biggles p = biggles.FramedPlot() p.title = "Histogramme" p.xlabel = "x" p.ylabel = "y" p.add( biggles.Curve(x1, y, color="red") ) p.add( biggles.Curve(x2, z, color="blue") ) p.show()
écrire un rapport au format HTML
# coding: cp1252 import os import os.path import PIL.Image class html_file (object) : """cette classe propose quelques méthodes pour écrire un fichier HTML simplement""" header = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> </HEAD> <BODY >""" foot = """</BODY> </HTML> """ def __init__ (self, file) : """construction d'un fichier HTML""" self.file = file def open (self) : """ouverture du fichier""" self.f = open (self.file, "w") self.f.write (self.header) def close (self) : """fermeture du fichier""" self.f.close () def text (self, s) : """écrit du texte dans un fichier HTML""" s = s.replace ("\n", "<BR>") self.f.write (s) def text_line (self) : """passe une ligne dans un fichier HTML""" self.f.write ("<BR>") def table_begin (self, nc) : """commence une table, nc est le nombre de colonnes""" self.f.write ("""<TABLE cellSpaceing="1" """) self.f.write ("""cellPadding="1" border="1">\n <TR>\n <TD>""") def table_end (self) : """termine une table""" self.f.write (""" </TD>\n </TR>\n</TABLE>\n""") def table_next (self) : """passe à la colonne suivante""" self.f.write (""" </TD>\n <TD>""") def table_next_line (self) : """passe à la ligne suivante""" self.f.write (""" </TD>\n </TR>\n <TR>\n <TD>""") def relative_path (self, url) : """trouve le chemin relatif par rapport au fichier""" pr = os.path.commonprefix ( [ self.file, url ] ) if pr != None : d = os.path.dirname (self.file) if pr.count (d) == 1 : pr = d + "\\" url = url [ len (pr) : len (url) ] return url def clean_url (self, url) : """enlève les espaces et redresse les barres""" url = url.replace (" ", "\%20") url = url.replace ("\\", "/") return url def add_link (self, url, caption, isfile) : """ajoute un lien dans le fichier html, url est l'adresse, caption est l'intitulé du lien, si isfile vaut True, cherche un chemin relatif par rapport à self.file""" if isfile : url = self.relative_path (url) url = self.clean_url (url) s = """<A HREF="%s">%s</A>""" % (url, caption) self.f.write (s) def add_image (self, image, size = None, zoom = None) : """ajoute une image dans le fichier html, celle-ci est enregistrée avec un numéro, offre la possibilité de zoomer ou de modifier la taille""" if not self.__dict__.has_key ("num_image") : self.num_image = 0 name, ext = os.path.splitext (self.file) name = name + str (self.num_image) + ".png" image.save (name) self.add_image_link (name, size, zoom) self.num_image += 1 def add_image_link (self, url, size = None, zoom = None) : """ajoute une image dans le fichier html, cette image n'est pas recopiée, il est possible de spécifier une taille, ou de multiplier cette taille""" if size == None : im = PIL.Image.open (url) size = im.size if zoom != None : size = (int (size [0] * zoom), int (size [1] * zoom)) url = self.relative_path (url) url = self.clean_url (url) s = """<IMG width=%d height=%d border=0 SRC="%s" alt="%s">""" \ % (size [0], size [1], url, url) self.f.write (s) if __name__ == "__main__" : print "écriture du fichier ",file file = "c:\\temp\\essai.html" html = html_file (file) html.open () html.text ("""première ligne d'un fichier HTML, seconde ligne""") html.table_begin (2) html.text ("1") html.table_next () html.text ("2") html.table_next_line () html.text("3") html.table_next () html.text ("4") html.table_end () html.add_link ("c:\\temp\\cours.py", "cours.py", True) html.text_line () im = PIL.Image.new ("RGB", (100,100), color = (100,100,100)) html.add_image (im) html.add_image (im, zoom = 2) html.close () print "fin"
récupération de chiffre de la base MNIST
# coding: cp1252 """décomposition de la base d'image MNIST""" import os import struct import PIL # ligne à supprimer si on n'a pas besoin des images import PIL.Image as PIM # ligne à supprimer si on n'a pas besoin des images def transcription_entier (str) : """convertit un entier lu en format binaire en entier""" t = struct.unpack ("BBBB", str) i = t [3] + t [2] * 256 + t [1] * 256 * 256 + t [0] * 256 * 256 * 256 return i def lire_image (fim, nl, nc) : """lit une image dans le fichier fim, cette image a nl lignes et nc colonnes, retourne l'image sous la forme d'un t-uple""" nb = nl * nc str = fim.read (nb) t = struct.unpack ("B" * nb, str) return t def lire_image (fim, nl, nc) : """lit une image dans le fichier fim, cette image a nl lignes et nc colonnes, retourne l'image sous la forme d'un t-uple""" nb = nl * nc str = fim.read (nb) t = struct.unpack ("B" * nb, str) return t def lire_label (fla) : """lit un label (un chiffre) dans le fichier fla, retourne un entier""" str = fla.read (1) t = struct.unpack ("B", str) return t [0] def binarisation (image, binar) : """binarisation d'une image""" res = [] for i in image : if i < 255 - binar : res.append (255) else : res.append (0) return res def write_image_matlab (fmat, image) : """écrit une image au format matlab, chaque nombre indique la position du prochain pixel noir, la suite est aussi longue qu'il y a de pixels dans l'image et se termine par une suite de 0 qui indique qu'il n'y a plus de pixels noirs""" nb = 0 for i in xrange (0, len(image)) : if image [i] == 0 : fmat.write ("," + str (i+1)) nb += 1 for i in xrange (0, len (image) - nb) : fmat.write (",0") def decompose_mnist (file_image, file_label, file_matlab, binar, \ nbcl = -1, dir_image1 = None, dir_image2 = None) : """décompose la base MNIST en un format utilisable sous MATLAB, commence par [, termine par ], chaque ligne est composée comme suit : premier nombre = classe, voir fonction write_image_matlab ;, nbcl est le nombre d'images à extraire par classe, si nbcl == -1, traite toute la base, binar est le seuil de binarisation, voir fonction binarisation, si dir_image1 != None, les images des nombres sont écrites, si dir_image2 != None, on continue d'explorer le fichier des images mais les images des nombres sont écrites dans le répertoire dir_image2""" fim = open (file_image, "rb") fla = open (file_label, "rb") s = fla.read (4) # , (Hal_byte*) &umagic_an) ; magic_an = transcription_entier (s) s = fla.read (4) # , (Hal_byte*) &unb_an) ; nb_an = transcription_entier (s) s = fim.read (4) # , (Hal_byte*) &umagic_im) ; magic_im = transcription_entier (s) s = fim.read (4) # , (Hal_byte*) &unb_im) ; nb_im = transcription_entier (s) s = fim.read (4) #, (Hal_byte*) &unl_im) ; nl_im = transcription_entier (s) s = fim.read (4) #, (Hal_byte*) &unc_im) ; nc_im = transcription_entier (s) if nbcl == -1 : nbcl = nb_im print "nombre de labels ", nb_an print "nombre magique label , vérification (2049) ", magic_an print "nombre d'images ", nb_im print "nombre magique image, vérification (2051) ", magic_im print "nombre de lignes ", nl_im print "nombre de colonnes ", nc_im if file_matlab != None : fmat = open (file_matlab, "wt") fmat.write ("[") label_count = { } nb = 0 cent = int (nb_im / 100) while nb < nb_im : if nb % cent == 0 : print "avancement ", nb / cent, " %" nb += 1 image = lire_image (fim, nl_im, nc_im) label = lire_label (fla) image = binarisation (image, binar) if not label_count.has_key (label) : label_count [label] = 0 if 0 <= label_count [label] < nbcl : dir_image = dir_image1 elif nbcl <= label_count [label] < nbcl * 2 : dir_image = dir_image2 else : dir_image = None continue if file_matlab != None : fmat.write (str (label)) write_image_matlab (fmat, image) fmat.write (";\n") if dir_image != None : nom = "image_%d_%5d" % (label, label_count [label] % nbcl) nom = dir_image + "\\" + nom + ".tif" surf = PIM.new ("RGB", (nc_im, nl_im) ) for i in xrange (0, len (image)) : x,y = i % nc_im, i // nc_im c = image [i] surf.putpixel ((x,y), (c,c,c)) surf.save (nom) label_count [label] += 1 if file_matlab != None : fmat.write ("]") fmat.close () fim.close () fla.close () key = label_count.keys () key.sort () for i in key : print "label ", i , " \t : ", label_count [i] return label_count if __name__ == "__main__" : file_image = "C:\\Downloads\\data_image\\mnist\\t10k-images.idx3-ubyte" file_label = "C:\\Downloads\\data_image\\mnist\\t10k-labels.idx1-ubyte" file_matlab = "c:\\temp\\mnist2\\matlab.txt" dir_image = None # "c:\\temp\\mnist2" nb = 20 binar = 190 decompose_mnist (file_image, file_label, file_matlab, \ binar, nb, dir_image1, dir_image2)
plus proches voisins
# coding: cp1252 import math import random class nuage_points (object) : """définit une classe de nuage de points""" def __init__ (self) : """constructeur""" self.nb = 0 # aucun élément self.nuage = [] # aucun élément def __iter__(self) : """retourne un itérateur sur l'ensemble de points""" return self.nuage.__iter__ () def __len__ (self) : """retourne le nombre d'élément""" return len (self.nuage) def distance (self, obj1, obj2) : """retourne une distance entre deux éléments obj1 et obj2""" return 0 def label (self, obj) : """retourne le label d'un objet""" return None def ppv (self, obj) : """retourne l'élément le plus proche de obj et sa distance avec obj""" mn = None dm = None for l in self.nuage : d = self.distance (l, obj) if dm == None or d < dm : dm = d mn = l return mn,dm def ppv_nuage (self, nuage, bienclasse = None, erreur = None) : """calcule un taux de classification pour un nuage, utilise la fonction ppv pour chaque élément de nuage, retourne le nombre d'élément bien classés, et mal classés, si bienclasse est une liste vide (!= None), cette liste contiendra la liste des couples d'éléments (x,y) in (nuage, self) pour lesquels la classification est bonne, si erreur est une liste vide (!= None), cette liste contiendra la liste des couples d'éléments (x,y) in (nuage,self) pour lesquels la classification est mauvaise""" disp = len (nuage) / 10 ; good = 0 bad = 0 n = 0 for x in nuage : obj,d = self.ppv (x) if self.label (obj) == self.label (x) : good += 1 if bienclasse != None : bienclasse.append ((obj,x)) else : bad += 1 if erreur != None : erreur.append ((obj, x)) if n % disp == 0 : print "ppv_nuage ", n * 100 / len (nuage), "%" n += 1 return good, bad
plus proches voisins sur des images
# coding: cp1252 import os import os.path import mnist import string import PIL import PIL.Image import html_file as html import psyco import random import kppv import time # définit une classe héritant de kppv.nuage_points qui surcharge les # fonctions distance et label class nuage_point_distance_label (kppv.nuage_points) : """hérite de kppv.nuage_point et surcharge les méthodes : - distance - label """ def distance (self, obj1, obj2) : """surcharge de la fonction distance, comme les images sont toutes de dimensions identiques, on peut compter les pixels de couleurs différentes, le résultat est la distance entre deux images""" if len (obj1) != len (obj2) : print "erreur, len (obj1) != len (obj2)" d = 0 for i in xrange (2, len (obj1)) : if obj1 [i] != obj2 [i] : d += 1 return d def label (self, obj) : """retourne le label d'un objet""" return obj [0] class nuage_image (object) : """nuage de points, chaque élément est une image, les images sont en noir et blanc, liste de 0 ou 1""" def __init__ (self, nuage_ppv, rep, nb, extension = "tif") : """initialise le nuage d'images avec un répertoire qui est l'emplacement des images pour ce nuage, le nom des images contient une chaîne de caractères suivi d'un label séparés par un blanc soulignés, extension est le type de images à charger, on ne considère que les nb premières images, nuage est une instance de la classe nuage_point ou nuage_point_laesa""" def binarise (p) : if p [0] == 0 : return 1 else : return 0 self.nb = 0 self.nuage = [] file = os.listdir (rep) nb = min (nb, len (file)) step = nb / 10 n = 0 for f in file : if n >= nb : break if n % step == 0 : print "nuage_image, avancement ", n * 100 / nb, "%" n += 1 ext = os.path.splitext (f) ext = ext [len (ext) - 1].lower () ext = ext [1 : len (ext)] if ext != "tif" : continue s = f.split ("_") label = s [1] im = PIL.Image.open (rep + "\\" + f) size = im.size data = [ binarise (im.getpixel ((x,y))) for y in xrange (0, size [1]) \ for x in xrange (0, size [0]) ] data.insert (0, size) data.insert (0, label) self.nuage.append ( tuple (data)) self.ppv = nuage_ppv self.ppv.nb = self.nb self.ppv.nuage = self.nuage def image (self, obj) : """reconstruit une image à partir d'un élément""" size = obj [1] im = PIL.Image.new ("RGB", size) nb = len (obj) - 2 for i in xrange (0, nb) : if obj [i] == 0 : im.putpixel ( (i % size [0], i // size [1]), (255,255,255)) else : im.putpixel ((i % size [0], i // size [1]), (0,0,0)) return im def html_couple (self, fichier, l, zoom = None) : """écrit un fichier html contenant toutes les images mal classées, à partir de la liste erreur construite par la méthode nuage_points.ppv_nuage""" # nombre de colonnes maximales maxc = 0 for x in l : maxc = max (maxc, len (x)) f = html.html_file (fichier) f.open () f.table_begin (maxc*2+1) f.text ("indice") f.table_next () f.text ("label") f.table_next () f.text ("à classer") f.table_next () for n in xrange (1, maxc) : f.text ("label") f.table_next () f.text ("voisin " + str (n)) f.table_next () f.table_next_line () n = 0 for x in l : f.text (str (n)) f.table_next () n += 1 for el in x : im = self.image (el) f.text (self.ppv.label (el)) f.table_next () f.add_image (im, zoom = zoom) f.table_next () f.table_next_line () f.table_end () f.close () def ppv_nuage (self, nuage, bienclasse = None, erreur = None) : """appelle self.nuage.ppv_nuage""" return self.ppv.ppv_nuage (nuage, bienclasse, erreur) def __len__ (self) : """retourne len (self.nuage)""" return len (self.ppv) def __iter__(self) : """retourne iter (self.nuage)""" return iter (self.ppv) if __name__ == "__main__" : psyco.full () rep_app = "c:\\temp\\mnist\\app" rep_test = "c:\\temp\\mnist\\test" nb_app = 400 nb_test = 400 html_file1 = "c:\\temp\\mnist\\bienclasse.html" html_file2 = "c:\\temp\\mnist\\erreur.html" # si les images n'existent pas if not os.path.exists (rep_app) or not os.path.exists (rep_test) : file_image = "C:\\Downloads\\data_image\\mnist\\t10k-images.idx3-ubyte" file_label = "C:\\Downloads\\data_image\\mnist\\t10k-labels.idx1-ubyte" os.makedirs (rep_app) os.makedirs (rep_test) binar = 220 nbcl = 40 mnist.decompose_mnist (file_image, file_label, None, binar, nbcl, \ rep_app, rep_test) ppv1 = nuage_point_distance_label () ppv2 = nuage_point_distance_label () print "construction du nuage d'apprentissage" nuage_app = nuage_image (ppv1, rep_app, nb_app) print "nombre de points : ", len (nuage_app) print "construction du nuage de test" nuage_test = nuage_image (ppv2, rep_test, nb_test) print "nombre de points : ", len (nuage_test) print "résultat de la classification" erreur = [] bienclasse = [] temps1 = time.clock () good,bad = nuage_app.ppv_nuage (nuage_test, bienclasse, erreur) temps2 = time.clock () print "---------------------------------------------------------------------------" print "temps de traitement en secondes ", temps2 - temps1 print "good, bad = ", good, bad print "taux de classification : ", float (good) / (good + bad) print "écriture du fichier ", html_file1 nuage_app.html_couple (html_file1, bienclasse, zoom = 4) print "écriture du fichier ", html_file2 nuage_app.html_couple (html_file2, erreur, zoom = 4)
plus proches voisins LAESA
# coding: cp1252 import math import random import kppv class nuage_point_laesa (kppv.nuage_points) : """implémente l'algorithme des plus proches voisins, version LAESA""" def __init__ (self) : """construit la classe""" kppv.nuage_points.__init__ (self) def selection_pivots (self,nb) : """sélectionne nb pivots aléatoirements""" nb = min (nb, len (self.nuage)) self.pivots = [] while len (self.pivots) < nb : i = random.randint (0,len (self.nuage)) if not self.nuage [i] in self.pivots : self.pivots.append (self.nuage [i]) # on calcule aussi la distance de chaque éléments au pivots self.dist = [] for el in self.nuage : dl = [] for p in self.pivots : d = self.distance (el, p) dl.append (d) self.dist.append (dl) def ppv (self, obj) : """retourne l'élément le plus proche de obj et sa distance avec obj, utilise la sélection à l'aide pivots""" # initialisation dp = [ self.distance (obj, p) for p in self.pivots ] # pivots le plus proche dm = dp [0] im = self.pivots [0] for i in xrange (0, len(self.pivots)) : d = dp [i] if d < dm : dm = d im = self.pivots [i] # améliorations for i in xrange (0, len (self.nuage)) : # on regarde si un pivots permet d'éliminer l'élément i calcul = True for j in xrange (0, len (self.pivots)) : d = abs (dp [j] - self.dist[i][j]) if d > dm : calcul = False break # dans le cas contraire on calcule la distance if calcul : d = self.distance (obj, self.nuage [i]) if d < dm : dm = d im = self.nuage [i] return im,dm
plus proches voisins LAESA sur des images
# coding: cp1252 import os import os.path import mnist import string import PIL import PIL.Image import html_file as html import psyco import random import kppv_laesa import time import kppv_image # définit une classe héritant de kppv.nuage_points qui surcharge les # fonctions distance et label class nuage_point_leasa_distance_label (kppv_laesa.nuage_point_laesa) : """hérite de kppv.nuage_point et surcharge les méthodes : - distance - label """ def distance (self, obj1, obj2) : """surcharge de la fonction distance, comme les images sont toutes de dimensions identiques, on peut compter les pixels de couleurs différentes, le résultat est la distance entre deux images""" if len (obj1) != len (obj2) : print "erreur, len (obj1) != len (obj2)" d = 0 for i in xrange (2, len (obj1)) : if obj1 [i] != obj2 [i] : d += 1 return d def label (self, obj) : """retourne le label d'un objet""" return obj [0] class nuage_image_leasa (kppv_image.nuage_image) : """nuage de points, chaque élément est une image, les images sont en noir et blanc, liste de 0 ou 1""" def __init__ (self, nuage_ppv, rep, nb, extension = "tif") : """initialise le nuage d'images avec un répertoire qui est l'emplacement des images pour ce nuage, le nom des images contient une chaîne de caractères suivi d'un label séparés par un blanc soulignés, extension est le type de images à charger, on ne considère que les nb premières images, nuage est une instance de la classe nuage_point ou nuage_point_laesa""" kppv_image.nuage_image.__init__(self, nuage_ppv, rep, nb, extension) self.ppv.selection_pivots (20) if __name__ == "__main__" : psyco.full () rep_app = "c:\\temp\\mnist\\app" rep_test = "c:\\temp\\mnist\\test" nb_app = 400 nb_test = 400 html_file1 = "c:\\temp\\mnist\\bienclasse.html" html_file2 = "c:\\temp\\mnist\\erreur.html" # si les images n'existent pas if not os.path.exists (rep_app) or not os.path.exists (rep_test) : file_image = "C:\\Downloads\\data_image\\mnist\\t10k-images.idx3-ubyte" file_label = "C:\\Downloads\\data_image\\mnist\\t10k-labels.idx1-ubyte" os.makedirs (rep_app) os.makedirs (rep_test) binar = 220 nbcl = 40 mnist.decompose_mnist (file_image, file_label, None, binar, nbcl, \ rep_app, rep_test) ppv1 = nuage_point_leasa_distance_label () ppv2 = nuage_point_leasa_distance_label () print "construction du nuage d'apprentissage" nuage_app = nuage_image_leasa (ppv1, rep_app, nb_app) print "nombre de points : ", len (nuage_app) print "construction du nuage de test" nuage_test = nuage_image_leasa (ppv2, rep_test, nb_test) print "nombre de points : ", len (nuage_test) print "résultat de la classification" erreur = [] bienclasse = [] temps1 = time.clock () good,bad = nuage_app.ppv_nuage (nuage_test, bienclasse, erreur) temps2 = time.clock () print "---------------------------------------------------------------------------" print "temps de traitement en secondes ", temps2 - temps1 print "good, bad = ", good, bad print "taux de classification : ", float (good) / (good + bad) print "écriture du fichier ", html_file1 nuage_app.html_couple (html_file1, bienclasse, zoom = 4) print "écriture du fichier ", html_file2 nuage_app.html_couple (html_file2, erreur, zoom = 4)
to be filled later
from scipy.stats import norm def pvalue (p, q, N) : theta = abs(p-q) var = p*(1-p) bn = (2*N)**0.5 * theta / var**0.5 ret = (1 - norm.cdf(bn))*2 return ret def pvalue_N (p, q, alpha) : theta = abs(p-q) var = p*(1-p) rev = abs(norm.ppf (alpha/2)) N = 2 * (rev * var**0.5 / theta)** 2 return int(N+1) def alphatable (ps, dps, alpha) : values = [] for p in ps : row=[] for dp in dps : q = p+dp r = pvalue_N (p,q,alpha) if 1 >= q >= 0 else -1 row.append (r) values.append (row) return values def pprint(ps,dps,table, format, fileFormat = "latex") : text = [] if fileFormat == "latex" : cc = "r" + ("|r" * len(dps)) text.append("\\begin{tabular}{" + cc + "}") row = [""] + [ r"\textbf{%1.3f}" % _ for _ in dps ] text.append("&".join(row) + r"\\\hline") for p,line in zip(ps,table) : row = ["\\textbf{%1.2f}" % p] + \ [ format % _ if _ != -1 else "" for _ in line ] text.append("&".join(row) + r"\\\hline") text.append("\\end{tabular}") return "\n".join(text) else : # TSV row = [""] + [ r"%1.3f" % _ for _ in dps ] text.append("\t".join(row) ) for p,line in zip(ps,table) : row = ["%1.2f" % p] + \ [ format % _ if _ != -1 else "" for _ in line ] text.append("\t".join(row) ) return "\n".join(text) if __name__ == "__main__" : print ("norm.ppf(0.025)",norm.ppf (0.025)) # -1.9599639845400545 ps = [0.001, 0.002] + [ 0.05*i for i in range (1,20) ] dps = [ -0.2, -0.1, -0.02, -0.01, -0.002, -0.001, 0.2, 0.1, 0.02, 0.01, 0.002, 0.001, ] dps.sort() t = alphatable (ps, dps, 0.05) print (pprint (ps, dps, t, "%d", "latex")) print (pprint (ps, dps, t, "%d", "html"))
to be filled later
import numpy, matplotlib, random, pylab, math def matrix_square_root(sigma) : eigen, vect = numpy.linalg.eig(sigma) dim = len(sigma) res = numpy.identity(dim) for i in range(0,dim) : res[i,i] = eigen[i]**0.5 return vect * res * vect.transpose() def chi2_level (alpha = 0.95) : N = 1000 x = [ random.gauss(0,1) for _ in range(0,N) ] y = [ random.gauss(0,1) for _ in range(0,N) ] r = map ( lambda c : (c[0]**2+c[1]**2)**0.5, zip(x,y)) r = list(r) r.sort() res = r [ int (alpha * N) ] return res def square_figure(mat, a) : x = [ ] y = [ ] for i in range (0,100) : x.append ( a * mat[0][0]**0.5 ) y.append ( (random.random ()-0.5) * a * mat[1][1]**0.5*2 ) x.append ( -a * mat[0][0]**0.5 ) y.append ( (random.random ()-0.5) * a * mat[1][1]**0.5*2 ) y.append ( a * mat[1][1]**0.5 ) x.append ( (random.random ()-0.5) * a * mat[0][0]**0.5*2 ) y.append ( -a * mat[1][1]**0.5 ) x.append ( (random.random ()-0.5) * a * mat[0][0]**0.5*2 ) pylab.plot(x,y, 'ro') x = [ ] y = [ ] for i in range (0,100) : x.append ( a ) y.append ( (random.random ()-0.5) * a*2 ) x.append ( -a ) y.append ( (random.random ()-0.5) * a*2 ) y.append ( a ) x.append ( (random.random ()-0.5) * a*2 ) y.append ( -a ) x.append ( (random.random ()-0.5) * a*2 ) xs,ys = [],[] for a,b in zip (x,y) : ar = numpy.matrix( [ [a], [b] ] ).transpose() we = ar * root xs.append ( we [0,0] ) ys.append ( we [0,1] ) pylab.plot(xs,ys, 'bo') pylab.show() def circle_figure (mat, a) : x = [ ] y = [ ] for i in range (0,200) : z = random.random() * math.pi * 2 i = a * mat[0][0]**0.5 * math.cos(z) j = a * mat[0][0]**0.5 * math.sin(z) x.append ( i ) y.append ( j ) pylab.plot(x,y, 'ro') x = [ ] y = [ ] for i in range (0,200) : z = random.random() * math.pi * 2 i = a * math.cos(z) j = a * math.sin(z) x.append ( i ) y.append ( j ) xs,ys = [],[] for a,b in zip (x,y) : ar = numpy.matrix( [ [a], [b] ] ).transpose() we = ar * root xs.append ( we [0,0] ) ys.append ( we [0,1] ) pylab.plot(xs,ys, 'bo') pylab.show() if __name__ == "__main__" : level = chi2_level () mat = [ [0.1, 0.05], [0.05, 0.2] ] npmat = numpy.matrix(mat) root = matrix_square_root (npmat) square_figure (mat, 1.96) circle_figure (mat, level)
to be filled later
import random, math def densite_gauss (mu, sigma, x) : e = -(x - mu)**2 / (sigma**2 * 2) d = 1. / ((2*math.pi)**0.5 * sigma) return d * math.exp (e) def simulation_vector (N, mu, sigma) : return [ random.gauss(mu,sigma) for n in range(N) ] def ratio (vector, x, fdensite) : under = 0 above = 0 fx = fdensite(x) for u in vector : f = fdensite (u) if f >= fx : above += 1 else : under += 1 return float(above) / float (above + under) if __name__ == "__main__" : x = 1.96 N = 10000 mu = 0 sigma = 1 v = simulation_vector (N, mu, sigma) g = ratio (v, x, lambda y : densite_gauss (mu, sigma, y) ) print (g)
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)
tracé d'une ligne
# -*- coding: utf-8 -*- """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 if b < 0: b += vx y += 1 ligne.append ((x,y)) # ------ ligne ajoutée x += 1 # ------ ligne déplacée 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 if b < 0: b += vy x += 1 ligne.append ((x,y)) # ------ ligne ajoutée y += 1 # ------ ligne déplacée 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), (1, 1), (2, 1), (3, 1), # (3, 2), (4, 2), (5, 2), (5, 3), (6, 3), (7, 3)] # rappel : résultat en 8-connexité : # [(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)
tracé d'une ellipse
# coding: cp1252 """ce module contient la fonction trace_ellipse qui retourne l'ensemble des pixels concernés par le tracé d'une ellipse en 8-connexité""" import pygame # pour les affichages import random import math def trace_ellipse (xc,yc,a,b): """dessine une ellipse de centre xc,yc, de demi axe horizontal a, de demi-axe vertical b, l'ellipse a pour équation x²/a² + y²/b² = 1 si l'origine est placée en xc,yc, l'équation de la tangente au point x0, y0 est : x x0 / a² + y y0 / b² = 0, ou x x0 b² + y y0 a² = 0""" # on évite les cas litigieux if a == 0 : return [ (xc, yc + y) for y in xrange (-b,b) ] if b == 0 : return [ (xc + x, yc) for x in xrange (-a,a) ] bb = b * b aa = a * a # on trace l'ellipse de centre 0,0 ellipse = [] # premier huitième vx = a * bb vy = 0 x = a y = 0 bl = vx / 2 while vx >= vy and x >= 0 : ellipse.append ((x,y)) y += 1 vy += aa # vy = y * aa bl -= vy if bl < 0 : x -= 1 vx -= bb # vx = x * bb bl += vx # second huitième while x >= 0 : ellipse.append ((x,y)) x -= 1 vx -= bb # vx = x * bb bl += vx if bl > 0 : y += 1 vy += aa # vy = y * aa bl -= vy # second quart, symétrique par rapport à l'axe des ordonnées ellipse2 = [ (-x,y) for (x,y) in ellipse ] ellipse2.reverse () ellipse.extend (ellipse2) # troisième et quatrième quarts : symétrique par rapport à l'axe des abscisse ellipse2 = [ (x,-y) for (x,y) in ellipse ] ellipse2.reverse () ellipse.extend (ellipse2) return [ (x + xc, y + yc) for (x,y) in ellipse ] def display_ligne (ensemble, screen): """affiche un ensemble de pixels à l'écran""" color = 0,0,0 for p in ensemble: 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 = 300, 300 black = 0, 0, 0 white = 255,255,255 screen = pygame.display.set_mode(size) screen.fill (white) print trace_ellipse (0,0,6,6) # pour le premier quart, affiche # [(6, 0), (6, 1), (6, 2), (5, 3), (4, 4), (3, 5), (2, 6), (1, 6), (0, 6), ... 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) xc,yc = (x1 + x2) / 2 , (y1 + y2) / 2 a,b = abs (x2 - x1) / 2 , abs (y2 - y1) / 2 ell = trace_ellipse (xc,yc,a,b) display_ligne (ell, screen) attendre_clic (screen)
File: portrait.tex, line 52
gamma = 9 # paramètre gamma park = 30 # paramètre k, pas trop petit pour commencer, # de plus en plus petit par la suite (jusqu'à 3) # chargement d'une image image = pygame.image.load("bette_davis.png") size = image.get_size () xx,yy = size [0], size [1] X,Y = int (xx // park) + 1, int (yy // park) + 1 # à cet endroit, il faut déterminer l'emplacement des villes # en utilisant l'image, la fonction construit_ville # du programme initial doit être réécrite villes = construit_ville (image, gamma, park) # les lignes qui suivent décrivent la séquence à écrire pour # obtenir le plus court chemin passant pour toutes les villes arbre = arbre_poids_minimal (villes,park) chemin = circuit_eulerien (villes ,arbre) neurone = circuit_hamiltonien (chemin) neurones = [ villes [i] for i in neurone ] amelioration_chemin (neurones, park, X,Y, 6, screen)
algorithme de Kruskal
# coding: cp1252 import random # pour tirer aléatoirement des nombres import math # fonctions cos, sin import pygame # pour les affichages import copy import bresenham_ligne4 as brl # pour dessiner des lignes import psyco # pour accélérer le programme def attendre_clic (screen,x,y): """dessine une croix sur l'écran et attend la pression d'un clic de souris""" color = 0,0,0 pygame.draw.line (screen, color, (0,0), (x-1,y-1)) pygame.draw.line (screen, color, (x-1,0), (0,y-1)) pygame.display.flip () reste = True while reste: for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONUP : reste = False break def ajuste_image (image, park): """arrondi les dimensions d'une images à park, retourne une partie de l'image""" x,y = image.get_size () x = (x // park) * park y = (y // park) * park image2 = image.subsurface (((0,0),(x,y))) image3 = image2.copy () return image3 def construit_ville(image, gamma, park): """tire aléatoirement des villes, ces villes sont d'autant plus nombreuses que l'intensité de l'image est faible, évite les villes confondues""" x,y = image.get_size () nbx = x // park nby = y // park villes = [] for i in xrange(0,nbx): for j in xrange(0,nby): x1 = i * park x2 = (i+1) * park y1 = j * park y2 = (j+1) * park # calcul de l'obscurité moyenne moy = 0 for k in xrange(x1,x2): for l in xrange(y1,y2): int = image.get_at ((k,l)) moy += int [0] + int [1] + int [2] moy /= park * park * 3 # nombre de villes nbv = gamma - gamma * moy / 256 pl = [] for k in xrange(0,nbv): xx = random.randint (x1,x2-1) yy = random.randint (y1,y2-1) if (xx,yy) not in pl : villes.append ((xx,yy)) pl.append ((xx,yy)) return villes def display_ville(villes,screen): """dessine les villes à l'écran""" color = 0,0,0 for v in villes: pygame.draw.line (screen, color, v, v) def display_neurone(neurones_,screen,mult = 1): """dessine les neurones à l'écran""" color = 0,0,0 color2 = 0,255,0 if mult != 1 : neurones = [ (n [0] * mult, n [1] * mult ) for n in neurones_ ] if mult == 2 : l = 1 else : l = 1 for n in neurones : pygame.draw.line (screen, color, n, n) #pygame.draw.circle (screen, color2, neurones [0], 8) if len (neurones) > 1 : color3 = 150,0,0 #pygame.draw.circle (screen, color3, neurones [1], 6) if len (neurones) > 1: pygame.draw.lines (screen, color, True, neurones, l) else : neurones = [ (n [0] * mult, n [1] * mult ) for n in neurones_ ] if mult == 2 : l = 1 else : l = 1 for n in neurones_ : pygame.draw.line (screen, color, n, n) #pygame.draw.circle (screen, color2, neurones [0], 8) if len (neurones_) > 1 : color3 = 150,0,0 #pygame.draw.circle (screen, color3, neurones [1], 6) if len (neurones_) > 1: pygame.draw.lines (screen, color, True, neurones_, l) def display_arbre (villes, arbre, mult = 1): """dessine le graphe de poids minimal défini par arbre""" if mult == 2 : color = 0,255,0 l = 4 else : l = 1 color = 0,0,255 for i in xrange (0, len (villes)): for j in arbre [i]: v = (villes [i][0] * mult, villes [i][1] * mult) vv = (villes [j][0] * mult, villes [j][1] * mult) pygame.draw.line (screen, color, v, vv, l) def repartition_zone (villes, zone_taille, ask_zone = False) : """répartit les villes en zones, retourne les villes rangées par zones, chaque éléments zones [z][k] contient : - les coordonnées de la ville - ses coordonnées en zone, (zx, zy) - son indice dans la liste villes la fonction retourne également le nombre de zones selon l'axe des abscisses et l'axe des ordonnées, retourne aussi le nombre de zones, si ask_zone est True, retourne un paramètre supplémentaire : zone""" print "gestion des zones" X,Y = 0,0 for v in villes: X = max (v [0] // zone_taille, X) Y = max (v [1] // zone_taille, Y) X += 1 Y += 1 # attribution des zones zone = [] nb = len (villes) Zmax = 0 for i in xrange (0,len (villes)): v = villes [i] x = int (v [0] // zone_taille) y = int (v [1] // zone_taille) z = int (y * X + x) Zmax = max (z,Zmax) zone.append ((z, v, (x,y), i)) # rangement par zone Zmax += 1 zones = [ [] for i in xrange (0,Zmax) ] for z in zone: zones [ z [0] ].append ((z [1], z [2], z [3])) if ask_zone : return zones,X,Y,Zmax,zone else : return zones,X,Y,Zmax def voisinage_zone (z,Zmax,X,Y): """retourne la liste des voisins d'une zone z sachant qu'il y a X zones sur l'axe des abscisses et Y zones sur l'axe des ordonnées, Zmax est le nombre de zones, inclus z dans cette liste""" x = z % X y = z // X voisin_ = [z] if x > 0: voisin_.append (z-1) if x < X: voisin_.append (z+1) if y > 0: voisin_.append (z-X) if y < Y: voisin_.append (z+X) if x > 0 and y > 0 : voisin_.append (z-1-X) if x > 0 and y < Y : voisin_.append (z-1+X) if x < X and y > 0 : voisin_.append (z+1-X) if x < X and y < Y : voisin_.append (z+1+X) voisin = [ int (i) for i in voisin_ if i >= 0 and i < Zmax ] return voisin def distance (p1,p2): """calcule la distance entre deux villes""" x = p1 [0] - p2[0] y = p1 [1] - p2[1] return math.sqrt (x*x + y*y) def arbre_poids_minimal(villes, zone_taille): """construit l'arbre de poids minimal, retourne une liste de listes, chaque sous-liste associée à une ville contient la liste des ses voisins, zone_taille permet de découper l'image en zones, les distances ne seront calculées que si deux éléments sont dans la même zone ou dans une zone voisine""" def tri_distance (u,v): if u [2] < v [2] : return -1 elif u [2] > v [2] : return 1 else : return 0 zones,X,Y,Zmax = repartition_zone (villes, zone_taille) # calcul des distances print "calcul des distances" li = [] for z in xrange (0,len (zones)): if z % 1000 == 0 : print "zone ", z, len(zones) voisin = voisinage_zone (z,Zmax,X,Y) for v in zones [z]: for zz in voisin: for u in zones [zz]: d = distance (v [0], u [0]) li.append ((v [2], u [2], d)) print "tri ", len(li) li.sort (tri_distance) # composantes connexes print "construction de l'arbre" # nombre de composantes connexes nb_comp = len (villes) # indice de la composante d'une ville num_comp = [ i for i in xrange(0,len(villes)) ] # liste des voisins pour chaque ville arbre = [ [] for i in xrange(0,len(villes)) ] # liste des villes par composante connexe list_comp = [ [i] for i in xrange(0,len(villes)) ] iii = 0 for c in li: if iii % 10000 == 0 : print "arête ", iii, len(li) iii += 1 i,j = c [0], c [1] if num_comp [i] != num_comp [j]: # on relie les villes i et j car elles appartiennent # à des composantes connexes différentes arbre [i].append (j) # i est voisine de j arbre [j].append (i) # j est voisine de i cl = num_comp [i] # composante connexe restante ki = num_comp [j] # composante connexe à aggréger à la précédente for k in list_comp [ki]: num_comp [k] = cl list_comp [cl].append (k) list_comp [ki] = [] nb_comp -= 1 # une composante connexe en moins if nb_comp == 0: break # il n'y a plus qu'une seule composante connexe, inutile de continuer return arbre def vecteur_points (p1,p2): """retourne le vecteur entre les points p1 et p2""" return ( p2 [0] - p1 [0], p2 [1] - p1 [1]) def vecteur_norme (vec): """retourne la norme d'un vecteur""" return math.sqrt (vec [0] * vec [0] + vec [1] * vec [1]) def vecteur_cosinus (vec1, vec2): """retourne le cosinus entre deux vecteurs, utilise le produit scalaire""" norm1 = vecteur_norme (vec1) norm2 = vecteur_norme (vec2) if norm1 == 0: return 1 if norm2 == 0: return 1 scal = vec1 [0] * vec2 [0] + vec1 [1] * vec2 [1] return scal / (norm1 * norm2) def vecteur_sinus (vec1, vec2): """retourne le sinus entre deux vecteurs, utilise le produit vectoriel""" norm1 = vecteur_norme (vec1) norm2 = vecteur_norme (vec2) if norm1 == 0: return 0 if norm2 == 0: return 0 scal = vec1 [0] * vec2 [1] - vec1 [1] * vec2 [0] return scal / (norm1 * norm2) def oppose_vecteur (vec): """retourne le vecteur opposé""" return (- vec [0], - vec [1]) def circuit_eulerien (villes, arbre): """définit un circuit eulérien, villes contient la liste des villes, tandis que arbre est une liste de listes, arbre [i] est la liste des villes connectées à la ville i, on suppose que arbre est un graphe de poids minimal non orienté, l'algorithme ne marche pas s'il existe des villes confondues""" # on choisit une ville qui est une extrémité et parmi celle-là on la choisit au hasard has = [] for i in xrange (0,len (villes)): n = len (arbre [i]) if n == 1: has.append (i) bm = random.randint (0, len (has) -1) bm = has [bm] # vecteur, le circuit eulérien contient # nécessairement 2 * len (villes) noeuds puisque c'est # le graphe eulérien d'un arbre de poids minimal non orienté vec = (1,1) chemin = [bm] while len (chemin) < 2 * len (villes)-1 : v = villes [bm] ma = - math.pi - 1 bvec = vec opvec = oppose_vecteur (vec) for k in xrange (0, len (arbre [bm])) : l = arbre [bm][k] vec2 = vecteur_points (v, villes [l]) if opvec == vec2 : angle = -math.pi else : cos = vecteur_cosinus (vec, vec2) sin = vecteur_sinus (vec, vec2) angle = math.atan2 (sin, cos) if angle > ma : ma = angle bl = k bvec = vec2 b = arbre [bm][bl] chemin.append (b) del arbre [bm][bl] # on supprime l'arc pour ne plus l'utiliser bm = b vec = bvec return chemin def circuit_hamiltonien (chemin): """extrait un circuit hamiltonien depuis un circuit eurlérien""" nb = max (chemin) + 1 res = [] coche = [ False for i in xrange (0, nb) ] for c in chemin : if coche [c] : continue res.append (c) coche [c] = True return res def equation_droite (p1,p2) : """retourne l'équation d'une droite passant par p1 et p2, ax + by + c = 0, retourne les coefficients a,b,c""" vec = vecteur_points (p1,p2) a = vec [1] b = - vec [0] c = - a * p1 [0] - b * p1 [1] return a,b,c def evaluation_droite (a,b,c,p): """l'équation d'une droite est : ax + by + c, retourne la valeur de cette expression au point p""" return a * p [0] + b * p [1] + c def intersection_segment (p1,p2,p3,p4): """dit si les segments [p1 p2] et [p3 p4] ont une intersection, ne retourne pas l'intersection""" # équation de la droite (p1 p2) a1,b1,c1 = equation_droite (p1,p2) a2,b2,c2 = equation_droite (p3,p4) s1 = evaluation_droite (a2,b2,c2,p1) s2 = evaluation_droite (a2,b2,c2,p2) s3 = evaluation_droite (a1,b1,c1,p3) s4 = evaluation_droite (a1,b1,c1,p4) if s1 * s2 <= 0 and s3 * s4 <= 0 : return True else : return False def longueur_chemin (chemin): """retourne la longueur d'un chemin""" s = 0 nb = len (chemin) for i in xrange (0,nb) : s += distance ( chemin [i], chemin [ (i+1) % nb ]) return s def retournement_essai (chemin, i,j, negligeable = 1e-5): """dit s'il est judicieux de parcourir le chemin entre les sommets i et j en sens inverse, si c'est judicieux, change le chemin et retourne True, sinon, retourne False, si j < i, alors la partie à inverser est i, i+1, i+2, ..., len(chemin) -1, 0, 1, ..., j""" nb = len (chemin) if i == j : return False if j - i == -1 : return False if j - i - nb == -1 : return False ia = (i - 1 + nb) % nb ja = (j + 1 ) % nb # arcs enlevés d_ia_i = distance (chemin [ia], chemin [i]) d_j_ja = distance (chemin [j], chemin [ja]) # arcs ajoutés d_ia_j = distance (chemin [ia], chemin [j]) d_i_ja = distance (chemin [i], chemin [ja]) # amélioration ? d = d_ia_j + d_i_ja - d_j_ja - d_ia_i if d >= - negligeable : return False # si amélioration, il faut retourner le chemin entre les indices i et j jp = j if jp < i : jp = j + nb ip = i while ip < jp : i = ip % nb j = jp % nb ech = chemin [i] chemin [i] = chemin [j] chemin [j] = ech ip = ip+1 jp = jp-1 return True def retournement (chemin, taille) : """amélioration du chemin par un algorithme simple, utilise des retournements de taille au plus <taille>, retourne le nombre de modifications""" # traitement des petits retournements nb = len (chemin) nb_change = 1 nbtout = 0 retour = { } while nb_change > 0 : nb_change = 0 for t in xrange (1,taille+1): retour [t] = 0 for i in xrange (0, nb) : j = (i + t) % nb b = retournement_essai (chemin, i, j) if b : retour [t] += 1 nb_change += 1 nbtout += nb_change print "nombre de retournements %d longueur : \t %10.0f détail \t" \ % (nbtout, longueur_chemin (chemin)), " détail : ", retour return nbtout def echange_position_essai (chemin, a,b, x, inversion, negligeable = 1e-5): """échange la place des villes ka à kb pour les placer entre les villes i et i+1, si inversion est True, on inverse également le chemin inséré, si inversion est False, on ne l'inverse pas, si cela améliore, déplace les villes et retourne True, sinon, retourne False""" nb = len(chemin) xa = (x + 1) % nb ka = (a - 1 + nb) % nb kb = (b + 1 ) % nb if not inversion : if x == ka : return False if x == kb : return False if xa == ka : return False if b < a : if a <= x <= b + nb : return False elif a <= x <= b : return False if b < a : if a <= x + nb <= b + nb : return False elif a <= x + nb <= b : return False # arcs enlevés d_x_xa = distance (chemin [x], chemin [xa]) d_ka_a = distance (chemin [ka], chemin [a]) d_b_kb = distance (chemin [b], chemin [kb]) # arcs ajoutés d_ka_kb = distance (chemin [ka], chemin [kb]) d_x_a = distance (chemin [x], chemin [a]) d_b_xa = distance (chemin [b], chemin [xa]) d = d_ka_kb + d_x_a + d_b_xa - d_x_xa - d_ka_a - d_b_kb if d >= -negligeable : return False # villes à déplacer ech = [] bp = b if bp < a : bp = b + nb for i in xrange (a,bp+1): ech.append (chemin [i % nb] ) diff = bp - a + 1 xp = x if xp < b : xp += nb for l in xrange (b+1,xp+1) : ll = l % nb bp = (a + l - b-1) % nb chemin [bp] = chemin [ll] for l in xrange (0,len(ech)) : chemin [ (x+l-diff+1 + nb) % nb ] = ech [l] return True else : if x == ka : return False if x == kb : return False if xa == ka : return False if b < a : if a <= x <= b + nb : return False elif a <= x <= b : return False if b < a : if a <= x + nb <= b + nb : return False elif a <= x + nb <= b : return False # arcs enlevés d_x_xa = distance (chemin [x], chemin [xa]) d_ka_a = distance (chemin [ka], chemin [a]) d_b_kb = distance (chemin [b], chemin [kb]) # arcs ajoutés d_ka_kb = distance (chemin [ka], chemin [kb]) d_x_b = distance (chemin [x], chemin [b]) d_a_xa = distance (chemin [a], chemin [xa]) d = d_ka_kb + d_x_b + d_a_xa - d_x_xa - d_ka_a - d_b_kb if d >= -negligeable : return False # villes à déplacer ech = [] bp = b if bp < a : bp = b + nb for i in xrange (a,bp+1): ech.append (chemin [i % nb] ) ech.reverse () diff = bp - a + 1 cop = copy.copy (chemin) xp = x if xp < b : xp += nb for l in xrange (b+1,xp+1) : ll = l % nb bp = (a + l - b-1) % nb chemin [bp] = chemin [ll] for l in xrange (0,len(ech)) : chemin [ (x+l-diff+1 + nb) % nb ] = ech [l] return True def dessin_arete_zone (chemin, taille_zone, X,Y): """retourne une liste de listes de listes, res [i][j] est une liste des arêtes passant près de la zone (x,y) = [i][j], si k in res [i][j], alors l'arête k,k+1 est dans la zone (i,j), X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur du côté du carré d'une zone""" res = [ [ [] for j in xrange (0,Y+1) ] for i in xrange (0,X+1) ] nb = len (chemin) for i in xrange (0,nb): a = chemin [i] b = chemin [(i+1) % nb] x1,x2 = int (a [0] // taille_zone), int (b [0] // taille_zone) y1,y2 = int (a [1] // taille_zone), int (b [1] // taille_zone) line = brl.trace_ligne (x1,y1,x2,y2) for x,y in line: res [x][y].append (i) return res def voisinage_zone_xy (x,y,X,Y): """retourne la liste des voisins d'une zone (x,y) sachant qu'il y a X zones sur l'axe des abscisses et Y zones sur l'axe des ordonnées, inclus z dans cette liste""" voisin = [(x,y)] if x > 0 : voisin.append ((x-1,y)) if x < X-1 : voisin.append ((x+1,y)) if y > 0 : voisin.append ((x,y-1)) if y < Y-1 : voisin.append ((x,y+1)) if x > 0 and y > 0 : voisin.append ((x-1,y-1)) if x > 0 and y < Y-1 : voisin.append ((x-1,y+1)) if x < X-1 and y > 0 : voisin.append ((x+1,y-1)) if x < X-1 and y < Y-1 : voisin.append ((x+1,y+1)) return voisin def echange_position (chemin, taille, taille_zone, X,Y, grande = 0.5) : """regarde si on ne peut pas déplacer un segment de longueur taille pour supprimer les arêtes les plus longues, au maximum <grande> longues arêtes, retourne le nombre de changement effectués, X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur d'un côté du carré d'une zone""" nb = len(chemin) def tri_arete (x,y): """pour trier la liste l par ordre décroissant""" if x [2] < y [2] : return 1 elif x [2] > y [2] : return -1 else : return 0 # list des arêtes triés par ordre décroissant la = [] for i in xrange (0,nb) : im = (i+1) % nb la.append ( (i, im, distance (chemin [i], chemin [im]) ) ) la.sort (tri_arete) # zone associé à chaque arête zone = dessin_arete_zone (chemin, taille_zone, X, Y) dseuil = la [ int (nb * grande) ] [ 2 ] nbtout = 0 nb_change = 0 iarete = 0 retour = { } for t in xrange (1, taille+1): retour [t] = 0 while iarete < nb : nb_change = 0 arete = la [iarete] iarete += 1 x = arete [0] xm = arete [1] a = chemin [x] b = chemin [xm] d = distance ( a,b ) if d < dseuil : break # arête trop petite # zone traversée par la ligne x1,x2 = int (a [0] // taille_zone), int (b [0] // taille_zone) y1,y2 = int (a [1] // taille_zone), int (b [1] // taille_zone) ens = brl.trace_ligne (x1,y1,x2,y2) ville = [] for k,l in ens: voisin = voisinage_zone_xy (k,l,X,Y) for u,v in voisin : ville.extend (zone [u][v]) # on supprime les doubles ville.sort () if len (ville) == 0 : continue sup = [] mx = -1 for v in ville: if v == mx : sup.append (v) mx = v for s in sup: ville.remove (s) # on étudie les possibilités de casser l'arête (x,xm) aux alentours des villes # comprise dans l'ensemble ville for t in xrange (1, taille+1): for i in ville: # on essaye d'insérer le sous-chemin (x- t + 1 + nb) --> x # au milieu de l'arête i,i+1 b = echange_position_essai (chemin, (x- t + 1 + nb) % nb,x, i, False) if b : nb_change += 1 retour [t] += 1 continue # on essaye d'insérer le sous-chemin (xm+ t - 1) --> xm # au milieu de l'arête i,i+1 b = echange_position_essai (chemin, (xm + t - 1) % nb, xm, i, False) if b : nb_change += 1 retour [t] += 1 continue # on essaye de casser l'arête x,xm en insérant # le sous-chemin i --> (i+t) % nb b = echange_position_essai (chemin, i, (i+t) % nb, x, False) if b : nb_change += 1 retour [t] += 1 continue # idem b = echange_position_essai (chemin, i, (i+t) % nb, x, True) if b : retour [t] += 1 nb_change += 1 continue # idem b = echange_position_essai (chemin, (i-t+nb) % nb, i, x, False) if b : nb_change += 1 retour [t] += 1 continue # idem b = echange_position_essai (chemin, (i-t + nb) % nb, i, x, True) if b : retour [t] += 1 nb_change += 1 continue nbtout += nb_change print "nombre de déplacements %d longueur : \t %10.0f détail \t" \ % (nbtout, longueur_chemin (chemin)), " détail : ", retour return nbtout def supprime_croisement (chemin, taille_zone, X,Y) : """supprime les croisements d'arêtes, retourne le nombre de changement effectués, X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur d'un côté du carré d'une zone""" nb = len(chemin) # zone associé à chaque arête zone = dessin_arete_zone (chemin, taille_zone, X, Y) nbtout = 0 for i in xrange (0,nb) : im = (i+1) % nb a = chemin [i] b = chemin [im] # zone traversée par la ligne x1,x2 = int (a [0] // taille_zone), int (b [0] // taille_zone) y1,y2 = int (a [1] // taille_zone), int (b [1] // taille_zone) ens = brl.trace_ligne (x1,y1,x2,y2) ville = [] for k,l in ens: voisin = voisinage_zone_xy (k,l,X,Y) for u,v in voisin : ville.extend (zone [u][v]) # on supprime les doubles ville.sort () if len (ville) == 0 : continue sup = [] mx = -1 for v in ville: if v == mx : sup.append (v) mx = v for s in sup: ville.remove (s) nb_change = 0 for v in ville : b = retournement_essai (chemin, i,v) if b : nb_change += 1 continue b = retournement_essai (chemin, im,v) if b : nb_change += 1 continue nbtout += nb_change print "nombre de croisements %d longueur : \t %10.0f détail \t" \ % (nbtout, longueur_chemin (chemin)) return nbtout def amelioration_chemin (chemin, taille_zone, X, Y, taille = 10, \ screen = None, image = None): """amélioration du chemin par un algorithme simple, utilise des retournements de taille au plus taille, traite les arcs qui se croisent, traite les grands arcs, utilise un quadrillage de taille window, X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur d'un côté du carré d'une zone""" white = 255,255,255 #première étape rapide nb = 1 while nb > 0: nb = retournement (chemin, taille) if screen != None: screen.fill (white) display_neurone(chemin, screen, 1) pygame.display.flip () # amélioration nb = 1 size = image.get_size () dec = size [0] fin = False while nb > 0 and not fin : nb = retournement (chemin, taille) if screen != None: screen.fill (white) if image != None : screen.blit (image, (dec,0)) display_neurone(chemin, screen) pygame.display.flip () nb += echange_position (chemin, taille / 2, taille_zone, X, Y) if screen != None: screen.fill (white) if image != None : screen.blit (image, (dec,0)) display_neurone(chemin, screen) pygame.display.flip () nb += supprime_croisement (chemin, taille_zone,X,Y) if screen != None: screen.fill (white) if image != None : screen.blit (image, (dec,0)) display_neurone(chemin, screen) pygame.display.flip () if screen != None : for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONUP : print "attendre.............................................." attendre_clic (screen,0,0) print "reprise" break if event.type == pygame.KEYDOWN and event.key == 27 : # si la touche ECHAP est pressée, l'optimisation s'arrête print "..............arrêter l'optimisation" fin = True break ################################################################################ if __name__ == "__main__" : pygame.init () psyco.full () gamma = 4 park = 3 image2 = pygame.image.load("bette_davis.png") image = ajuste_image (image2, park) size = image.get_size () xx,yy = size [0], size [1] X,Y = int (xx // park) + 1, int (yy // park) + 1 dec = size [0] size = (size [0] * 2, size [1]) size = width, height = x,y = size black = 0, 0, 0 white = 255,255,255 screen = pygame.display.set_mode(size) villes = construit_ville (image, gamma, park) print "taille de l'image : ", size print "nombre de villes : ", len(villes) screen.fill (white) screen.blit (image, (dec,0)) display_ville (villes, screen) pygame.display.flip () print "calcul" arbre = arbre_poids_minimal (villes,park) arbre2 = copy.deepcopy (arbre) print "dessin" display_arbre (villes, arbre) attendre_clic(screen,0,0) print "circuit eulérien" chemin = circuit_eulerien (villes ,arbre) print "circuit hamiltonien" neurone = circuit_hamiltonien (chemin) print "dessin" neurones = [ villes [i] for i in neurone ] display_neurone(neurones, screen) attendre_clic(screen,0,0) print "amélioration" amelioration_chemin (neurones, park, X,Y, 6, screen, image) attendre_clic(screen,0,0) # taille double print "taille double" size = (size [0], size [1]*2) screen = pygame.display.set_mode(size) screen.fill (white) #display_arbre (villes, arbre2, 2) display_neurone (neurones, screen, 2) attendre_clic(screen,0,0)
image de synthèse, base
# coding: cp1252 """définition des objets permettant de construire une image de synthèse""" import math import copy class vecteur (object) : """définit ce qu'est un point""" __slots__ = "x","y","z" def __str__ (self): """pour l'affichage""" return "(%3.2f,%3.2f,%3.2f)" % (self.x, self.y, self.z) def __init__(self,x,y,z): """initialisation""" self.x, self.y, self.z = float (x), float (y), float (z) def __add__ (self,p): """addition de deux points""" return vecteur (self.x + p.x, self.y + p.y, self.z + p.z) def __neg__ (self): """retourne l'opposé d'un vecteur""" return vecteur (-self.x,-self.y,-self.z) def __iadd__ (self,p): """addition de deux points""" self.x += p.x self.y += p.y self.z += p.z return self def __sub__ (self,p): """soustraction de deux points""" return vecteur (self.x - p.x, self.y - p.y, self.z - p.z) def __isub__ (self,p): """soustraction de deux points""" self.x -= p.x self.y -= p.y self.z -= p.z return self def __mul__ (self,x): """multiplication par un scalaire""" return vecteur (self.x * x, self.y * x, self.z * x) def __imul__ (self,x): """multiplication par un scalaire""" self.x *= x self.y *= x self.z *= x return self def __div__ (self,x): """division par un scalaire""" return vecteur (self.x / x, self.y / x, self.z / x) def __idiv__ (self,x): """division par un scalaire""" self.x /= x self.y /= x self.z /= x return self def norme2 (self) : """retourne la norme du vecteur au carrée""" return self.x * self.x + self.y * self.y + self.z * self.z def scalaire (self, v) : """calcule le produit scalaire entre self et v""" return self.x * v.x + self.y * v.y + self.z * v.z def vectoriel (self, v) : """calcule le produit vectoriel entre self et v""" res = vecteur (0,0,0) res.x = self.y * v.z - self.z * v.y res.y = self.z * v.x - self.x * v.z res.z = self.x * v.y - self.y * v.x return res def norme (self) : """retourne la norme du vecteur""" return math.sqrt (self.norme2 ()) def renorme (self) : """renorme ce vecteur""" n = self.norme () if n > 0 : return self / n else : return copy.copy (self) def cosinus (self, v) : """retourne le cosinus de entre le vecteur self et le vecteur r""" sc = self.scalaire (v) n1 = self.norme () n2 = v.norme () n = n1 * n2 if n == 0 : return 0 return float (sc) / float (n) def sinus (self, v, norm) : """retourne le sinus de entre le vecteur self et le vecteur r, norm est un vecteur normal et de norme 1 permettant d'orienter le plan dans lequel se trouve les deux vecteurs dont il faut mesurer le sinus""" sc = self.vectoriel (v) n1 = self.norme () n2 = v.norme () n = n1 * n2 if n == 0 : return 0 return sc.scalaire (norm) / float (n) def angle (self, v, norm) : """retourne l'angle entre les vecteur self et v, retourne un angle compris entre -pi et pi, norm est la direction du vecteur normal au plan des deux vecteurs""" cos = self.cosinus (v) sin = self.sinus (v, norm) angle = math.atan2 (sin, cos) if angle > math.pi : angle -= math.pi * 2 return angle def diff_abs (self, v): """retourne la somme des valeurs absolues des différentes entre coordonnées""" r = abs (self.x - v.x) r += abs (self.y - v.y) r += abs (self.z - v.z) return r def __eq__ (self, v) : """définit l'égalité entre deux vecteurs""" if v == None : return False return self.diff_abs (v) < 1e-10 def __ne__ (self, v) : """définit l'égalité entre deux vecteurs""" if v == None : return True return self.diff_abs (v) > 1e-10 class couleur (vecteur) : """une couleur est un vecteur dont les coordonnées sont comprises entre 0 et 1, x <--> rouge, y <--> vert, z <--> bleu""" def __init__ (self, x,y,z) : vecteur.__init__(self, x,y,z) self.borne () def borne (self) : """si une couleur est hors bornes, réajuste la couleur, prend le maximum devient 1, les autres intensités sont ajustées selon ce facteur d'échelle""" if self.x < 0 : self.x = 0 if self.y < 0 : self.y = 0 if self.z < 0 : self.z = 0 m = max (self.x, self.y) m = max (m, self.z) if m > 1 : self.x /= m self.y /= m self.z /= m def __add__ (self,p): """addition de deux couleurs""" return couleur (self.x + p.x, self.y + p.y, self.z + p.z) def produit_terme (self, v) : """effectue un produit terme à terme""" return couleur (self.x * v.x, self.y * v.y, self.z * v.z) def __mul__ (self,x): """multiplication par un scalaire""" return couleur (self.x * x, self.y * x, self.z * x) class repere (object) : """définition d'un repère orthonormé""" def __init__ (self, origine = vecteur (0,0,0), \ axex = vecteur (1,0,0), \ axey = vecteur (0,1,0), \ axez = vecteur (0,0,1)) : """initialisation, origine et les trois axes""" self.origine = origine self.x = axex self.y = axey self.z = axez def coordonnees (self, v) : """on suppose que les coordonnées de v sont exprimées dans ce repère, calcule les coordonnées de v dans le repère d'origine""" res = copy.copy (self.origine) res.x += v.x * self.x.x + v.y * self.y.x + v.z * self.z.x res.y += v.x * self.x.y + v.y * self.y.y + v.z * self.z.y res.z += v.x * self.x.z + v.y * self.y.z + v.z * self.z.z return res def __str__ (self): """affichage""" s = "origine : " + str (self.origine) + "\n" s += "axe des x : " + str (self.x) + "\n" s += "axe des y : " + str (self.y) + "\n" s += "axe des z : " + str (self.z) + "\n" return s class pixel (object) : """définit ce qu'est un pixel""" __slots__ = "x","y" def __init__(self,x,y): """initialisation""" self.x, self.y = int (x), int (y) def __str__ (self): """pour l'affichage""" return "(%d, %d)" % (self.x, self.y) class rayon (object) : """définit ce qu'est un rayon""" __slots__ = "origine", "direction", "pixel", "couleur" def __init__ (self, origine, direction, pixel, couleur): """initialisation""" self.origine, self.direction, self.pixel, self.couleur = \ origine, direction, pixel, couleur def __str__ (self): """pour l'affichage""" s = "origine : " + str (self.origine) s += " direction : " + str (self.direction) s += " pixel : " + str (self.pixel) s += " couleur : " + str (self.couleur) return s class objet (object): """définit l'interface pour un objet à dessiner dans une image de synthese""" def intersection (self, r) : """retourne le point d'intersection avec le rayon r, retourne None s'il n'y pas d'intersection""" return None def normale (self, p, rayon) : """retourne la normale au point de coordonnée p, et connaissant le rayon""" return None def couleur_point (self, p) : """retourne la couleur au point de coordonnée p""" return None def rayon_refracte (self, rayon, p) : """retourne le rayon réfracté au point p de la surface, si aucune, retourne None""" return None def rayon_reflechi (self, rayon, p) : """retourne le rayon réfléchi au point p de la surface, si aucune, retourne None""" return None def phong_coefficient (self): """retourne un coefficient propre à l'objet pour le modèle d'illumination de Phong""" return float (0) class source (object) : """définition d'une source ponctuelle""" __slots__ = "origine", "couleur" def __init__ (self, origine, couleur): """initialisation""" self.origine, self.couleur = origine, couleur def __str__ (self) : """affichage""" return "source : " + str (self.origine) + " couleur : " + str (self.couleur) if __name__ == "__main__" : v = vecteur (0,1,2) u = vecteur (0,1,2) w = u + v print u,v,w print w * 6 p = pixel (5,5) print p c = couleur (1,1,1) print c r = rayon (u,w,p,c) print r s = source (v, c) print s
image de synthèse, sphère
# coding: cp1252 """définition d'une sphère""" import image_synthese_base as base import math class sphere (base.objet): """définit une sphère""" __slots__ = "centre", "rayon", "couleur" def __init__ (self, centre, rayon, couleur): """initialisation""" self.centre, self.rayon, self.couleur = centre, float (rayon), couleur def intersection (self, r) : """retourne le point d'intersection avec le rayon r, retourne None s'il n'y pas d'intersection""" oc = self.centre - r.origine vn = r.direction.norme2 () s = r.direction.scalaire (oc) delta = s*s - vn * (oc.norme2 () - self.rayon * self.rayon) if delta < 0 : return None delta = math.sqrt (delta) l1 = (s - delta) / vn l2 = (s + delta) / vn if 0 < l1 < l2 : l = l1 elif l1 < 0 < l2 : l = l2 elif 0 < l2 < l1 : l = l2 elif l2 < 0 < l1 : l = l1 else : l = None if l == None : return None v = r.origine + r.direction * l return v def normale (self, p, rayon) : """retourne la normale au point de coordonnée p""" v = (p - self.centre) / self.rayon return v def couleur_point (self, p) : """retourne la couleur au point de coordonnée p""" return self.couleur def __str__ (self): """affichage""" s = "sphère --- centre : " + str (self.centre) s += " rayon : " + str (self.rayon) s += " couleur : " + str (self.couleur) return s if __name__ == "__main__" : s = sphere (base.vecteur (0,0,0), 5, base.couleur (0,1,0)) r = base.rayon ( base.vecteur (10,0,0), base.vecteur (1,0,0), \ base.pixel (0,0), base.couleur (0,0,0)) print s print r p = s.intersection (r) print p
image de synthèse, scène
# coding: cp1252 """définition d'une scène""" import image_synthese_base as base import image_synthese_sphere as obj import math import pygame class scene (object): """définit une scène, les axes x,y sont ceux de l'écran, z-1 est la distance à l'écran du point (x,y,z)""" def __init__ (self, repere, alpha, x,y) : """définit la position de l'oeil, l'angle d'ouverture, et la taille de l'écran""" self.repere = repere self.alpha = float (alpha) self.dim = (int (x), int (y)) def ajoute_source (self, source): """ajoute une source ponctuelle de lumière""" if not self.__dict__.has_key ("sources") : self.sources = [] self.sources.append (source) def ajoute_objet (self, objet): """ajoute un objet à la scène""" if not self.__dict__.has_key ("objets") : self.objets = [] self.objets.append (objet) def __str__ (self) : """affichage""" s = "scène ----------------------------\n" s += "repère : " + str (self.repere) + "\n" s += "angle d'ouverture : " + str (self.alpha) + "\n" s += "dimension de l'écran : " + str (self.dim) + "\n" if self.__dict__.has_key ("sources") : for a in self.sources : s += " " +str (a) + "\n" if self.__dict__.has_key ("objets") : for a in self.objets : s += " " + str (a) + "\n" return s def intersection (self, rayon) : """calcule le point d'intersection entre un rayon et le plus proche des objets, retourne l'objet et le point d'intersection""" if not self.__dict__.has_key ("objets") : return None, None p = rayon.origine sp,so = None, None for o in self.objets : i = o.intersection (rayon) if i == None : continue if rayon.direction.scalaire (i - p) <= 0 : continue if i == rayon.origine : continue if sp == None : sp = i so = o else : v = i - p d = sp - p if v.norme2 () < d.norme2 () : sp = i so = o return so, sp def sources_atteintes (self, p) : """retourne la liste des sources atteintes depuis une position p de l'espace, vérifie qu'aucun objet ne fait obstacle""" res = [] for s in self.sources: r = base.rayon (s.origine, p - s.origine, base.pixel (0,0), s.couleur) o,i = self.intersection (r) if i == None : continue if (i - p).norme2 () < 1e-10 : # possible problème d'arrondi res.append (s) continue return res def construit_rayon (self, pixel) : """construit le rayon correspondant au pixel pixel""" x = (pixel.x - self.dim [0] / 2) * math.tan (self.alpha / 2) / min (self.dim) y = (pixel.y - self.dim [1] / 2) * math.tan (self.alpha / 2) / min (self.dim) v = base.vecteur (x,y,1) r = base.rayon (self.repere.origine, self.repere.coordonnees (v), \ pixel, base.couleur (1,1,1)) return r def modele_illumination (self, rayon, p, obj, source) : """calcule la couleur pour un rayon donné, un point p, un objet obj, et une source de lumière source""" n = obj.normale (p, rayon) cos = n.cosinus (source.origine - p) cl = obj.couleur_point (p) * cos cl = cl.produit_terme (rayon.couleur) return cl def couleur_fond (self) : """retourne la couleur du fond""" return base.couleur (0,0,0) def rayon_couleur (self, rayon, ref = True) : """retourne la couleur d'un rayon connaissant les objets, cette fonction doit être surchargée pour chaque modèle d'illumination, si ref == True, on tient compte des rayons réfracté et réfléchi""" list_rayon = [ rayon ] c = base.couleur (0,0,0) b = False while len (list_rayon) > 0 : r = list_rayon.pop () o,p = self.intersection (r) if p == None : continue if ref : t = o.rayon_refracte (r, p) if t != None : list_rayon.append (t) t = o.rayon_reflechi (r, p) if t != None : list_rayon.append (t) sources = self.sources_atteintes (p) if len (sources) == 0 : return base.couleur (0,0,0) for s in sources : cl = self.modele_illumination (r, p, o, s) c += cl b = True if not b : c = self.couleur_fond () else : c.borne () return c def construit_image (self, screen): """construit l'image de synthèse où screen est un objet du module pygame""" count = 0 nbpixel = int (self.dim [0] * self.dim [1] / 100) for y in xrange (0, self.dim [1]) : for x in xrange (0, self.dim [0]) : p = base.pixel (x,y) r = self.construit_rayon (p) c = self.rayon_couleur (r, True) q = (p.x,self.dim [1] - p.y - 1) d = (int (c.x * 255), int (c.y * 255), int (c.z * 255)) pygame.draw.line (screen, d, q,q) count += 1 if count % 150 == 0 : pygame.display.flip () if count % nbpixel == 0 : print "avancement " , count // nbpixel , "%" pygame.display.flip () def attendre_clic (): """dessine une croix sur l'écran et attend la pression d'un clic de souris""" reste = True while reste: for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONUP : reste = False break if __name__ == "__main__" : s = scene (base.repere (), math.pi / 1.5, 400, 300) s.ajoute_source ( base.source (base.vecteur (0,10,10), \ base.couleur (1,1,1) ) ) s.ajoute_source ( base.source (base.vecteur (10,10,5), \ base.couleur (0.5,0.5,0.5) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,0,12), \ 3, base.couleur (1,0,0) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5) ) ) print s screen = pygame.display.set_mode (s.dim) screen.fill ((255,255,255)) s.construit_image (screen) print "image terminée" attendre_clic ()
image de synthèse, complet
# coding: cp1252 """implémentation du modèle d'illumination de Phong""" import image_synthese_scene as scene import image_synthese_base as base import image_synthese_sphere as obj import math import pygame class scene_phong (scene.scene): """définit une scène et utilise le modèle d'illumination de Phong pour construire l'image de synthèse""" def __init__ (self, repere, alpha, x,y, ka = 0.1, kb = 0.8, kc = 0.3, reflet = 6, fond = base.couleur (200,200,200)) : """définit la position de l'oeil, l'angle d'ouverture, et la taille de l'écran""" scene.scene.__init__ (self, repere, alpha, x, y) self.ka, self.kb, self.kc = ka,kb,kc self.reflet = reflet self.fond = fond self.constante = float (1) def __str__ (self) : """affichage""" s = scene.scene.__str__ (self) s += "ka = %1.3f kb = %1.3f kc = %1.3f\n" % (self.ka,self.kb,self.kc) s += "reflet " + str (self.reflet) + "\n" s += "couleur du fond " + str (self.fond) + "\n" return s def couleur_fond (self) : """retourne la couleur du fond""" return self.fond * self.ka def modele_illumination (self, rayon, p, obj, source) : """calcule la couleur pour un rayon donné, un point p, un objet obj, et une source de lumière source""" n = obj.normale (p, rayon).renorme () vr = rayon.direction.renorme () vr *= float (-1) vs = source.origine - p vs = vs.renorme () bi = vs + vr bi = bi.renorme () # premier terme cos = n.scalaire (vs) couleur = source.couleur.produit_terme (obj.couleur_point (p)) * (cos * self.kb) # second terme : reflet cos = n.scalaire (bi) ** self.reflet couleur += source.couleur.produit_terme (source.couleur) * (cos * self.kc) couleur = couleur.produit_terme (rayon.couleur) return couleur if __name__ == "__main__" : s = scene_phong (base.repere (), math.pi / 1.5, 400, 300) s.ajoute_source ( base.source (base.vecteur (0,10,10), \ base.couleur (1,1,1) ) ) s.ajoute_source ( base.source (base.vecteur (10,10,5), \ base.couleur (0.5,0.5,0.5) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,0,12), \ 3, base.couleur (1,0,0) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5) ) ) print s screen = pygame.display.set_mode (s.dim) screen.fill ((255,255,255)) s.construit_image (screen) print "image terminée" scene.attendre_clic ()
image de synthèse, facette
# coding: cp1252 """définition d'une sphère""" import image_synthese_base as base import image_synthese_sphere as obj import image_synthese_phong as scene import image_synthese_scene as scene_p import pygame import math class facette (base.objet): """définit un triangle dans l'espace""" def __init__ (self, a,b,c, couleur): """initialisation""" self.a, self.b, self.c = a,b,c ab = b - a ac = c - a self.vnorm = ab.vectoriel (ac) self.vnorm = self.vnorm.renorme () self.couleur = couleur def intersection_plan (self, r) : """retourne le point d'intersection entre le plan et le rayon r""" if r.direction.scalaire (self.vnorm) == 0 : return None oa = self.a - r.origine l = self.vnorm.scalaire (oa) / self.vnorm.scalaire (r.direction) p = r.origine + r.direction * l return p def point_interieur (self, p) : """dit si un point appartient à l'intérieur du triangle""" pa = self.a - p pb = self.b - p pc = self.c - p theta = pa.angle (pb, self.vnorm) theta += pb.angle (pc, self.vnorm) theta += pc.angle (pa, self.vnorm) theta = abs (theta) if theta >= math.pi * 0.9 : return True else : return False def intersection (self, r) : """retourne le point d'intersection avec le rayon r, retourne None s'il n'y pas d'intersection""" p = self.intersection_plan (r) if p == None : return None if self.point_interieur (p) : return p else : return None def normale (self, p, rayon) : """retourne la normale au point de coordonnée p et connaissant le rayon""" if rayon.direction.scalaire (self.vnorm) < 0 : return self.vnorm else : return - self.vnorm def couleur_point (self, p) : """retourne la couleur au point de coordonnée p""" return self.couleur def __str__ (self): """affichage""" s = "facette --- a : " + str (self.a) s += " b : " + str (self.b) s += " c : " + str (self.c) s += " couleur : " + str (self.couleur) return s class rectangle (facette): """définit un rectangle dans l'espace""" def __init__ (self, a,b,c,d, couleur): """initialisation, si d == None, d est calculé comme étant le symétrique de b par rapport au milieu du segment [ac]""" facette.__init__(self, a,b,c, couleur) if d != None : self.d = d else : i = (a + c) / 2 self.d = b + (i-b) * 2 def point_interieur (self, p) : """dit si un point appartient à l'intérieur du triangle""" pa = self.a - p pb = self.b - p pc = self.c - p pd = self.d - p theta = pa.angle (pb, self.vnorm) theta += pb.angle (pc, self.vnorm) theta += pc.angle (pd, self.vnorm) theta += pd.angle (pa, self.vnorm) theta = abs (theta) if theta >= math.pi * 0.9 : return True else : return False def __str__ (self): """affichage""" s = "rectangle --- a : " + str (self.a) s += " b : " + str (self.b) s += " c : " + str (self.c) s += " d : " + str (self.d) s += " couleur : " + str (self.couleur) return s if __name__ == "__main__" : s = scene.scene_phong (base.repere (), math.pi / 1.5, 400, 300) s.ajoute_source ( base.source (base.vecteur (0,8,8), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_source ( base.source (base.vecteur (10,0,0), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_source ( base.source (base.vecteur (8,8,4.5), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (1,0,5), \ 1, base.couleur (1,0,0) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5) ) ) s.ajoute_objet (facette ( base.vecteur (0,-2.5,6), \ base.vecteur (-2,-2.5,3), \ base.vecteur (1,-3.5,4.5), \ base.couleur (0.2,0.8,0))) s.ajoute_objet (rectangle ( base.vecteur (0,-2.5,6), \ base.vecteur (-2,-2.5,3), \ base.vecteur (-2,2.8,3.5), \ None, \ base.couleur (0,0,1))) print s screen = pygame.display.set_mode (s.dim) screen.fill ((255,255,255)) s.construit_image (screen) print "image terminée" scene_p.attendre_clic ()
image de synthèse, facette image
# coding: cp1252 """définition d'une sphère""" import image_synthese_base as base import image_synthese_sphere as obj import image_synthese_phong as scene import image_synthese_scene as scene_p import image_synthese_facette as facette import pygame import math import psyco class rectangle_image (facette.rectangle): """définit un rectangle contenant un portrait""" def __init__(self, a,b,c,d, nom_image, invertx = False): """initialisation, si d == None, d est calculé comme étant le symétrique de b par rapport au milieu du segment [ac], la texture est une image, si invertx == True, inverse l'image selon l'axe des x""" facette.rectangle.__init__(self, a,b,c,d, base.couleur (0,0,0)) self.image = pygame.image.load (nom_image) self.nom_image = nom_image self.invertx = invertx def __str__ (self): """affichage""" s = "rectangle image --- a : " + str (self.a) s += " b : " + str (self.b) s += " c : " + str (self.c) s += " d : " + str (self.d) s += " image : " + self.nom_image return s def couleur_point (self, p) : """retourne la couleur au point de coordonnée p""" ap = p - self.a ab = self.b - self.a ad = self.d - self.a abn = ab.norme2 () adn = ad.norme2 () x = ab.scalaire (ap) / abn y = ad.scalaire (ap) / adn sx,sy = self.image.get_size () k,l = int (x * sx), int (y * sy) k = min (k, sx-1) l = min (l, sy-1) l = sy - l - 1 if not self.invertx : c = self.image.get_at ((k,l)) else : c = self.image.get_at ((sx-k-1,l)) cl = base.couleur (float (c [0]) / 255, float (c [1]) / 255, float (c [2]) / 255) return cl class sphere_reflet (obj.sphere) : """implémente une sphère avec un reflet""" def __init__ (self, centre, rayon, couleur, reflet): """initialisation, reflet est un coefficient de réflexion""" obj.sphere.__init__ (self, centre, rayon, couleur) self.reflet = reflet def __str__ (self): """affichage""" s = "sphère reflet --- centre : " + str (self.centre) s += " rayon : " + str (self.rayon) s += " couleur : " + str (self.couleur) return s def rayon_reflechi (self, rayon, p) : """retourne le rayon réfléchi au point p de la surface, si aucune, retourne None""" if p == rayon.origine : return None n = self.normale (p, rayon) n = n.renorme () y = n.scalaire (rayon.direction) d = rayon.direction - n * y * 2 r = base.rayon (p, d, rayon.pixel, rayon.couleur * self.reflet) return r if __name__ == "__main__" : psyco.full () s = scene.scene_phong (base.repere (), math.pi / 1.5, 400, 200) s.ajoute_source ( base.source (base.vecteur (0,8,8), \ base.couleur (0.4,0.4,0.4) ) ) s.ajoute_source ( base.source (base.vecteur (10,0,0), \ base.couleur (0.4,0.4,0.4) ) ) s.ajoute_source ( base.source (base.vecteur (8,8,4.5), \ base.couleur (0.4,0.4,0.4) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (3,-4,7), \ 1, base.couleur (1,0,0) ) ) s.ajoute_objet ( sphere_reflet (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5), 0.5 ) ) s.ajoute_objet (rectangle_image ( base.vecteur (8,-3.5,9), \ base.vecteur (2,-3.5,8), \ base.vecteur (2,3.8,8), \ None, \ "bette_davis.png", invertx = True)) s.ajoute_source ( base.source (base.vecteur (7,2,8), \ base.couleur (0.2,0.2,0.2) ) ) s.ajoute_source ( base.source (base.vecteur (12.5,3,5), \ base.couleur (0.2,0.2,0.2) ) ) s.ajoute_source ( base.source (base.vecteur (-12.5,1,6), \ base.couleur (0.2,0.2,0.2) ) ) s.ajoute_objet (facette.rectangle ( base.vecteur (-12.4,0.99,5.9), \ base.vecteur (-12.6,0.99,5.9), \ base.vecteur (-12.6,0.99,6.1), \ None, \ base.couleur (0,0,0))) print s screen = pygame.display.set_mode (s.dim) screen.fill ((255,255,255)) s.construit_image (screen) print "sauvegarde de l'image" im = pygame.display.get_surface() print "image size : ", im.get_size () pygame.image.save (im, "c:\\temp\\image.jpg") pygame.image.save (im, "c:\\temp\\image.tif") pygame.image.save (im, "c:\\temp\\image.bmp") print "image terminée" scene_p.attendre_clic ()
File: usb_window.tex, line 44
import Tkinter as Tk # import du module Tkinter root = Tk.Tk () # création de la fenêtre principale, # c'est toujours la première ligne b = Tk.Button (text = "bouton") # création d'un bouton e = Tk.Entry () # création d'une zone de saisie l = Tk.Label (text = "légende") # création d'une légende b.grid (row = 0, column = 0) # positionnement de b dans la case (0,0) e.grid (row = 1, column = 1) # positionnement de e dans la case (1,1) l.grid (row = 2, column = 2) # positionnement de e dans la case (2,2) root.mainloop () # on lance le programme et l'affichage de la fenêtre
File: usb_window.tex, line 83
import Tkinter as Tk # import du module Tkinter root = Tk.Tk () # création de la fenêtre principale, # c'est toujours la première ligne b = Tk.Button (text = "bouton") # création d'un bouton e = Tk.Entry () # création d'une zone de saisie l = Tk.Label (text = "légende") # création d'une légende b.grid (row = 0, column = 0) # positionnement de b dans la case (0,0) e.grid (row = 1, column = 1) # positionnement de e dans la case (1,1) l.grid (row = 2, column = 2) # positionnement de e dans la case (2,2) # spécifications b.config (width = 30, height = 4) # largeur de 30, hauteur de 4 e.config (width = 50, font = "arial") # largeur de 50, police arial l.config (width = 30, height = 6) # largeur de 30, hauteur de 6 root.mainloop () # on lance le programme et l'affichage de la fenêtre
File: usb_window.tex, line 117
import Tkinter as Tk # import du module Tkinter root = Tk.Tk () # création de la fenêtre principale, # c'est toujours la première ligne b = Tk.Button (text = "bouton") # création d'un bouton e = Tk.Entry () # création d'une zone de saisie l = Tk.Label (text = "légende") # création d'une légende b.grid (row = 0, column = 0) # positionnement de b dans la case (0,0) e.grid (row = 1, column = 1) # positionnement de e dans la case (1,1) l.grid (row = 2, column = 2) # positionnement de e dans la case (2,2) e.insert (0, "texte par défaut") # on insère une chaîne de caractères dans la zone de saisie root.mainloop () # on lance le programme et l'affichage de la fenêtre
File: usb_window.tex, line 138
class copie_usb_window (copie_usb.copie_usb): def fenetre (self) : # ici, création de la fenêtre graphique # ...
File: usb_window.tex, line 148
# programme principal 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$" c = copie_usb_window (ch1, ch2, filtre_accept, filtre_refuse) c.fenetre () # affiche la fenêtre graphique
File: usb_window.tex, line 166
import Tkinter as Tk # import du module Tkinter root = Tk.Tk () # création de la fenêtre principale, # c'est toujours la première ligne b = Tk.Button (text = "bouton") # création d'un bouton e = Tk.Entry () # création d'une zone de saisie l = Tk.Label (text = "légende") # création d'une légende b.grid (row = 0, column = 0) # positionnement de b dans la case (0,0) e.grid (row = 1, column = 1) # positionnement de e dans la case (1,1) l.grid (row = 2, column = 2) # positionnement de e dans la case (2,2) # fonction à exécuter si le bouton b est pressé def affichage_bouton (): print "chaîne affichée si le bouton est pressé" # on affecte la fonction affichage_bouton au bouton b b.config (command = affichage_bouton) root.mainloop () # on lance le programme et l'affichage de la fenêtre
File: usb_window.tex, line 192
b.config (command = root.destroy)
File: usb_window.tex, line 215
s = e.get () # on récupère le contenu de la zone de saisie i = len (s) # i est égal à la longueur de la chaîne s e.delete (0, i) # on vide la zone de saisie s = s.upper () # mise en majuscules e.insert (0,s) # on remplace le contenu de la zone de saisie
File: usb_window.tex, line 233
import selection_file fs = selection_file.FileSelection (titre, "c:\\temp", file = False) r = fs.run () print r # chaîne de caractères ou None
sélection d'un fichier
# coding: cp1252 """module contenant une boîte de dialogue permettant de sélectionner un fichier ou un répertoire, il utilise l'interface Tkinter""" import Tkinter as Tk import os.path import os class FileSelection (object) : """classe permettant de sélectionner un fichier ou un répertoire à travers une boîte de dialogue""" def __init__ (self, titre = "Sélection de fichier", \ chemin = None, file = True, exist= True) : """initialise la classe @param titre titre de la fenêtre @param chemin fichier ou répertoire par défaut @param file True : fichier, False : répertoire @param exist True : le répertoire ou le fichier sélectionné doit exister""" self.titre = titre self.chemin = chemin self.file = file self.exist = exist if self.chemin == None : self.chemin = os.getcwd () def get_list (self) : """retourne la liste des fichiers et des répertoires (2 listes), répertoires seulement et [] si self.file == False""" if os.path.isdir (self.chemin) : list = os.listdir (self.chemin) else : ch,fi = os.path.split (self.chemin) list = os.listdir (ch) lifile = [] lidir = [] for l in list : if os.path.isdir (self.chemin + "\\" + l) : lidir.append (l) elif self.file : lifile.append (l) lidir.sort () lifile.sort () return lidir, lifile def run (self) : """lance la boîte de dialogue et retourne la chaîne sélectionnée""" top = Tk.Toplevel () top.wm_title (self.titre) fli = Tk.Frame (top) scrollbar = Tk.Scrollbar (fli) li = Tk.Listbox (fli, width = 120, height = 15, \ yscrollcommand = scrollbar.set) scrollbar.config (command = li.yview) ch = Tk.Entry (top, width = 120) f = Tk.Frame (top) prec = Tk.Button (f, text = "Précédent") suiv = Tk.Button (f, text = "Entre") annul = Tk.Button (f, text = "Annuler") ok = Tk.Button (f, text = "Ok") prec.grid (column = 0, row = 0) suiv.grid (column = 1, row = 0) annul.grid (column = 3, row = 0) ok.grid (column = 4, row = 0) li.pack (side = Tk.LEFT) scrollbar.pack(side = Tk.RIGHT, fill = Tk.Y) fli.pack () ch.pack () f.pack () def update_chemin () : """mise à jour du chemin dans la boîte de dialogue""" s = ch.get () ch.delete (0, len (s)) ch.insert (0, self.chemin) def update_list () : """mise à jour de la liste des fichiers et répertoires à partir de la chaîne dans la boîte de dialogue""" self.chemin = ch.get () lidir, lifile = self.get_list () li.delete (0, Tk.END) if len (lidir) > 0 : for l in lidir : li.insert (Tk.END, "+ "+ l) if len (lifile) > 0 : for l in lifile : li.insert (Tk.END, " "+ l) def precedent () : """passe au répertoire précédent""" if os.path.isdir (self.chemin) : ch, last = os.path.split (self.chemin) self.chemin = ch else : ch, last = os.path.split (self.chemin) ch, last = os.path.split (ch) self.chemin = ch update_chemin () update_list () def suivant () : """rentre dans un répertoire""" sel = ch.get () if os.path.isdir (sel) : self.chemin = sel update_chemin () update_list () def update_sel () : """mise à jour de la chaîne de caractères dans la boîte de dialogue à partir de la ligne sélectionnée dans la liste""" li.after (200, update_sel) sel = li.curselection () if len (sel) == 1 : t = li.get (sel [0]) c = self.chemin + "\\" + t [2:len (t)] c = c.replace ("\\\\", "\\") s = ch.get () ch.delete (0, len (s)) ch.insert (0, c) def annuler () : """annule la recherche""" self.resultat = False top.destroy () top.quit () def accepter () : """accepte le résultat""" self.resultat = True self.chemin = ch.get () top.destroy () top.quit () prec.config (command = precedent) suiv.config (command = suivant) annul.config (command = annuler) ok.config (command = accepter) update_chemin () update_list () update_sel () ch.focus_set () top.mainloop () if self.resultat : return self.chemin else : return None if __name__ == "__main__" : root = Tk.Tk () def run () : r = FileSelection ("sélection d'un fichier", "c:\\") s = r.run () print "fichier sélectionné ", s Tk.Button (text = "fenêtre", command = run).pack () Tk.Button (text = "fermer", command = root.destroy).pack () root.mainloop ()
copie de fichiers avec interface graphique
# coding: cp1252 """copie de fichiers sur une clé USB, interface fenêtrée""" import Tkinter as Tk # pour la fenêtre import selection_file # pour rechercher un répertoire import copie_usb # version sans fenêtre import re # pour les expressions régulières class copie_usb_window (copie_usb.copie_usb): """recopie des fichiers sur une clé USB avec une fenêtre graphique""" def chercher (self, s, titre) : """modifie un répertoire""" fs = selection_file.FileSelection (titre, chemin = s, file = False) r = fs.run () if r != None : return r else : return s def fenetre (self) : """change les paramètres de la classe par l'intermédiaire d'une fenêtre""" # définition de la fenêtre root = Tk.Tk () source = Tk.Entry (width = 100) source_label = Tk.Label (text = "répertoire source") source_label.grid (column = 0, row = 0) source.grid (column = 1, row = 0) dest = Tk.Entry (width = 100) dest_label = Tk.Label (text = "répertoire destination") dest_label.grid (column = 0, row = 1) dest.grid (column = 1, row = 1) filtre_accept = Tk.Entry (width = 100) accept_label = Tk.Label (text = "filtre pour les fichiers acceptés") filtre_accept.grid (column = 1, row = 2) accept_label.grid (column = 0, row = 2) filtre_refuse = Tk.Entry (width = 100) refuse_label = Tk.Label (text = "filtre pour les fichiers refusés") filtre_refuse.grid (column = 1, row = 3) refuse_label.grid (column = 0, row = 3) def chercher_source () : s = source.get () i = len (s) s = self.chercher (s, "répertoire source") source.delete (0, i) source.insert (0,s) def chercher_dest () : s = dest.get () i = len (s) s = self.chercher (s, "répertoire source") dest.delete (0, i) dest.insert (0,s) def copier () : self.ch1 = source.get () self.ch2 = dest.get () self.accept = re.compile (filtre_accept.get ()) self.refuse = re.compile (filtre_refuse.get ()) self.copie () brepsource = Tk.Button (text = "chercher", command = chercher_source) brepdest = Tk.Button (text = "chercher", command = chercher_dest) brepsource.grid (column = 2, row = 0) brepdest.grid (column = 2, row = 1) bfermer = Tk.Button (text = "Fermer", command = root.destroy) bfermer.grid (column = 2, row = 4) bcopier = Tk.Button (text = "Copier", command = copier) bcopier.grid (column = 2, row = 3) root.wm_title ("copie de fichiers vers une clé USB") source.insert (0, self.ch1) dest.insert (0, self.ch2) filtre_accept.insert (0, self.accept.pattern) filtre_refuse.insert (0, self.refuse.pattern) root.mainloop () 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_window (ch1, ch2, filtre_accept, filtre_refuse) c.fenetre ()
File: usb_window_save.tex, line 15
# ouverture fichier essai.txt en mode écriture f = open ("essai.txt", "w") # écriture d'une chaîne de caractères dans le fichier f.write ("première ligne") # passage à la ligne f.write ("\n") # fermeture du fichier f.close ()
File: usb_window_save.tex, line 30
# ouverture fichier essai.txt en mode lecture f = open ("essai.txt", "r") # lecture de la première ligne du fichier s = f.readline () # on enlève de la chaîne de caractères s le symbole de fin de ligne s = s.replace ("\n", "") # affichage de s print s # fermeture du fichier f.close ()
copie de fichiers, sauvergarde des paramètres
# coding: cp1252 """copie de fichiers sur une clé USB, interface fenêtrée, enregistrement des paramètres précédents""" import copie_usb_window # version avec fenêtre import os.path # pour détecter l'existence d'un fichier import re # pour les expressions régulières class copie_usb_window_save (copie_usb_window.copie_usb_window): """recopie des fichiers sur une clé USB avec une fenêtre graphique, et enregistrement des précédents paramètres""" def ecrire_parametre (self, txt) : """écriture des paramètres dans le fichier txt""" # ouverture du fichier en mode écriture f = open (txt, "w") f.write (self.ch1) f.write ("\n") f.write (self.ch2) f.write ("\n") f.write (self.accept.pattern) f.write ("\n") f.write (self.refuse.pattern) f.write ("\n") f.close () def lire_parametre (self, txt) : """relecture des paramètres écrits dans le fichier txt s'il existe""" if os.path.exists (txt) : f = open (txt, "r") s = f.readline () s = s.replace ("\n", "") self.ch1 = s s = f.readline () s = s.replace ("\n", "") self.ch2 = s s = f.readline () s = s.replace ("\n", "") self.accept = re.compile (s) s = f.readline () s = s.replace ("\n", "") self.refuse = re.compile (s) f.close () def fenetre (self) : """méthode fenêtre surchargée pour lire les derniers paramètres et enregistrer les nouveaux""" # première étape, lire les précédents paramètres self.lire_parametre ("copie_usb_window_save.txt") # seconde étape, appel de la méthode précédente copie_usb_window.copie_usb_window.fenetre (self) # troisième étape, écriture des paramètres self.ecrire_parametre ("copie_usb_window_save.txt") 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_window_save (ch1, ch2, filtre_accept, filtre_refuse) c.fenetre ()
File: debutant_common_part.tex, line 4
# coding : latin-1 nom_prenom = "Xavier Dupré"
File: debutant_common_part.tex, line 11
i = 3 # i=3 mais on fait référence au 4ème caractère valeur = ord ( nom_prenom [i] )
File: debutant_common_part.tex, line 23
def somme_caractere (nom_prenom) : ... return ...
File: debutant_common_part.tex, line 31
s = somme_caractere ("Xavier Dupre") % 200 url = "http://www.xavierdupre.fr/enseignement/tutoriels_data/tutoriel_%d.py" % s print url
File: debutant_common_part.tex, line 39
from tutoriel_99.py import *
File: debutant_tri.tex, line 16
0.56 # position i --> tri [i] 0.43 # position i+1 --> tri [i+1]
File: debutant_tri.tex, line 23
def permutation ( tri, ...) : ...
File: debutant_tri.tex, line 30
tri = .... for i in xrange (0, len (n)-1) : permutation (tri, ...)
File: debutant_tri.tex, line 40
tri = .... for i in xrange (0, len (n)-1) : permutation (tri, ...) for i in xrange (0, len (n)-1) : permutation (tri, ...)
File: debutant_tri.tex, line 50
def tri_bulle (tri) : ... tri_bulle (tri) for el in tri : print el
File: debutant_tri.tex, line 63
m = len(tri)/2 tri1 = tri [0:m] tri2 = tri [m:len(tri)] tri_bulle(tri1) tri_bulle(tri2)
File: debutant_tri.tex, line 79
def fusion (tri1, tri2) : res = [] i1 = 0 i2 = 0 while i1 + i2 < len (tri1) + len(tri2) : if tri1 [i1] < tri2 [i2] : res.append ( tri1 [i1] ) ... else : res.append ( tri2 [i2] ) ... return res
File: debutant_tri.tex, line 102
m = len(tri)/4 tri1 = tri [0:m] tri2 = tri [m:2*m] tri3 = tri [2*m:3*m] tri4 = tri [3*m:len(tri)] tri_bulle(tri1) tri_bulle(tri2) tri_bulle(tri3) tri_bulle(tri4) ...
déterminer la taille des poissons
# coding: cp1252 import poisson #import scipy.optimize.lbfgsb as Opt # optimisation import bfgs # optimisation import numpy as Num # pour les tableaux import psyco def fonction_bfgs (x, cl, l) : """fonction retournant l'opposé de la log-vraisemblance de l'instance cl, fonction à minimiser""" cl.set (x) f = - cl.log_densite_list (l) #print f, "\t", x return f def fonction_derivee_bfgs (x, cl, l) : """fonction retournant l'opposé de la log-vraisemblance de l'instance cl, fonction à minimiser""" cl.set (x) f = cl.gradient_total (l) return - Num.array (f) class poisson_loi_bfgs (poisson.poisson_loi) : """loi de distribution de la taille des poissons, optimisation à l'aide de l'algorithme BFGS""" def __init__(self, alpha = 0.5, mm = 1, sm = 1, mf = 1, sf = 1) : """initialisation des paramètres de la loi""" poisson.poisson_loi.__init__(self, alpha, mm, sm, mf, sf) def set (self, x) : """initialisation avec un tableau""" self.alpha = x [0] self.mm = x [1] self.sm = abs (x [2]) self.mf = x [3] self.sf = abs (x [4]) def get (self) : """retourne un tableau contenant les paramètres""" return Num.array ( (self.alpha, self.mm, self.sm, self.mf, self.sf) ) def __str__(self) : """affichage""" s = "classe poisson_loi BFGS\n" s += "alpha = " + str (self.alpha) + "\n" s += "moyenne male = " + str (self.mm) + "\n" s += "sigma male = " + str (self.sm) + "\n" s += "moyenne femelle = " + str (self.mf) + "\n" s += "sigma femelle = " + str (self.sf) + "\n" return s def optimisation (self, l, epsilon = 0.001) : """recherche du maximum de la fonction f""" self.init (l) x0 = self.get () print x0 opt = bfgs.optimisation_bfgs (fonction_bfgs, \ fonction_derivee_bfgs, \ args = (self, l)) x = opt.optimise (x0) #x = bfgs.Opt.fmin_l_bfgs_b ( fonction_bfgs, \ # x0, \ # fonction_derivee_bfgs, \ # args = (self, l)) self.set (x) print "optimisation terminée" print "valeur maximale : ", self.log_densite_list (l) print "message ", d if __name__ == "__main__" : psyco.full () # création d'une instance de la classe cl = poisson.poisson_loi (0.55, 0.40, 0.020, 0.35, 0.015) print cl # affichage #cl.trace_densite () # courbe densité l = cl.generate (10000) cl2 = poisson_loi_bfgs () print "-----------------------------------------------------------" print "log densité maximale ", cl.log_densite_list (l) (a,b,c,d,e) = cl.gradient_total (l) print "gradient idéal ", (a,b,c,d,e) print "-----------------------------------------------------------" (a,b,c,d,e) = cl2.gradient_total (l) print "gradient avant", (a,b,c,d,e) cl2.optimisation (l) (a,b,c,d,e) = cl2.gradient_total (l) print "gradient après ", (a,b,c,d,e) print "-----------------------------------------------------------" print cl2 cl2.trace_densite (cl) print "log vraisemblance : ", cl2.log_densite_list (l)
File: debutant_common_part.tex, line 4
# coding : latin-1 nom_prenom = "Xavier Dupré"
File: debutant_common_part.tex, line 11
i = 3 # i=3 mais on fait référence au 4ème caractère valeur = ord ( nom_prenom [i] )
File: debutant_common_part.tex, line 23
def somme_caractere (nom_prenom) : ... return ...
File: debutant_common_part.tex, line 31
s = somme_caractere ("Xavier Dupre") % 200 url = "http://www.xavierdupre.fr/enseignement/tutoriels_data/tutoriel_%d.py" % s print url
File: debutant_common_part.tex, line 39
from tutoriel_99.py import *
File: debutant_liste.tex, line 16
(1, 2) > (0,9) (1, 2) > (1,1) (1, 2) == (1, 2) (1, 2) < (2, 0)
File: debutant_liste.tex, line 28
[ 4.6, 6.4, 4.3, 7.8 ]
File: debutant_liste.tex, line 37
[ (4.6, 1), (6.4, 2), (4.3, 3), (7.8, 4) ]
File: debutant_liste.tex, line 49
def ajoute_position (tableau) : ... return matrice
File: debutant_liste.tex, line 66
[ 4.6, [ "rouge", 6.4, "bleu", 4.3, "rouge", 7.8 ] "bleu" ]
File: debutant_liste.tex, line 76
[ 4.3, [ "rouge", 4.6, "rouge", 6.4, "bleu", 7.8 ] "bleu" ]
File: debutant_liste.tex, line 88
def rearrange_attribut (attribut, mat) : ... return nouveau_attribut
File: debutant_liste.tex, line 97
permutation = [ m[1] for m in mat ] nouveau = [ -1 for i in permutation ] for i in xrange (0, len (permutation)) : nouveau [ permutation [i] ] = i
File: debutant_liste.tex, line 113
import numpy # import du module numpy mat = numpy.array (pmat) # on transforme une liste en liste en matrice format numpy l, v = numpy.linalg.eig(mat) # calcul des valeurs propres et vecteurs propres pl = list (l) # on tranforme un vecteur numpy en liste pv = list (v) # on tranforme une matrice numpy en liste
File: debutant_liste.tex, line 126
l = range (1, 100) # soit la liste [ 1, 2, 3, ..., 99 ]
File: debutant_liste.tex, line 134
l = [ -3, -3, -3, -3, +3, +3, +3, +3, -2, ... ]
File: debutant_liste.tex, line 140
d = { -3:4, +3:4, -2:10, +2:15, ... }
déterminer la taille des poissons
# coding: cp1252 import poisson #import scipy.optimize.lbfgsb as Opt # optimisation import bfgs # optimisation import numpy as Num # pour les tableaux import psyco def fonction_bfgs (x, cl, l) : """fonction retournant l'opposé de la log-vraisemblance de l'instance cl, fonction à minimiser""" cl.set (x) f = - cl.log_densite_list (l) #print f, "\t", x return f def fonction_derivee_bfgs (x, cl, l) : """fonction retournant l'opposé de la log-vraisemblance de l'instance cl, fonction à minimiser""" cl.set (x) f = cl.gradient_total (l) return - Num.array (f) class poisson_loi_bfgs (poisson.poisson_loi) : """loi de distribution de la taille des poissons, optimisation à l'aide de l'algorithme BFGS""" def __init__(self, alpha = 0.5, mm = 1, sm = 1, mf = 1, sf = 1) : """initialisation des paramètres de la loi""" poisson.poisson_loi.__init__(self, alpha, mm, sm, mf, sf) def set (self, x) : """initialisation avec un tableau""" self.alpha = x [0] self.mm = x [1] self.sm = abs (x [2]) self.mf = x [3] self.sf = abs (x [4]) def get (self) : """retourne un tableau contenant les paramètres""" return Num.array ( (self.alpha, self.mm, self.sm, self.mf, self.sf) ) def __str__(self) : """affichage""" s = "classe poisson_loi BFGS\n" s += "alpha = " + str (self.alpha) + "\n" s += "moyenne male = " + str (self.mm) + "\n" s += "sigma male = " + str (self.sm) + "\n" s += "moyenne femelle = " + str (self.mf) + "\n" s += "sigma femelle = " + str (self.sf) + "\n" return s def optimisation (self, l, epsilon = 0.001) : """recherche du maximum de la fonction f""" self.init (l) x0 = self.get () print x0 opt = bfgs.optimisation_bfgs (fonction_bfgs, \ fonction_derivee_bfgs, \ args = (self, l)) x = opt.optimise (x0) #x = bfgs.Opt.fmin_l_bfgs_b ( fonction_bfgs, \ # x0, \ # fonction_derivee_bfgs, \ # args = (self, l)) self.set (x) print "optimisation terminée" print "valeur maximale : ", self.log_densite_list (l) print "message ", d if __name__ == "__main__" : psyco.full () # création d'une instance de la classe cl = poisson.poisson_loi (0.55, 0.40, 0.020, 0.35, 0.015) print cl # affichage #cl.trace_densite () # courbe densité l = cl.generate (10000) cl2 = poisson_loi_bfgs () print "-----------------------------------------------------------" print "log densité maximale ", cl.log_densite_list (l) (a,b,c,d,e) = cl.gradient_total (l) print "gradient idéal ", (a,b,c,d,e) print "-----------------------------------------------------------" (a,b,c,d,e) = cl2.gradient_total (l) print "gradient avant", (a,b,c,d,e) cl2.optimisation (l) (a,b,c,d,e) = cl2.gradient_total (l) print "gradient après ", (a,b,c,d,e) print "-----------------------------------------------------------" print cl2 cl2.trace_densite (cl) print "log vraisemblance : ", cl2.log_densite_list (l)
File: debutant_common_part.tex, line 4
# coding : latin-1 nom_prenom = "Xavier Dupré"
File: debutant_common_part.tex, line 11
i = 3 # i=3 mais on fait référence au 4ème caractère valeur = ord ( nom_prenom [i] )
File: debutant_common_part.tex, line 23
def somme_caractere (nom_prenom) : ... return ...
File: debutant_common_part.tex, line 31
s = somme_caractere ("Xavier Dupre") % 200 url = "http://www.xavierdupre.fr/enseignement/tutoriels_data/tutoriel_%d.py" % s print url
File: debutant_common_part.tex, line 39
from tutoriel_99.py import *
File: confirme_graph.tex, line 43
class MonGraphe : def __init__ (self, num, valeur) : self.valeur = valeur self.num = num self.arcs = [] # liste déléments MonGraphe
File: confirme_graph.tex, line 56
def ConstruireMonGraphe (noeuds, arcs) : ... return mongraphe
File: confirme_graph.tex, line 65
class MonGraphe : def NombreTotalNoeud (self) : r = 1 for a in self.arcs : r += a.NombreTotalNoeud() return r
utilisation de Graphviz
# coding:latin-1 def import_Graphviz () : import os, urllib,struct files = [ "_graphviz_draw.exe"] if not os.path.exists (files[-1]) : # on télécharge les fichiers nécessaires d'abord for f in files : print "téléchargement de ", f url = "http://www.xavierdupre.fr/enseignement/tutoriel_python/graphviz/" + f u = urllib.urlopen (url, "rb") all = u.read () if "404 Not Found" in all : raise Exception ("fichier introuvable") u.close () u = open (f, "wb") u.write ( struct.pack ("c"*len(all), *all)) u.close() if not os.path.exists (files[-1]) : raise Exception ("mauvais téléchargement") return files def drawDiGraph (text, image) : f = open ("graph.gv", "w") f.write ( text ) f.close () files = import_Graphviz () cmd = "%s . graph.gv %s png neato" % (files[-1], image) import os os.system (cmd) def drawGraph (edges, image) : """ dessine un graph en utilisant Graphviz (http://www.graphviz.org/ edges = [ (1,2), (3,4), (1,3), ... ] , liste d'arcs image = bom d'image (format png) """ li = [ "digraph{" ] for i,j in edges : li.append ( "%d -> %d ;" % (i,j) ) li.append ("};") text = "\n".join(li) drawDiGraph(text, image) def drawGraphEdgesVertices (vertices, edges, image) : """ dessine un graph en utilisant Graphviz (http://www.graphviz.org/ edges = [ (1,2, label, couleur), (3,4), (1,3), ... ] , liste d'arcs vertices = [ (1, label, couleur), (2), ... ] , liste de noeuds image = bom d'image (format png) """ memovertex = { } for v in vertices : if len(v) == 1 : memovertex[v[0]] = None else : memovertex[v[0]] = v[1:] for edge in edges : i,j = edge[:2] if i not in memovertex : memovertex[i] = None if j not in memovertex : memovertex[j] = None li = [ "digraph{" ] for k,v in memovertex.iteritems() : if v == None : li.append("%s ;" % k) elif len(v) == 1 : li.append ("\"%s\" [label=\"%s\"];" % (k, v[0])) elif len(v) == 2 : li.append ("\"%s\" [label=\"%s\",fillcolor=%s,color=%s];" % (k, v[0], v[1], v[1])) else : raise Exception("unable to understand " + str(v)) for edge in edges : i,j = edge[:2] if len (edge) == 2 : li.append ( "\"%s\" -> \"%s\" ;" % (i,j) ) elif len (edge) == 3 : li.append ( "\"%s\" -> \"%s\" [label=\"%s\"];" % (i,j,edge[2]) ) elif len (edge) == 4 : li.append ( "\"%s\" -> \"%s\" [label=\"%s\",color=%s];" % (i,j,edge[2],edge[3]) ) else : raise Exception("unable to understand " + str(edge)) li.append ("};") text = "\n".join(li) drawDiGraph(text, image) if __name__ == "__main__" : drawGraph ([(1,2),(3,4), (1,3)], "image.png") drawGraphEdgesVertices ([(1,"eee","red")], [(1,2,"blue"),(3,4), (1,3)], "image2.png")
recherche du nom
#coding:latin-1 ########## Question 1 ################ nom_prenom= "illotevtelo ChMa" i=3 valeur= ord (nom_prenom [i]) print valeur print ord('p') ########## Question 2 ################ r=0 for i in xrange(0,len(nom_prenom)): r += ord( nom_prenom [i] ) print r ########## Question 3 ################ def somme_caractere (nom_prenom): r=0 for i in xrange(0,len(nom_prenom)): r += ord( nom_prenom [i] ) return r print somme_caractere (nom_prenom) ########## Question 4 ################ s = somme_caractere(nom_prenom) % 200 url = "http://www.xavierdupre.fr/enseignement/tutoriels_data/tutoriel_%d.py" % s print url
clustering dans un graphe
#coding:latin-1 from tutoriel_119 import * # tutoriel_graphe noeuds = {0: 'fr\xe9quemment.', 1: 'je', 2: 'dit', 3: '\xeatre', 4: 'Code",', 5: 'incident', 6: 'dernier', 7: 'de', 8: '\xe0', 9: 'go\xfbt', 10: 'celui-l\xe0.', 11: 'pour', 12: 'plus', 13: 'prendre', 14: 'commenter', 15: '\xe9quilibr\xe9', 16: 'inconsciemment', 17: ':', 18: 'vous', 19: 'pr\xe9f\xe8re', 20: 'moyen', 21: 'doute,', 22: 'de', 23: 'les', 24: 'les', 25: "l'ann\xe9e", 26: 'se', 27: "c'est", 28: 'je', 29: 'am\xe9ricain.', 30: 'de', 31: 'raconter', 32: 'livre,', 33: 'se', 34: 'sarcasmes', 35: 'derni\xe8re', 36: 'ce', 37: '\xe0', 38: 'changent,', 39: 'une', 40: 'soutient', 41: 'sens', 42: 'est', 43: 'Minelli,', 44: 'est', 45: "n'ai", 46: 'est', 47: 'une', 48: '\xe7a,', 49: 'pour'} arcs = {(13, 22): None, (0, 7): None, (24, 4): None, (40, 41): None, (2, 22): None, (1, 6): None, (32, 31): None, (42, 35): None, (44, 34): None, (8, 24): None, (6, 7): None, (37, 48): None, (19, 14): None, (25, 26): None, (16, 22): None, (30, 42): None, (29, 34): None, (5, 3): None, (18, 20): None, (37, 41): None, (44, 39): None, (25, 38): None, (31, 38): None, (4, 16): None, (11, 0): None, (10, 24): None, (7, 5): None, (47, 40): None, (17, 20): None, (27, 40): None, (15, 24): None, (15, 1): None, (29, 37): None, (2, 17): None, (41, 45): None, (40, 35): None, (13, 23): None, (34, 41): None, (1, 12): None, (37, 44): None, (5, 14): None, (10, 14): None, (11, 15): None, (15, 16): None, (30, 45): None, (11, 16): None, (30, 32): None, (20, 3): None, (3, 11): None, (42, 47): None, (2, 12): None, (5, 1): None, (30, 43): None, (14, 22): None, (0, 21): None, (49, 41): None, (26, 29): None, (31, 47): None, (25, 43): None, (22, 7): None, (44, 46): None, (26, 33): None, (27, 44): None, (16, 23): None, (4, 14): None, (46, 27): None, (0, 9): None, (1, 19): None, (7, 18): None, (19, 23): None, (29, 46): None, (27, 31): None, (0, 8): None, (23, 24): None, (4, 11): None, (2, 7): None, (43, 39): None, (4, 6): None, (25, 37): None, (9, 23): None, (7, 4): None, (6, 20): None, (5, 20): None, (16, 20): None, (32, 42): None, (32, 39): None, (3, 15): None, (1, 3): None, (28, 29): None, (10, 15): None, (8, 19): None, (45, 48): None, (11, 14): None, (31, 30): None, (1, 20): None, (17, 15): None, (4, 20): None, (29, 40): None, (42, 44): None, (37, 46): None, (23, 15): None, (26, 46): None, (14, 23): None, (29, 48): None, (11, 13): None, (0, 22): None, (6, 18): None, (30, 47): None, (1, 23): None, (36, 46): None, (23, 20): None, (38, 46): None, (43, 49): None, (49, 38): None, (12, 0): None, (11, 8): None, (29, 32): None, (34, 36): None, (1, 18): None, (31, 45): None, (13, 18): None, (33, 42): None, (24, 13): None, (21, 7): None, (33, 31): None, (42, 49): None, (4, 10): None, (38, 43): None, (9, 22): None, (15, 31): None, (27, 42): None, (16, 21): None, (47, 39): None, (13, 8): None, (12, 16): None, (24, 0): None, (18, 19): None, (3, 8): None, (5, 12): None, (3, 14): None, (36, 31): None, (47, 26): None, (30, 38): None, (29, 38): None, (1, 24): None, (41, 46): None, (18, 24): None, (42, 45): None, (37, 45): None, (44, 29): None, (33, 47): None, (19, 20): None, (17, 4): None, (7, 9): None, (26, 27): None, (30, 35): None, (32, 37): None, (22, 5): None, (36, 45): None, (43, 26): None, (2, 15): None} points = [(0.95267535699124162, 0.82560629131856578), (0.29648364156865914, 0.18050600487154633), (0.79996985136162935, 0.57893660071459829), (0.085376952582970955, 0.031034879282891392), (0.016348760649931293, 0.50115702327334655), (0.74771613576024176, 0.44138768803286821), (0.5492358527201977, 0.81850752511271008), (0.95542745148916108, 0.17816204660413593), (0.99050031891464319, 0.24851774111600722), (0.59460011551737468, 0.37389676235300828), (0.18654793854244078, 0.6840075536088509), (0.14657352787860223, 0.99366919091486383), (0.20017263306996014, 0.36275912353643147), (0.94074045424419872, 0.0072132133182595259), (0.61740384464135112, 0.43686790737625958), (0.66539931762342697, 0.55679917050743688), (0.45015730018055056, 0.31099714183225291), (0.12415928874693283, 0.71076075162623464), (0.68924309228021652, 0.31141865520722745), (0.10516400088906552, 0.58731899757629535), (0.12188375680883579, 0.51881747990793747), (0.07558429625479568, 0.043497856810040703), (0.13026049803968498, 0.54683395827968562), (0.52712532997481876, 0.17157989187856604), (0.45114145954948592, 0.70617762309961618), (0.56406777662890695, 0.71132385696741118), (0.55461691931730994, 0.29547405922511316), (0.099441144430514661, 0.36779227191569108), (0.49402620743521286, 0.35145024932175195), (0.63613038961532231, 0.51163660427562563), (0.55581345719517494, 0.071142652579506804), (0.33592381455203424, 0.42007024413872029), (0.40672043722017814, 0.056365679688573422), (0.62027382936709818, 0.35952751815993511), (0.71720130482031286, 0.92410962623683579), (0.32551467496845776, 0.065920384323213677), (0.84569564126604313, 0.23703980163205995), (0.42807674751831126, 0.054150904243620013), (0.64062636462843214, 0.15042491134125857), (0.48100807171343629, 0.14134222101625216), (0.40180636763784205, 0.99474182532249189), (0.27948653677901758, 0.71630115956590457), (0.15535336634912322, 0.34851408508671899), (0.45298028214932573, 0.32066296654826165), (0.44862985083939377, 0.30547670650187053), (0.029256933006530872, 0.73724241682736447), (0.15622132444455183, 0.21521612682099767), (0.11690710489512957, 0.4786251875596268), (0.50738236737590658, 0.51986175679349422), (0.55108314047038542, 0.57095630870069658), (0.73093092106169111, -3.9925338781977224), (1.9199614425637721, -4.9962543381481126), (4.0439915887357065, 3.8498484270922391), (-3.40709035308348, 0.39775864157910079), (4.0730819072938669, 3.2890212795827303), (-3.7742136951993408, -3.1123669548128072), (-4.9860229704641412, -0.33930202390130337), (1.1480453006246507, 5.3709879064645794), (4.0440299719273201, -3.1359324647302684), (-0.44887083769379277, -3.3799423541322735), (3.4398670515279557, 3.8334059332033497), (0.76952265995298075, -4.0625181910119244), (1.6956587062968544, -3.3744478144946441), (-0.10396158258453836, -5.0743258686216315), (-3.9534018707169429, -2.5038913982934172), (4.7680866941585229, 0.81715016175569477), (-0.42862569608862167, 5.8432707351932933), (1.518614059709694, 5.1977766227862325), (-1.1242218799970169, -4.6179402103967639), (-1.4258244150043791, -4.1685616113702944), (1.9409162750433124, -4.7404641006556236), (1.1435464790122816, 4.0279467283359454), (0.38121779630834041, 3.8382568106291739), (4.2044759346207483, -2.3148006282830065), (-5.7363326915308024, -2.9192244608795028), (3.2495073925554618, -4.0573216044653897), (0.32372336455076411, -3.9912555547264752), (-0.90791219358485331, 3.9787696565918154), (3.6256474234954226, 4.8226560186800373), (-3.8963553456339688, 1.1198210722224913), (3.3604780169461765, -3.5642594588211649), (1.687058366889852, -6.210927082177248), (-5.0088975511144023, 2.2360658464462815), (0.37106204009035448, -4.4457015129313913), (3.9649514458322459, -3.3070905420671415), (-1.8819631023110905, 3.3200252718097296), (-2.6843465848858159, 2.0533835595291654), (-3.2557819026437267, 1.5973998477974416), (4.6885709328444847, -1.2173870239662024), (2.404962474396116, 5.5064199228937731), (4.1216693489758471, -3.5030595862817462), (1.0944087405444316, 4.9129405674584641), (-5.9103174847844873, 1.9114254460109923), (-4.132188963311493, 1.4022043343548183), (-1.1020149832348243, 3.5636367949517318), (2.664931398644931, -4.3052248468766985), (-3.5601955924295829, -1.9443401692133171), (-4.201585463270586, -3.8511178493837335), (-4.5260781255083566, -1.3173319537940902), (-3.5520622021177473, 4.5357043246405819), (-2.3077280555810677, -2.6714981243721976), (-1.8571447222954365, -1.9519861881351419), (-3.2255068414551546, 3.1795664716329615), (-4.4482213664716559, -4.2185611163633974), (-3.9997974009755564, -2.5517555288239171), (-4.8699798695561576, -3.9692238738753982), (3.3151561188844925, -0.55206233883637235), (3.9438026346904129, -3.0304323218823326), (-4.7094073035463007, -3.8287671974811586), (2.1914918183775023, 1.1556602211075755), (2.239822051268634, -5.2980602701664683), (2.3595979948449535, -0.3398618231136934), (3.4516151992690514, -1.4120593478012067), (-4.1621980502057756, 1.8975419998882086), (2.7428097192268956, -0.30002875549521779), (4.3605014242243074, 1.3503549800798575), (5.2613590378052635, 2.1022774759999576), (3.6367225250843793, -3.1716591169498045), (4.6726118996244095, -1.2790433464904203), (4.9058044780104595, -2.1364525616895911), (0.069636008996937004, -2.5735387007511115), (-2.3129926401371748, -2.8967224927343578), (4.8127318966269534, -1.0852430298581375), (-4.3260746865404673, -1.5492672712798914), (2.302625177338677, -3.7148086473256443), (5.1338859559296068, 2.9533293912327001), (1.3625934799042121, 3.1298364974715676), (-4.5114122266499832, -3.3542526117819542), (-4.326594346630996, -1.7921498252383388), (2.7026843300795145, -0.014530189102330074), (-2.722907308307938, 2.7453464789348763), (-5.083591175043483, -0.30615128717542933), (-4.4586660147794506, -5.0971750441048398), (-2.2315188766141807, 1.9005390242378848), (-5.987594485873192, 2.4785543875512492), (1.1221786043911814, -4.0861810554465618), (4.1750084684753421, 1.6969862360709904), (3.6859080775408026, 6.1851460026850944), (2.9214278188299945, -2.9093405748617487), (3.7000980748880048, 3.1807433447418449), (-3.3630507245753694, -4.8588967519552382), (-0.26921474742305929, 4.9015232652416945), (3.1407992489793077, 2.501535088460213), (-4.6378352522239554, 0.71224131017907655), (2.9680366726671408, 3.8057463470229771), (-4.3923934213067932, -1.3791542744104026), (-4.2053686108626351, -3.6915210305842443), (-2.0746723787889829, -5.4464802222512967), (-4.0996534303685408, 3.3267880265107594), (-1.8128378443025992, -3.9344867995823476), (-3.2353459560678726, 0.0078487639308876256), (-5.2567050348371964, -2.8358582468324252), (-2.2350770635882338, 4.8035421802935794), (4.5454547247951318, 3.8505415523103865), (0.77852150481602367, -6.304360789570536), (2.8006251537057874, -3.4054180128674925), (0.80971629500490194, 3.8065008164142045), (-4.6893071013407308, 2.2137047680876876), (3.3741845332290392, 0.1809403893940662), (-3.2918652308459055, 0.090757607140976582), (-2.731021645889272, -1.6662800739451944), (4.1392456836843463, -2.6535938902245615), (0.46602710316953699, 2.1099910099056247), (-0.99288504381124265, -3.635131537333915), (-3.4662675388435948, -0.058701426738028029), (-2.9999952003703356, 0.97385236270124387), (3.2650338417095948, -3.8196135607333344), (-3.9456323778158917, 1.6498531850237104), (3.4959780062736767, -4.7693709944976597), (-6.3793247897778178, 3.7936917868316788), (-2.8361948828141816, -1.4723239541777753), (-3.4585466204767146, -3.8744844913637744), (2.960095790660457, -4.8884709834126614), (-1.2993953267806311, 4.0973104894384376), (-3.0970989922258405, 0.22866598184118958), (3.4437835364866913, -0.8809379622205642), (-1.2881813072780375, -4.1229601681474559), (5.4862812324101551, 1.836628009823206), (3.1236304949998903, -4.1524561478238979), (0.61467544773508809, -5.1189666093912951), (1.8730432423071945, -4.3249847084872606), (2.0752011951950715, -4.4488200981023773), (-5.3418920228459292, -2.9894449162072085), (0.88838354958991195, 4.7891995309050168), (-2.9815280097655044, 0.75974611993798513), (-4.4459283100583553, -2.8427774445017384), (-4.064198055377803, -0.26016925859548712), (3.9592858553113812, 5.7062659782102383), (-4.0776456770357399, -2.1108468150902038), (2.80041795823937, 3.9790775056847605), (0.78487223802603201, -4.2564317334246189), (-4.9580286073678153, -4.3043816295110746), (-2.7669760995888444, -2.5651126393631269), (-3.9254876523953905, -3.5085487626888177), (-3.7540103697600991, 3.7300659425632596), (3.6783559669906869, -2.351144064434612), (4.0933414500950187, 4.5060014596068578), (3.7335394329236813, 1.0973237757208787), (1.1442075030227594, -4.2316977637013782), (-3.6220150980624424, 3.185201907480816), (-2.2337125392446318, 4.3478035180013368), (2.6781697617925388, 2.2280922113698827), (-1.6681130570090124, 4.7186880822137711), (3.4525222878110728, 2.8129919629877103), (-4.2615596708093531, -2.7146058843073311), (-3.4402593724261346, -3.1673759335208658), (3.1774382402490873, -4.8863913791911475), (3.5356594608336036, -2.1183528278045651), (5.4668883824812955, 0.96389044748342978), (-3.6545253298129072, 1.191029553432321), (2.4693389761239732, -4.3812421972626314), (-4.7093027774610103, 3.965026191026729), (3.2404707985524244, 0.77619181600786824), (3.0540906215419827, -0.28806712267986057), (-3.6028130521113049, 1.935895100383537), (-3.3489404619836742, 2.4563658827640311), (-2.4889130194431983, -2.2068778228055628), (-4.8626794620087885, -2.8453503859189597), (-5.281369798564187, 3.5735280155556834), (1.6030813205100574, 3.5731475337773819), (-2.1025461390993794, 3.4422700241336504), (-4.2729514664802686, 0.98295236061849844), (-2.7317907928709642, 3.817432925064046), (-3.347758848146241, -2.5448741023523311), (0.8915743485505736, -2.2569697596670535), (3.5045925916795215, 3.2722443198059601), (3.5998395703577524, 3.2190081781102129), (1.4334706104985417, -4.0424849300410903), (-4.0667426219862737, -1.4761924494221059), (2.1740645996991859, -3.0289758518776351), (-2.4038443669649543, 3.0160752773304909), (-4.0303363017873819, 2.7543768490206029), (0.47537794879953099, 2.8085335721228395), (1.6413771309213714, -4.3558686770090542), (-5.1433034570264313, 1.9430061162740762), (1.8276873292623577, -3.6790602249992337), (4.1406942586495843, 1.3675393354116923), (3.3480076038224218, 4.721175565871162), (4.4634711149083595, -2.8871256008130279), (5.7357361409997534, 3.4008106446903601), (-3.0916329376751204, -4.0216467418174098), (-0.3493957952197404, -3.9951380224963402), (-4.7778083762237662, 0.26542128046507107), (1.403043362648535, -5.9337467353513125), (-3.8601684384095898, 2.4274964923790896), (-2.3093328988302524, 2.5925313771583451), (5.1033208593702017, -0.46327358367228422), (-4.1094019584172159, -2.6861910724662836), (-0.57183320351506084, -4.365390016818222), (-5.0613329560272344, -0.92832778971832219)] ###################################### Question 3 ################ #je définis une fonction qui va me servir pour NombreTotalNoeud def action(a,liste): for e in a.arcs: if e not in liste: liste+=[e] action(e,liste) class MonGraphe : def __init__ (self, num, valeur) : self.valeur = valeur self.num = num self.arcs = [] def NombreTotalNoeud (self) : connus=[self] #je définis ma liste de sommets connus for a in self.arcs: action(a,connus) #j'applique l'action qui consiste à ajouter des sommets non connus return len(connus) def Degre (self): return len(self.arcs) ###################################### Question 4 ################ def ConstruireMonGraphe (noeuds, arcs): l = [] for i in noeuds: l += [ MonGraphe(i,noeuds[i]) ] for (a,b) in arcs : l [a].arcs += [ l [b] ] l [b].arcs += [ l [a] ] return l graphe = ConstruireMonGraphe(noeuds,arcs) #definition d'une fonction pour afficher le graphe def afficher(graphe): for e in graphe: print e.num, e.valeur, [a.num for a in e.arcs] afficher(graphe) #print '**********************' ###################################### Question 5 ################ #for i in xrange(0,len(graphe)): # print graphe[i].NombreTotalNoeud() #cette fonction retourne une erreur car elle boucle sur elle-même #si b est dans a.arcs alors elle se rappelle car a est dans b.arcs #il faut retenir les noeuds déja traités #voir question 3 pour la fonction corrigée #sinon on peut faire le meme principe que pour le graphe sur les amis ###################################### Question 6 ################ #voir partie de la question 3 ###################################### Question 7 ################ #l'algorithme permet de diminuer le nombre d'aretes #ici il reviendrait à recouvrir avec le moinds d'aretes possibles #mais il ne permet pas de faire ce qu'on veut #une fois qu'on a l'arbre minimal, si on coupe on ne sait pas combien d'aretes on coupe en réalité ###################################### Question 8 ################ #voir dans la définition de class MonGraphe #ou sinon def Deg(numero): return len( graphe[numero].arcs ) print graphe[0].Degre() print '*****************' ###################################### Question 9 ################ n=len(graphe) #n*n sera la taille de la matrice import numpy as np import scipy.linalg M = np.matrix( [[0 for i in xrange(0,n)] for j in xrange(0,n)] ) #construction d'une matrice de 0 de taille n*n #je définis une fonction qui me donne le coefficient i,j def laplacien(i,j): if i==j : return graphe[i].Degre() elif graphe[j] in graphe[i].arcs: return -1 else: return 0 #je modifie ma matrice en appliquant cette fonction for i in xrange(0,n): for j in xrange(0,n): M[i,j] = laplacien(i,j) #quelques vérifications print M[2,2] print Deg(2) print M[20,17] print M[41,0] ###################################### Question 10 ################ #pour vérifier que toutes les sommes de ligne sont nulles b=True i=0 while b==True and i<n: if sum ( M[:,j] ) <>0: b=False i+=1 print b V=np.matrix ( [1 for i in xrange(0,n) ]) #print M*V.transpose() ###################################### Question 11 ################ L,P = np.linalg.eig(M) print L,P P=P.transpose() print P[2] #print M*P[2].transpose()-L[2]*M ###################################### Question 12 ################ pos=[ (L[i],i) for i in xrange(0,len(L)) ] pos.sort() print pos vecteursp= [ P[i] for (a,i) in pos ] #le premier vecteur propre associé à une valeur propre non nulle est le 2e V = vecteursp[1] print V #une fois qu'on a le vecteur propre en question #on peut construire une liste pour chaque composante compneg = [] comppos = [] for i in xrange(0,50): if V[0,i]<0 : compneg += [graphe [i]] else : comppos += [graphe [i]] def nombre_arcs(sommet): def nombre_arcs_liste(comp): r=0 for n in comp: if n in sommet.arcs : r += 1 return r if sommet in compneg : return nombre_arcs_liste(comppos) else : return nombre_arcs_liste(compneg) print [a.num for a in comppos], [a.num for a in compneg] r=0 for sommet in graphe: if sommet in comppos: r+= nombre_arcs(sommet) print r r=0 for sommet in graphe: if sommet in compneg: r+= nombre_arcs(sommet) print r #pour savoir quelle est l'arête à couper for a in comppos: for b in compneg: if a in b.arcs : print (a.num,b.num)
File: confirme_viterbi.tex, line 21
r s t a i r n t s r e s t a u r a n t
File: confirme_viterbi.tex, line 38
entier DistanceDeLevenshtein(caractere chaine1[1..longueurChaine1], caractere chaine2[1..longueurChaine2]) // d est un tableau de longueurChaine1+1 rangées et longueurChaine2+1 colonnes declarer entier d[0..longueurChaine1, 0..longueurChaine2] // i et j itèrent sur chaine1 et chaine2 declarer entier i, j, coût pour i de 0 à longueurChaine1 d[i, 0] := i pour j de 0 à longueurChaine2 d[0, j] := j pour i de 1 à longueurChaine1 pour j de 1 à longueurChaine2 si chaine1[i] = chaine2[j] alors coût := 0 sinon coût := 1 d[i, j] := minimum( d[i-1, j ] + 1, // effacement d[i, j-1] + 1, // insertion d[i-1, j-1] + coût // substitution ) retourner d[longueurChaine1, longueurChaine2]
File: confirme_viterbi.tex, line 68
d[i, j] := minimum( d[i-1, j ] + 1, // effacement d[i, j-1] + 1, // insertion d[i-1, j-1] + coût // substitution )
File: confirme_viterbi.tex, line 78
e = d[i-1, j ] + 1 i = d[i, j-1] + 1 s = d[i-1, j-1] + coût if s <= min (e,i) : # ligne A d [i, j] := s predecessor [i,j] = (i-1, j-1) elif e < min (s,i) : d [i, j] := e predecessor [i,j] = (i-1, j) else : d [i, j] := i predecessor [i,j] = (i, j-1)
distance de Levenstein et Viterbi
#HERMANT Bettina #import-*-coding:cp1252-* import numpy as np import random # PARTIE I # Question 1 def DistanceDeLevenshtein(c1,c2) : d=[[0 for i in xrange(0,len(c2)+1)] for j in xrange(0,len(c1)+1)] for i in xrange(0,len(c1)) : d[i][0]=i for j in xrange(0,len(c2)) : d[0][j]=j for i in xrange(1,len(c1)+1) : for j in xrange(1,len(c2)+1) : if c1[i-1]==c2[j-1] : cout=0 else : cout=1 d[i][j]=min(d[i-1][ j ] + 1, d[i][ j-1] + 1, d[i-1][ j-1] + cout) return d[len(c1)][len(c2)] print DistanceDeLevenshtein("rstairnts","restaurant") # On obtient bien une disctance de 4 pour l'exemple cité # Question 2 def DistanceDeLevenshtein2(c1,c2) : d=[[0 for i in xrange(0,len(c2)+1)] for j in xrange(0,len(c1)+1)] predecessor=[[(i-1,j-1) for j in xrange(0,len(c2)+1)] for i in xrange(0,len(c1)+1)] for i in xrange(0,len(c1)) : d[i][0]=i for j in xrange(0,len(c2)) : d[0][j]=j for i in xrange(1,len(c1)+1) : for j in xrange(1,len(c2)+1) : if c1[i-1]==c2[j-1] : cout=0 else : cout=1 e = d[i-1][ j ] + 1 ins = d[i][j-1] + 1 s = d[i-1][j-1] + cout if s < min (e,ins) : d [i][j] = s predecessor [i][j] = (i-1, j-1) elif e < min (s,ins) : d [i][ j] = e predecessor [i][j] = (i-1, j) else : d [i][j] = ins predecessor [i][j] = (i, j-1) print predecessor print i,j print predecessor[len(c1)][len(c2)] return d[len(c1)][len(c2)] # predecessor permet d'avoir la trace des modifications effectuées sur le mot # Question 3 #prodecessor[len(c1),(c2)] contient l'information sur la nature de la transformation donnant la dernière lettre du mot modifié # Question 4 # PARTIE II l1=[0.1,0.2,0.3,0.1,0.1,0.2] l2=[0.3,0.1,0.1,0.1,0.1,0.3] l3=[0.1,0.2,0.2,0.2,0.1,0.2] # Question 5 def tirage(l) : #creation de la fonction de repartition m=[0 for i in xrange(0,7)] for i in xrange(0,6) : m[i+1]=m[i]+l[i] import random a=random.random() for i in xrange(0,6) : if m[i]<a<m[i+1] : return i+1 print tirage(l1) #Question 6 def simulation(l1,l2,l3) : l=[0,0,0] l[0]=tirage(l1) for i in xrange(0,2) : if l[i]==1 or l[i]==2 : l[i+1]=tirage(l1) if l[i]==3 or l[i]==4 : l[i+1]=tirage(l2) if l[i]==5 or l[i]==6 : l[i+1]=tirage(l3) return str(l) print simulation (l1,l2,l3) #Question 7 def sim10000() : sim=[simulation() for i in xrange(0,10000)] d={} for l in sim : d[l]=0 for l in sim : d[l]+=1 return d # Question 8 # P([6,6,6])=0.2*0.2*0.2=0.008 l=[l1,l2,l3] #Question 9 def trivalues (d): l = [ (m,n) for (n,m) in d.iteritems () ] l.sort (reverse = True) l = [ (m,n) for (n,m) in l] return l def proba() : p={} for i in xrange(1,7) : for j in xrange(1,7) : for k in xrange(1,7) : if j==1 or j==2 : p[i,j,k]=l[0][k-1] if j==3 or j==4 : p[i,j,k]=l[1][k-1] if j==5 or j==6 : p[i,j,k]=l[2][k-1] if i==1 or i==2 : p[i,j,k]*=l[0][j-1] if i==3 or i==4 : p[i,j,k]*=l[1][j-1] if i==5 or i==6 : p[i,j,k]*=l[2][j-1] p[i,j,k]*=l[0][i-1] return trivalues (p)[0] print proba() # La sequence la plus probable est 313 avec une probabilite de 0.027 #PARTIE III #Question 10 # Chaque proba ne dépend que du tirage précédent (et seulement de celui-ci). Ainsi la matrice du premier au second tirage sera la même que celle du second au troisième tirage. a1=[l1,l1] a2=[l2,l2] a3=[l3,l3] A=a1+a2+a3 print "A: \n", A #PARTIE IV #Question 11 #Il faut absolument que le premier tirage soit effectué avec le dé 1. On a donc S0(1)=1 et S0(2)=1 et les autres valeurs sont nulles. S=[[0 for j in xrange(0,6)] for i in xrange(0,4)] for i in xrange(0,2) : S[0][i]=1 print "S: \n", S #Question 12 def Sc(t,j) : a=max(S[t-1][i]*A[i][j] for i in xrange(0,6)) return a #Question 13 for t in xrange(1,4) : for j in xrange(0,6) : S[t][j]=Sc(t,j) print max(S[3]) print S[3].index(max(S[3]))+1 print np.array(S) #La sequence la plus probable se termine par un 3 et pour probabilite 0.027. #Question 14 def B(t,j) : l=[S[t-1][i]*A[i][j] for i in xrange(0,6)] a=max(l) b=l.index(max(l)) return [a,b] def seq_plus_probable(t) : S=[[0 for j in xrange(0,6)] for i in xrange(0,t+1)] R=[[0 for j in xrange(0,6)] for i in xrange(0,t-1)] for i in xrange(0,2) : S[0][i]=1 for u in xrange(1,t+1) : for j in xrange(0,6) : S[u][j]=B(u,j)[0] if u>1 : R[u-2][j]=B(u,j)[1] print np.array(R) l=[] l+=[S[t].index(max(S[t]))+1] for i in xrange(t-2,-1,-1) : l+=[R[i][S[i+2].index(max(S[i+2]))]+1] l.reverse() return l print seq_plus_probable(3) # On retrouve bien que la séquence la plus probable est 3 1 3. #Question 15 # La première méthode est à proscrire car le nombre de lancés est trop faible pour obtenir un résultat cohérent.
File: description_cours.tex, line 52
1. Boucles, tests 2. Fonctions, fichiers 1 3. Fonctions, fichiers 2 4. Présentation dun tri 5. Recherche dichotomique à laide dun dictionnaire 6. Classes 1 7. Classes 2 8. Calcul matriciel (implémentation de la régression) 9. Chaînes de caractères, expression régulières 10. Interfaçage, présentation des modules les plus utilisés 11. Interface graphique 12. Plus court chemin 13. TD noté (à répartir sur deux autres séances) Idéalement, le tutoriel sappuierait sur un article pour bien montrer aux étudiants à quoi peut servir Python, sans toutefois trop séloigner du cours. Les TD devraient être également plus centrés sur les curs de métier ENSAE : stat ou éco.
File: recherche_dichotomique_minute.tex, line 19
x = 3 y = x + 5 print x print x,y # commentaire
File: recherche_dichotomique_minute.tex, line 34
i = 3 # entier r = 3.3 # réel s = "exemple" # chaîne de caractères c = (4,5) # couple de valeurs (ou tuple) l = [ 4, 5, 6.5] # listes de valeurs ou tableaux x = l [0] # obtention du premier élément de la liste l d = { "un":1, "deux":2 } # dictionnaire de valeurs y = d ["un"] # obtention de la valeur associée à l'élément "un" couple = 4, 5 # collage de deux valeurs en un couple ou (tuple) print type (l) # on affiche le type de la variable l mat = [ [0,1], [2,3] ] # liste de listes print mat [0][1] # obtention du second élément de la première liste n = None # None signifie que la variable existe mais qu'elle ne contient rien # elle est souvent utilisé pour signifier qu'il n'y a pas de résultat # car... une erreur s'est produite, une liste était vide...
File: recherche_dichotomique_minute.tex, line 54
i = 3 i = i + 5
File: recherche_dichotomique_minute.tex, line 63
print x + y # addition print x - y # soustraction print x / y # division print x * y # multiplication print x % y # modulo print x == y # égalité print x < y # inférieur print x <= y # inférieur ou égal print min (x,y) # minimum print max (x,y) # maximum print zip (x,y) # zip ( [4,5], ["a", "b"] ) donne [ (4,"a"), (5,"b") ] # de deux listes, on passe à une sorte de matrice print True and False # et logique print True or False # ou logique print (5 < 4) or (5 > 4) # condition
File: recherche_dichotomique_minute.tex, line 83
print -x # opposé print len ( [ 4,5] ) # obtention du nombre d'éléments d'une liste print not False # négation
File: recherche_dichotomique_minute.tex, line 91
print [ 3,4 ] * 5 print "azerty" * 4 print 4 * "azerty" print [ 3,4 ] + (3,4)
File: recherche_dichotomique_minute.tex, line 114
print int (3.4) print list ( (4,5) ) print tuple ( [ 4,5] ) print dict ( [4,5] ) print str ( { "un":1, "deux":2 } )
File: recherche_dichotomique_minute.tex, line 125
x = 1.2 y = 1.2 * 6.55 print "Le prix de la baguette est ", x, "francs." print "Le prix de la baguette est " + x + "francs." print "Le prix de la baguette est " + str(x) + "francs."
File: recherche_dichotomique_minute.tex, line 142
l = [ 4, 6, 3, 4, 2, 9] # n'importe quelle liste au hasard l.sort () print l # le programme affiche la liste triée
File: recherche_dichotomique_minute.tex, line 152
for i in xrange (0, len (l)) : print l [i]
File: recherche_dichotomique_minute.tex, line 161
resultat = ... for i in xrange (0, ...) : if ... > ... : resultat = False break print "le tableau est-il trié : ", resultat
File: recherche_dichotomique_minute.tex, line 172
resultat = ... i = ... while i < ... if ... > ... : resultat = False break print "le tableau est-il trié : ", resultat
File: tri_minute.tex, line 17
# première moyenne poids = [1, 2, 1, 2] notes = [12, 14, 8, 9] s = 0 # w = 0 # for p,n in zip (poids, notes) : # calcule du résultat s += p*n # w += p # resultat = s * 1.0 / w # * 1.0 évite le problème dus aux divisions entières # 1/2 --> 0, 1 * 1.0 / 2 --> 0.5 # seconde moyenne poids = [1, 1, 2] notes = [12, 14, 8] s = 0 w = 0 for p,n in zip (poids, notes) : s += p*n w += p resultat = s * 1.0 / w
File: tri_minute.tex, line 42
def moyenne_ponderee (poids, notes) : s = 0 w = 0 for p,n in zip (poids, notes) : s += p*n w += p return s * 1.0 / w # le mot-clé return désigne le résultat que la fonction calcule poids = [1, 2, 1, 2] notes = [12, 14, 8, 9] resultat = moyenne_ponderee (poids, notes) poids = [1, 1, 2] notes = [12, 14, 8] resultat = moyenne_ponderee (poids, notes)
File: tri_minute.tex, line 74
def trie_tableau (tableau) : tableau.sort () return tableau tab = [ 3,5,4] tri = trie_tableau (tab) print tab print tri
File: tri_minute.tex, line 92
def trie_tableau (tableau) : tableau.sort () return tableau tab = ( 3, 5, 4 ) tri = trie_tableau (tab) print tab print tri
File: tri_minute.tex, line 110
l = [ 4, 5, 3, 7, 7, 9, 10, 0 ]
File: tri_minute.tex, line 116
l.sort ()
File: tri_minute.tex, line 124
l = [ 4, 5, "ee", 7, "aa", 7, 9, 10, 0, "gg" ]
File: tri_minute.tex, line 131
print l [1] print l [ len (l)-1 ]
File: tri_minute.tex, line 152
def permutation (l, i, j) : ...
File: tri_minute.tex, line 165
def comparaison_permutation (l, i) : ...
File: tri_minute.tex, line 173
for i in xrange (0, 10) : print i
File: tri_minute.tex, line 180
def plusieurs_comparaison_permutation (l) : ...
File: tri_minute.tex, line 193
def n_fois_plusieurs_comparaison_permutation (l) : ...
File: vigenere_minute.tex, line 20
ABCDEFGHIJKLMNOPQRSTUVWXZ BCDEFGHIJKLMNOPQRSTUVWXZA CDEFGHIJKLMNOPQRSTUVWXZAB DEFGHIJKLMNOPQRSTUVWXZABC EFGHIJKLMNOPQRSTUVWXZABCD FGHIJKLMNOPQRSTUVWXZABCDE GHIJKLMNOPQRSTUVWXZABCDEF HIJKLMNOPQRSTUVWXZABCDEFG IJKLMNOPQRSTUVWXZABCDEFGH JKLMNOPQRSTUVWXZABCDEFGHI KLMNOPQRSTUVWXZABCDEFGHIJ LMNOPQRSTUVWXZABCDEFGHIJK MNOPQRSTUVWXZABCDEFGHIJKL NOPQRSTUVWXZABCDEFGHIJKLM OPQRSTUVWXZABCDEFGHIJKLMN PQRSTUVWXZABCDEFGHIJKLMNO QRSTUVWXZABCDEFGHIJKLMNOP RSTUVWXZABCDEFGHIJKLMNOPQ STUVWXZABCDEFGHIJKLMNOPQR TUVWXZABCDEFGHIJKLMNOPQRS UVWXZABCDEFGHIJKLMNOPQRST VWXZABCDEFGHIJKLMNOPQRSTU WXZABCDEFGHIJKLMNOPQRSTUV XZABCDEFGHIJKLMNOPQRSTUVW ZABCDEFGHIJKLMNOPQRSTUVWX ABCDEFGHIJKLMNOPQRSTUVWXZ
File: vigenere_minute.tex, line 52
s = "" for i in xrange (0,26) : s += chr (65+i) print s
File: vigenere_minute.tex, line 66
lescodessecretsontjoueunrolediscretmaisimportantdanslhistoire CODECODECODECODECODECODECODECODECODECODECODECODECODECODECODEC NSV...
File: vigenere_minute.tex, line 74
def lettre_codee (lettre_message, lettre_cle, carre_vigenere) : ... return lettre_codee
File: vigenere_minute.tex, line 82
print chr(65) # retourne la lettre correspondant au code 65 --> A print ord("A") # retourne le code associé à la lettre "A" --> 65
File: vigenere_minute.tex, line 96
def cryptage (message, cle, carre_vigenere) : ... return message_code
File: vigenere_minute.tex, line 111
f = open ("nom_de_fichier", "r") text = f.read () f.close ()
File: vigenere_minute.tex, line 119
import urllib2 f = urllib2.urlopen ("http://www.gutenberg.org/files/30696/30696-h/30696-h.htm") text = f.read ()
File: vigenere_minute.tex, line 127
import urllib2 req = urllib2.Request("http://www.gutenberg.org/files/30696/30696-h/30696-h.htm", headers={'User-Agent' : "Magic Browser"}) f = urllib2.urlopen (req) text = f.read ()
File: vigenere_minute.tex, line 147
h = { } h ["A"] = 50 h ["B"] = 50 print h ["A"] print h
File: vigenere_minute.tex, line 157
def histogramme_lettre (texte) : h = { } ... return h
File: langue_minute.tex, line 32
def normalise (dico) : # faire la somme en une ligne avec la fonction sum # diviser # fin return nouveau_dico
File: langue_minute.tex, line 75
import os for fichier in os.listdir (".") : print fichier
File: carre_minute.tex, line 37
class CarreMagique : def __init__ (self, ...) : ...
File: carre_minute.tex, line 45
class CarreMagique : def __init__ (self, a,b,c, d,e,f, g,h,i) : self.carre = [ [ a,b,c ], [ d,e,f ], [ g,h,i ] ]
File: carre_minute.tex, line 53
c = CarreMagique ( 1,2,3, 4,5,6, 7,8,9 )
File: carre_minute.tex, line 59
print c.carre
File: carre_minute.tex, line 66
l = range (1,10) c = CarreMagique ( l )
File: carre_minute.tex, line 74
class CarreMagique : def __init__ (self, a,b,c, d,e,f, g,h,i) : self.carre = [ [ a,b,c ], [ d,e,f ], [ g,h,i ] ] c = CarreMagique (2,7,6, 9,5,1, 4,3,8) print c
File: carre_minute.tex, line 85
class CarreMagique : def __init__ (self, a,b,c, d,e,f, g,h,i) : self.carre = [ [ a,b,c ], [ d,e,f ], [ g,h,i ] ] def __str__ (self) : return "carre magique : " + str (self.carre) c = CarreMagique (2,7,6, 9,5,1, 4,3,8) print c
File: carre_minute.tex, line 99
s = "un deux" print s s = "un \n deux" # ajout du caractère \n print s
File: carre_minute.tex, line 114
class CarreMagique : def __init__ (self, a,b,c, d,e,f, g,h,i) : self.carre = [ [ a,b,c ], [ d,e,f ], [ g,h,i ] ] def __str__ (self) : return "carre magique : " + str (self.carre) def somme_ligne (self, i) : # ajout return sum ( self.carre [i] ) # ajout c = CarreMagique (2,7,6, 9,5,1, 4,3,8) print c.somme_ligne (0) # somme des nombres sur la première ligne
File: carre_minute.tex, line 135
class CarreMagique : ... def carre_est_magique (self) : li = [ self.somme_ligne (i) for i in xrange (0,3) ] lj = [ self.somme_colonne (j) for j in xrange (0,3) ] diag = [ self.somme_diagonal (k) for k in xrange (0,2) ] tout = li + lj + diag tout.sort () return .................
File: carre_minute.tex, line 163
d = {} d [ 1,-1 ] = 1
File: carre_minute.tex, line 170
for i in xrange (0,9) : print i % 3 # affiche 0,1,2, 0,1,2, 0,1,2
File: carre_minute.tex, line 208
class CarreMagique : ... def etape_damier_1 (self, dimension) : d = { } ... return d
File: carre_minute.tex, line 226
class CarreMagique : ... def damier_crenele (self, dimension) : d = self.etape_damier_1 ( dimension ) self.carre = [ [ 0 for i in xrange (0, ... ) ] for j in xrange (0, ... ) ] ... c = CarreMagique ([]) c.damier_crenele () print c print c.carre_est_magique ()
File: graphe_minute.tex, line 26
coleman,frank dana,lara dana,melanie dana,ralph danny,dylan dona,jenny ...
File: graphe_minute.tex, line 38
def lit_donnees_depuis_un_fichier_ou_internet (fichier) : """ cette fonction lit un fichier où le télécharge depuis un site internet, si le fichier n'existe pas, il est téléchargé puis enregisté sur disque """ if not os.path.exists (fichier) : url = "http://www.xavierdupre.fr/enseignement/complements/" + fichier import urllib2 f = urllib2.urlopen (url) t = f.read() f.close() f = open(fichier, "w") f.write(t) f.close()
File: graphe_minute.tex, line 58
f = open (".......", "r") lines = f.readlines () f.close () # la partie après le if sert à enlever les lignes vides couples = [ l.strip(" \n\r").split ( ... ) for l in lines if ... ]
File: graphe_minute.tex, line 80
class Personne : def __init__ (self, nom): self.nom = nom self.amis = [] def ajout_ami (self, ami) : self.amis.append (ami)
File: graphe_minute.tex, line 94
graph = { } for prenom in liste_prenoms : graph [ prenom ] = Personne ( prenom )
File: graphe_minute.tex, line 102
for a,b in couples : graph [ ... ].ajout_ami ( ... ) graph [ ... ].ajout_ami ( ... )
File: graphe_minute.tex, line 116
class Personne : ... def nombre_amis_amis(self) : nb = 0 .... return nb
chargement de données depuis internet
#coding:latin-1 import urllib, os, os.path def charge_donnees () : if os.path.exists ("marathon.txt") : # si le fichier existe (il a déjà été téléchargé une fois) f = open ("marathon.txt", "r") text = f.read () f.close () else : # si le fichier n'existe pas link = "http://www.xavierdupre.fr/enseignement/complements/marathon.txt" url = urllib.urlopen (link) text = url.read () # on enregistre les données pour éviter de les télécharger une seconde fois f = open ("marathon.txt", "w") f.write (text) f.close () lines = text.split ("\n") lines = [ l.split("\t") for l in lines if len(l) > 3 ] # conversion en réel des données numérique for l in lines : l [1] = float(l[1]) l [3] = float(l[3]) return lines if __name__ == "__main__" : matrice = charge_donnees () print "nombre de lignes ", len(matrice)
dessin des données du marathon
# coding:latin-1 import marathon # cette première ligne suppose que le programme de la la première question # a été enregistrée dans un fichier marathon.py # il n'y a alors pas besoin de le recopier ici import matplotlib import matplotlib.pyplot as plt def dessin (donnees, titre = "titre") : x = [ d[0] for d in donnees ] y = [ d[1] for d in donnees ] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x,y, 'o') ax.set_title(titre) plt.show() if __name__ == "__main__" : matrice = marathon.charge_donnees() mat = [ (m[1], m[3]) for m in matrice ] dessin (mat)
File: regression_minute.tex, line 32
from marathon import * import numpy as np donnees = charge_donnees () mat = np.matrix(donnees)
File: regression_minute.tex, line 42
print mat.ndim print mat.shape print mat.size
File: regression_minute.tex, line 50
a = mat[0,0] b = mat[:,0] c = mat[0,:] d = mat[4:10,:] e = mat.transpose()
File: regression_minute.tex, line 61
ms = np.column_stack ( (mat[:,1], mat[:,3])) ms = mat[:,[1,3]] # seconde écriture
File: regression_minute.tex, line 67
ms * 3.0
File: regression_minute.tex, line 74
xy = np.matrix ( ms, dtype=float) xy * 3.0
File: regression_minute.tex, line 81
print xy [ ... ].sum() / xy.shape [ ...]
File: regression_minute.tex, line 87
z = np.zeros ( mat.shape[ ... ] ) mat = np.column_stack ( (mat, z))
File: regression_minute.tex, line 94
mat [:,4] = 1.0
File: regression_minute.tex, line 165
mat[ mat[:,0] == "PARIS" , 4 ] = nouvelle valeur
File: decorrelation_minute.tex, line 21
import random import numpy as np def combinaison () : x = random.gauss(0,1) # génère un nombre aléatoire y = random.gauss(0,1) # selon une loi normale z = random.gauss(0,1) # de moyenne null et de variance 1 x2 = x y2 = 3*x + y z2 = -2*x + y + 0.2*z return [x2, y2, z2] mat = [ ............. ] npm = np.matrix ( mat )
File: decorrelation_minute.tex, line 40
npm = ... # voir question précédente t = npm.transpose () a = t * npm a /= npm.shape[0]
File: decorrelation_minute.tex, line 57
import copy b = copy.copy (a) # remplacer cette ligne par b = a b [0,0] = 44444444 print b # et comparer le résultat ici
File: decorrelation_minute.tex, line 67
def correlation ( npm ) : .......... return .....
File: decorrelation_minute.tex, line 104
L,P = np.linalg.eig(a)
File: decorrelation_minute.tex, line 112
print np.diag(L)
File: decorrelation_minute.tex, line 129
np.linalg.inv(a)
File: decorrelation_minute.tex, line 149
def simultation (N, cov) : # simule un échantillon de variables corrélées # N : nombre de variables # cov : matrice de covariance ... return M
chargement de v\oe ux des présidents depuis internet
#coding:latin-1 import urllib, os, os.path def charge_discours () : discours = { } for annee in [2001, 2005, 2006, 2007, 2008, 2009, 1974, 1975, 1979, 1983, 1987, 1989, 1990, 1994] : nom = "VOEUX%02d.txt" % (annee % 100) 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/voeux_presidents/" + 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 () discours [annee] = text return discours if __name__ == "__main__" : discours = charge_discours () print "nombre de discours ", len(discours)
File: regex_minute.tex, line 21
import discours textes = discours.charge_discours()
File: regex_minute.tex, line 28
import discours textes = discours.charge_discours() def somme_texte (textes): ... return ...
File: regex_minute.tex, line 39
accent = { 'à':'a', 'â':'a', 'ä':'a', 'é':'e', 'è':'e', 'ê':'e', 'ë':'e', 'î':'i', 'ï':'i', 'ù':'u', 'û':'u', 'ü':'u', 'ô':'o', 'ö':'o', } def pas_daccent (texte) : res = "" for c in texte : c = c.lower () res += accent.get (c,c) return res
File: regex_minute.tex, line 59
def decoupe_mot (texte) : return ....
File: regex_minute.tex, line 65
def compte_mots (mots) : d = { } for mot in mots : ... ... return d
File: regex_minute.tex, line 75
def mot_tries (d): l = [ (n,m) for ... in d.iteritems () ] l.sort (reverse = True) return l
File: regex_minute.tex, line 88
def decoupe_mot2 (texte) : exp = re.compile ("\\w+", re.IGNORECASE) return exp.findall(texte)
File: regex_minute.tex, line 102
def trouver_expression(texte) : exp = re.compile ("je .{1,60}", re.IGNORECASE) return exp.findall(texte)
récupération de la définition d'un graphe
#coding:latin-1 import urllib, os, os.path from importme import * GV = import_module ("use_graphivz") webhelper = import_module ("webhelper") drawGraph = GV.drawGraphScript graphviz_script = GV.graphviz_script # coding:latin-1 def charge_donnees (file = "matrix_distance_7398.txt") : webhelper.import_module_or_file_from_web_site(file) f = open (file, "r") text = f.read () f.close () lines = text.split ("\n") lines = [ l.split("\t") for l in lines if len(l) > 1 ] return lines def conversion_en_dictionnaire (lines) : res = { } for a,b,c in lines : c = int (c) res [a,b] = c res [b,a] = c return res if __name__ == "__main__" : matrice_line = charge_donnees () mat = conversion_en_dictionnaire (matrice_line) script = graphviz_script (mat) drawGraph([], script , "im.png")
File: meilleur_chemin_minute.tex, line 145
Fonction Dijkstra (nuds, fils, distance, début, fin) Pour n parcourant nuds n.parcouru = infini // Peut être implémenté avec -1 n.précédent = 0 Fin pour début.parcouru = 0 pasEncoreVu = nuds Tant que pasEncoreVu != liste vide n1 = minimum(pasEncoreVu) // Le nud dans pasEncoreVu avec parcouru le plus petit pasEncoreVu.enlever(n1) Pour n2 parcourant fils(n1) // Les nuds reliés à n1 par un arc Si n2.parcouru > n1.parcouru + distance(n1, n2) // distance correspond au // poids de l'arc reliant n1 et n2 n2.parcouru = n1.parcouru + distance(n1, n2) n2.précédent = n1 // Dit que pour aller à n2, il faut passer par n1 Fin si Fin pour Fin tant que chemin = liste vide n = fin Tant que n != début chemin.ajouterAvant(n) n = n.précédent Fin tant que chemin.ajouterAvant(debut) Retourner chemin Fin fonction Dijkstra
Pas 1
x = 5 y = 10 z = x + y print (z) # affiche z
Pas 2
x = 2 x = x + 1 print (x) # affiche 3 x += 5 print (x) # affiche 8
Pas 3
a = 0 for i in range (0, 10) : a = a + i # répète dix fois cette ligne print (a)
Pas 4
a = 10 if a > 0 : print(a) # un seul des deux blocs est pris en considération else : a -= 1 print (a)
Pas 5
a = 10 print (a) # quelle est la différence print ("a") # entre les deux lignes s = "texte" s += "c" print (s)
Pas à reculons 1
a = 5 a + 4 print (a) # ou voudrait voir 9 mais c'est 5 qui apparaît
Pas à reculons 2
a = 0 for i in range (0, 10) a = a + i print (a)
-
File "i.py", line 2 for i in range (0, 10) ^ SyntaxError: invalid syntax
Pas à reculons 3
a = 0 for i in range (0, 10) a = a + i print (a)
-
File "i.py", line 4 print (a) ^ IndentationError: unindent does not match any outer indentation level
Pas à reculons 4
a = 0 s = "e" print (a + s)
-
Traceback (most recent call last): File "i.py", line 3, in <module> print (a + s) TypeError: unsupported operand type(s) for +: 'int' and 'str'
Pas à reculons 5
a = 0 for i in range (0, 10) : a = (a + (i+2)*3 print (a)
-
File "i.py", line 4 print (a) ^ SyntaxError: invalid syntax'
calcule la somme des 10 premiers entiers au carré
#coding:latin-1 s = 0 for i in range(1,11) : # 11 car range va de 1 à 11 exclu s += i**2 print (s)
calcule la somme des 5 premiers entiers impairs au carré (1)
s = 0 for i in range(1,11) : if i % 2 == 1 : s += i**2 print (s)
calcule la somme des 5 premiers entiers impairs au carré (2)
s = 0 for b in range(1,5) : i = 2*b+1 s += i**2 print (s)
somme des qui 10 premmières factorielles
s = 0 f = 1 for i in range(1,11) : f *= i s += f print (s)
types très simples
i = 3 # entier = type numérique (type int) r = 3.3 # réel = type numérique (type float) s = "exemple" # chaîne de caractères = type str (exemple n'est pas une variable) n = None # None signifie que la variable existe mais qu'elle ne contient rien # elle est souvent utilisée pour signifier qu'il n'y a pas de résultat # car... une erreur s'est produite, il n'y a pas de résultat # (racine carrée de -1 par exemple)
affectation, print
v = anything # affectation print ( v ) # affichage v1, v2 = 5, 6 # double affectation
format
x,y = 4,5 s = "addition" print ( "{3} de {0} et {1} donne : {0} + {1} = {2}".format (x,y,x+y,s) )
File: seance2_boucle_test_var.tex, line 61
additition de 4 et 5 donne : 4 + 5 = 9
type d'une variable
print ( type ( v ) ) # affiche le type d'une variable print ( isinstance (v, str) ) # pour déterminer si v est de type str
tableaux
c = (4,5) # couple de valeurs (ou tuple) l = [ 4, 5, 6.5] # listes de valeurs ou tableaux x = l [0] # obtention du premier élément de la liste l y = c [1] # obtention du second élément le = [ ] # un tableau vide
tableau : ajouter supprimer
l = [ 4, 5 ] l += [ 6 ] # ajouter un élément l.append ( 7 ) # ajouter un élément l.insert (1, 8) # insérer un élément en seconde position del l [0] # supprimer un élément del l [0:2] # supprimer les deux premiers éléments
tableau : longueur d'un tableau et autres
l = [ 4, 5, 6 ] print ( len(l) ) # affiche la longueur du tableau print ( max(l) ) # affiche le plus grand élément s = l * 3 # création de la liste [ 4, 5, 6, 4, 5, 6, 4, 5, 6 ] t = s [ 4:7 ] # extraction de la sous-liste de la position 4 à 7 exclu s [4:7] = [ 4 ] # remplacement de cette liste par [ 4 ]
boucle for
for i in range (0, 10) : # on répète 10 fois print (i) # l'affichage de i # ici, on est dans la boucle # ici, on n'est plus dans la boucle
boucle while
i = 0 while i < 10 : print (i) i += 1
interruption d'une boucle
for i in range (0, 10) : if i == 2 : continue # on passe directement au suivant print (i) if i > 5 : break # interruption définitive
parcours d'une liste
l = [ 5, 3, 5, 7 ] for i in range (0, len(l)) : print ("élément ",i, "=", l [ i ] )
parcours d'une liste sans indice
l = [ 5, 3, 5, 7 ] for v in l : print ("élément ", v )
parcours d'une liste avec enumerate
l = [ 5, 3, 5, 7 ] for i,v in enumerate(l) : print ("élément ",i, "=", v )
programme mystère
l = [ 4, 3, 0, 1, 2 ] i = 0 while l[i] != i : i = l[i] print (i) # que vaut l[i] ?
un test
v = 2 if v == 2 : print ("v est égal à 2") else : print ("v n'est pas égal à 2")
un test tronqué
v = 2 if v == 2 : print ("v est égal à 2")
plusieurs tests
v = 2 if v == 2 : print ("v est égal à 2") elif v > 2 : print ("v est supérieur à 2") else : print ("v est inférieur à 2")
liste non compacte
l = [ ] for i in range (10) : l.append( i*2+1)
liste compacte
l = [ i*2+i for i in range(10) ]
notations abrégée
l = [ i*2 for i in range(0,10) ] print (l) # qu'affiche l ?
un exemple de liste
l = [ 3, 6, 2 , 7, 9 ] x = 7 # ... print ( position )
recherche de la position d'un élément
l = [ 3, 6, 2 , 7, 9 ] x = 7 for i,v in enumerate(l) : if v == x : position = i print ( position )
recherche dichotomique de la position d'un élément
# coding:latin-1 l = [2, 3, 6, 7, 9] # si la liste n'est pas triée, il faut écrire : l.sort () x = 7 a = 0 b = len(l)-1 while a <= b : m = (a+b)//2 # ne pas oublier // sinon la division est réelle if l[m] == x : position = m # ligne A break elif l[m] < x : a = m+1 else : b = m-1 print ( position ) # si le nombre qu'on cherche x n'est pas dans la liste, # le programme produit l'erreur suivante car la ligne A n'est jamais exécutée : """ Traceback (most recent call last): File "seance2_recherche_dicho.py", line 19, in <module> print ( position ) NameError: name 'position' is not defined """ # soit n la longueur de la liste l # le coût d'une recherche simple est en O(n) # le coût d'une recherche dichotomique est en O(ln(n))
import d'un module
import math print (math.cos(1)) from math import cos print (cos(1)) from math import * # cette syntaxe est déconseillée car il est possible qu'une fonction print (cos(1)) # porte le même nom qu'une des vôtres
premier fichier : monmodule.py
import math def fonction_cos_sequence(seq) : return [ math.cos(x) for x in seq ] if __name__ == "__main__" : print ("ce message n'apparaîtra pas toujours")
second fichier : le programme principal
import monmodule print ( monmodule.fonction_cos_sequence ( [ 1, 2, 3 ] )
écrire un fichier texte
mat = ... # matrice de type liste de listes with open ("mat.txt", "w") as f : # création d'un fichier for i in range (0,len (mat)) : # for j in range (0, len (mat [i])) : # f.write ( str (mat [i][j]) + "\t") # f.write ("\n") #
écrire un fichier texte (version condensée)
mat = ... # matrice de type liste de listes with open ("mat.txt", "w") as f : # création d'un fichier f.write ( '\n'.join ( [ '\t'.join( [ str(x) for x in row ] ) for row in mat ] ) )
lecture d'un fichier texte
with open ("mat.txt", "r") as f : # ouverture d'un fichier mat = [ row.strip(' \n').split('\t') for row in f.readlines() ]
contenu d'un répertoire
import os for f in os.listdir('.'): print (f)
téléchargement des discours du président
import pyensae discours = pyensae.download_data('voeux.zip', website = 'xd')
File: seance4_module_fichier_regexp.tex, line 170
[0-9]{4}/[0-9]{2}/[0-9]{2}
File: seance4_module_fichier_regexp.tex, line 174
a{2,10}
téléchargement de discours du président Sarkozy (issue de secours)
#coding:latin-1 import urllib.request, os, os.path def charge_discours () : discours = { } for annee in [2001, 2005, 2006, 2007, 2008, 2009, 1974, 1975, 1979, 1983, 1987, 1989, 1990, 1994] : nom = "VOEUX%02d.txt" % (annee % 100) if os.path.exists (nom) : # si le fichier existe (il a déjà été téléchargé une fois) with open (nom, "r") as f : text = f.read () else : # si le fichier nexiste pas link = "http://www.xavierdupre.fr/enseignement/td_python/" + \ "python_td_minute/data/voeux_presidents/" + nom url = urllib.request.urlopen (link) text = url.read ().decode("latin-1") # on enregistre les données pour éviter de les télécharger une seconde fois with open (nom, "w") as f : f.write (text) discours [annee] = text return discours if __name__ == "__main__" : discours = charge_discours () print ("nombre de discours ", len(discours))
nombres aléatoires
import random alea = [ random.random() for i in range(10) ] print (alea) random.shuffle(alea) print (alea)
dates
from datetime import datetime date1 = datetime(2013,9,9) date0 = datetime(2013,8,1) print (date1 - date0) birth = datetime (1975,8,11) print (birth.weekday()) # lundi
manipulation de colonnes et Excel
with open ("seance4_excel.txt", "r") as f : mat = [ row.strip(' \n').split('\t') for row in f.readlines() ] mat = mat [1:] res = [ [ None ] * 3 for i in range(5) ] for i,j,v in mat : res [ int(j)-1 ] [ int (i)-1 ] = float(v) with open ("seance4_excel_mat.txt", "w") as f : f.write ( '\n'.join ( [ '\t'.join( [ str(x) for x in row ] ) for row in res ] ) )
corrections de l'exercice sur les expressions régulières
import pyensae discours = pyensae.download_data('voeux.zip', website = 'xd') exp = re.compile ("je .{1,60}", re.IGNORECASE) for d,text in discours.items() : je = exp.findall(text) for t in je : print (t) print ("")
recherche des phrases commençant par je (issue de secours)
#coding:latin-1 import urllib.request, os, os.path, re def charge_discours () : discours = { } for annee in [2001, 2005, 2006, 2007, 2008, 2009, 1974, 1975, 1979, 1983, 1987, 1989, 1990, 1994] : nom = "VOEUX%02d.txt" % (annee % 100) if os.path.exists (nom) : # si le fichier existe (il a déjà été téléchargé une fois) with open (nom, "r") as f : text = f.read () else : # si le fichier nexiste pas link = "http://www.xavierdupre.fr/enseignement/td_python/" + \ "python_td_minute/data/voeux_presidents/" + nom url = urllib.request.urlopen (link) text = url.read ().decode("latin-1") # on enregistre les données pour éviter de les télécharger une seconde fois with open (nom, "w") as f : f.write (text) discours [annee] = text return discours if __name__ == "__main__" : discours = charge_discours () print ("nombre de discours ", len(discours)) exp = re.compile ("je .{1,60}", re.IGNORECASE) for d,text in discours.items() : je = exp.findall(text) for t in je : print (t) print ("")
classe Point
class Point : def __init__ (self, x,y) : self.x = x self.y = y
instance Point
p = Point (4,5)
self ou moi
class Point : def __init__ (moi, x,y) : moi.x = x moi.y = y p1 = Point(4,5) # moi désigne p1 ici p2 = Point(6,7) # moi désigne p2 ici
print point
print (p1) # affiche <__main__.Point object at 0x0288E470>
print x,y
print (p1.x, p1.y)
__str__
class Point : def __init__ (moi, x,y) : moi.x = x moi.y = y def __str__(moi): return "point: ({0},{1})".format(moi.x, moi.y) p = Point(4,5) print (p) # affiche point: (4,5)
addition avec __add__
class Point : def __init__ (moi, x,y) : moi.x = x moi.y = y def __str__(moi): return "{0},{1}".format(moi.x, moi.y) def __add__(moi, autre_point) : return Point(moi.x + autre_point.x, moi.y + autre_point.y) p = Point(4,5) print (p + p) # affiche 8,10
classe CarreMagique
class CarreMagique : def __init__(self, ...) : .... def __str__(self) : .... def __add__(self) : ....
méthode norm
class Point : def __init__ (moi, x,y) : moi.x = x moi.y = y def norm(moi) : return (moi.x**2 + moi.y**2) ** 0.5 p = Point(4,5) print (p.norm())
méthode norm
class Point : def __init__ (moi, x,y) : moi.x = x moi.y = y def norm(moi, lx = 2) : return (abs(moi.x)**lx + abs(moi.y)**lx) ** (1.0 / lx) print (p.norm(1)) print (p.norm(2)) print (p.norm(3)) print (p.norm(100))
appel d'une méthode depuis une autre méthode
class Point : def __init__ (moi, x,y) : moi.x = x moi.y = y def norm(moi, lx = 2) : if lx == 0 : return moi.est_nul() else : return (abs(moi.x)**lx + abs(moi.y)**lx) ** (1.0 / lx) def est_nul(moi): return moi.x == 0 and moi.y == 0
classe CarreMagique
class CarreMagique : def __init__(self, coef) : self.mat = [ [ coef[i+j*3] for i in range(3) ] for j in range(3) ] def __str__(self) : return "\n".join ( [ ",".join( [ str(n) for n in row ] ) for row in self.mat ] ) def __add__ (self, carre) : coef = [] for i in range(3) : for j in range(3) : coef.append ( self.mat[i][j] + carre.mat[i][j]) return CarreMagique(coef) c = CarreMagique ( [ 1,3,4, 2,6,9, 8,7,5 ] ) print (c) print (c + c)
fonction est_magique
Fonction \codes{est\_magique}: class CarreMagique : def __init__(self, coef) : self.mat = [ [ coef[i+j*3] for i in range(3) ] for j in range(3) ] def __str__(self) : return "\n".join ( [ ",".join( [ str(n) for n in row ] ) for row in self.mat ] ) def __add__ (self, carre) : coef = [] for i in range(3) : for j in range(3) : coef.append ( self.mat[i][j] + carre.mat[i][j]) return CarreMagique(coef) def somme_ligne_colonne_diagonale(self): tout = [ sum ( ligne ) for ligne in self.mat ] + \ [ sum ( [ self.mat[i][j] for j in range(3) ] ) for i in range(3) ] + \ [ sum ( [ self.mat[i][i] for i in range(3) ] ) ] + \ [ sum ( [ self.mat[2-i][i] for i in range(3) ] ) ] return tout def coefficient_unique(self): d = { } for ligne in self.mat : for c in ligne : d [c] = d.get(c,0) + 1 return len(d) == 9 def est_magique(self): unique = self.coefficient_unique() if not unique : return False somme = self.somme_ligne_colonne_diagonale() return min(somme) == max(somme) c = CarreMagique ( [ 1,1,1, 1,1,1, 1,1,1 ] ) print (c.est_magique()) c = CarreMagique ( [ 1,4,8, 5,2,6, 7,9,3 ] ) print (c.est_magique())
tous les carrés, de façon naïve (1)
def tous_les_carre_naif() : res = [] for a1 in range(9) : for a2 in range(9) : for a3 in range(9) : for b1 in range(9) : for b2 in range(9) : for b3 in range(9) : for c1 in range(9) : for c2 in range(9) : for c3 in range(9) : carre = CarreMagique( [a1,a2,a3, b1,b2,b3, c1,c2,c3 ]) if carre.est_magique() : res.append (carre) print (carre) return res
tous les carrés, de façon naïve (2)
def tous_les_carre_naif2() : # on choisit l'ensemble de tous les tableaux de 9 chiffres compris entre 1 et 9 coef = [ 1 ] * 9 res = [ ] while coef [0] < 10 : carre = CarreMagique(coef) if carre.est_magique() : res.append (carre) print (carre) coef[-1] += 1 if coef[-1] >= 10 : i = len(coef)-1 while coef[i] >= 10 and i > 0 : coef[i] = 1 coef[i-1] += 1 i -= 1
tous les carrés, permutation
#coding:latin-1 def tous_les_carres_permutation( permut = None, pos = 0): if pos == 9 : carre = CarreMagique (permut) if carre.est_magique() : print (carre) print () return [ carre ] else : return [] else : res = [ ] if permut == None : permut = [ i+1 for i in range(9) ] for i in range (pos,9) : # on permute les éléments i et pos a = permut[i] permut[i] = permut[pos] permut[pos] = a res += tous_les_carres_permutation(permut, pos+1) # on effectue la permutation inverse a = permut[i] permut[i] = permut[pos] permut[pos] = a return res res = tous_les_carres_permutation() print ("nombre de carrés", len(res))
mesure du temps d'exécution
import time d = time.clock() res = tous_les_carres_permutation() d = time.clock() - d print ("nombre de carrés", len(res), " en ", d)
carré magique, réduction du nombre de permutations évaluées
def tous_les_carres_permutation_ligne12_meme_somme( permut = None, pos = 0): if pos == 9 : carre = CarreMagique (permut) if carre.est_magique() : #print (carre) #print () return [ carre ] else : return [] else : if pos >= 6 : # ajout if sum ( permut[:3]) != sum(permut[3:6]) : # ajout return [ ] # ajout res = [ ] if permut == None : permut = [ i+1 for i in range(9) ] for i in range (pos,9) : # on permute les éléments i et pos a = permut[i] permut[i] = permut[pos] permut[pos] = a res += tous_les_carres_permutation_ligne12_meme_somme(permut, pos+1) # changé # on effectue la permutation inverse a = permut[i] permut[i] = permut[pos] permut[pos] = a return res
parcours des carrés magiques, version complète
#coding:latin-1 class CarreMagique : def __init__(self, coef) : self.mat = [ [ coef[i+j*3] for i in range(3) ] for j in range(3) ] def __str__(self) : return "\n".join ( [ ",".join( [ str(n) for n in row ] ) for row in self.mat ] ) def __add__ (self, carre) : coef = [] for i in range(3) : for j in range(3) : coef.append ( self.mat[i][j] + carre.mat[i][j]) return CarreMagique(coef) def somme_ligne_colonne_diagonale(self): tout = [ sum ( ligne ) for ligne in self.mat ] + \ [ sum ( [ self.mat[i][j] for j in range(3) ] ) for i in range(3) ] + \ [ sum ( [ self.mat[i][i] for i in range(3) ] ) ] + \ [ sum ( [ self.mat[2-i][i] for i in range(3) ] ) ] return tout def coefficient_unique(self): d = { } for ligne in self.mat : for c in ligne : d [c] = d.get(c,0) + 1 return len(d) == 9 def est_magique(self): unique = self.coefficient_unique() if not unique : return False somme = self.somme_ligne_colonne_diagonale() return min(somme) == max(somme) def tous_les_carres_permutation_ligne12_meme_somme( permut = None, pos = 0): if pos == 9 : carre = CarreMagique (permut) if carre.est_magique() : #print (carre) #print () return [ carre ] else : return [] else : if pos >= 6 : # ajout if sum ( permut[:3]) != sum(permut[3:6]) : # ajout return [ ] # ajout res = [ ] if permut == None : permut = [ i+1 for i in range(9) ] for i in range (pos,9) : # on permute les éléments i et pos a = permut[i] permut[i] = permut[pos] permut[pos] = a res += tous_les_carres_permutation_ligne12_meme_somme(permut, pos+1) # changé # on effectue la permutation inverse a = permut[i] permut[i] = permut[pos] permut[pos] = a return res import time d = time.clock() res = tous_les_carres_permutation_ligne12_meme_somme() d = time.clock() - d print ("nombre de carrés", len(res), " en ", d)
obtenir les données
import pyensae file = pyensae.download_data("velib_vanves.zip", website = "xd") print (file) # affiche ['velib_vanves.txt']
aperçu des données
address available_bike_stands available_bikes banking bike_stands bonus contract_name last_update lat lng name number status idr 112 RUE VERCINGETORIX - 75014 PARIS 65 2 0 67 0 Paris 15/07/2013 15:00 48,83425925 2,313391647 14029 - GERGOVIE VERCINGETORIX 14029 OPEN 669 112 RUE VERCINGETORIX - 75014 PARIS 65 2 0 67 0 Paris 15/07/2013 15:05 48,83425925 2,313391647 14029 - GERGOVIE VERCINGETORIX 14029 OPEN 1898 112 RUE VERCINGETORIX - 75014 PARIS 66 1 0 67 0 Paris 15/07/2013 15:10 48,83425925 2,313391647 14029 - GERGOVIE VERCINGETORIX 14029 OPEN 3127 112 RUE VERCINGETORIX - 75014 PARIS 66 1 0 67 0 Paris 15/07/2013 15:15 48,83425925 2,313391647 ,.,
lecture des données avec pandas
import pandas df = pandas.read_table(file, header = False, sep = "\t", decimal = ",")
accéder ou modifier une place de données
une_colonne = df.ix[:,"available_bikes"])
accéder ou modifier une place de données
mx_col = df["available_bikes"].max() # maximum d'une colonne mx_col = df.ix[:,"available_bikes"].max() # même maximum, autre écriture mx = df.max() # maximum sur toutes les colonnes
décrire un dataframe
df.describe()
nombre de ligne d'un dataframe
len(df)
sous-ensemble d'un dataframe vérifiant une condition
zero = df [ df["available_bikes"]==0 ]
ajouter deux colonnes
add = df["available_bikes"] + df["available_bike_stands"]
visualisation des données avec pandas
df = df.set_index("last_update") # on identifie chaque ligne avec une date import matplotlib.pyplot as plt # module matplotblig ts = df.ix[:,"available_bikes"] # on extrait la série à dessiner ts.plot() # on dessine plt.show() # on affiche le dessin
sélection de deux colonnes
df2 = df.ix[:, ["last_update","available_bikes"]]
opérations avec les objets datetime
import datetime d = datetime.datetime.now() print (d.weekday()) print (d.strftime("%H:%M")) print (d.isocalendar())
exercice 1 : matrix de numpy
mat = numpy.matrix ( [ 0.0, 0.1, 0.3, 0.4 ] ).transpose() # crée une matrice 4x1 print (mat [ 1:-1,:] ) # enlève la première et la dernière ligne mat = mat + mat * 2.4 # fait des additions avec cette matrice
exercice 2 : conversion d'un DataFrame sous Excel
piv.to_excel("pivot.xlsx") # cela nécessite le module openpyxl # si celui n'est pas installé, il faut enregistré le fichier au format texte piv.to_csv("pivot.txt", sep="\t")
exercice 2 : ajout de valeur NaN
piv.ix['4-16:00':,31] = numpy.NaN # vous pouvez vérifier que sous Excel (en utilisant les lignes précédentes), # les cellules sont vides.
exercice 2 : autres fonctionnalités utiles
# on crée une matrice de type numpy.array mx = numpy.array ( [ [ 10.0, 1.0], [2.0, 3.] ] ) # on calcule la moyenne de la première colonne print ( numpy.average( mx[:,0] )) # on remplace la première valeur par NaN mx[0,0] = numpy.NaN # on calcule la moyenne de la première colonne sans les valeurs NaN print ( numpy.average( mx[~numpy.isnan(mx[:,0]),0]) ) # on utilise la fonction isnan car numpy.NaN != numpy.NaN est vrai print ( numpy.NaN != numpy.NaN ) # aussi surprenant que cela soit # on parcourt toutes les dates de la matrice obtenue après pivot : for i,k in enumerate(piv.index) : print (i,k)
lire les données
import pandas df = pandas.read_table(file, header = False, sep = "\t", decimal = ",", parse_dates = ["last_update"], date_parser = lambda s : datetime.datetime.strptime (s, "%d/%m/%Y %H:%M"))
la première et la dernière dates
print ("min_date", df["last_update"].min()) print ("max_date", df["last_update"].max())
le nombre maximum de vélos et de places vides
print ("max velo", df["available_bikes"].max()) print ("max_place", df["available_bike_stands"].max())
la proportion du temps durant lequel la station n'a pas de vélos disponibles
print ("pas de vélo", len(df [ df["available_bikes"]==0 ]) / len(df) )
la proportion du temps durant lequel la station n'a pas de places disponibles
print ("pas de place", len(df [ df["available_bike_stands"]==0 ]) / len(df) )
le nombre d'emplacements de vélos à cette station
add = df["available_bikes"] + df["available_bike_stands"] print (add.max())
visualisation des données avec pandas
import matplotlib.pyplot as plt df = df.set_index("last_update") ts = df.ix[:,"available_bikes"] ts.plot() plt.show()
seconde visualisation avec matplotlib
import numpy from matplotlib.mlab import csv2rec import matplotlib.pyplot as plt import matplotlib.cbook as cbook from matplotlib.ticker import Formatter class MyFormatter(Formatter): def __init__(self, dates, fmt='%Y-%m-%d'): self.dates = dates self.fmt = fmt def __call__(self, x, pos=0): 'Return the label for time x at position pos' ind = int(round(x)) if ind>=len(self.dates) or ind<0: return '' return self.dates[ind].strftime(self.fmt) formatter = MyFormatter(df["last_update"]) fig, ax = plt.subplots() ax.xaxis.set_major_formatter(formatter) ax.plot(numpy.arange(len(ts)), ts, '-') fig.autofmt_xdate() plt.show()
ajouter une colonne contenant le jour de la semaine et l'heure
df2["weekday"] = df2['last_update'].map(lambda d: str(d.weekday()) + "-" + d.strftime("%H:%M"))
aligner les données par jour de la semaine
df2["weekno"] = df2['last_update'].map(lambda d: d.isocalendar()[1]) sp = "available_bikes weekday weekno".split() sem = df2.ix[:,sp] piv = sem.pivot ('weekday', "weekno", "available_bikes") piv.plot() # pour visualiser les données plt.show()
exercice 1 : lissage
# on somme la série complète 12 fois mais décalé à chaque fois nbperiod = 12 mat = numpy.matrix ( [0.0] * (len( df2 ) - nbperiod+1) ).transpose() for i in range(0,nbperiod) : r = df2.ix[i:len(df2)-nbperiod+i,'available_bikes'] m = numpy.matrix(list(r)).transpose() mat += m mat /= 1.0 * nbperiod # on élimine les premières et dernières valeurs df2 = df2[nbperiod/2:-nbperiod/2+1] df2["lisse"] = mat # on répète la même manipulation pour superposer les semaines sp = "lisse weekday weekno".split() sem = df2.ix[:,sp] piv = sem.pivot ('weekday', "weekno", "lisse") piv.plot() plt.show()
exercice 1 : lissage avec les fonctions évoluées de pandas
df2 = df.ix[:, ["last_update","available_bikes"]] # on ajoute une colonne lissage qui contient la moyenne mobile sur 12 périodes via la fonction rolling_mean df2["lissage"] = pandas.stats.moments.rolling_mean(df2["available_bikes"],12) # on fait la meme transformation que dans l'exercice précédent pour afficher la valeur lissée par semaine, par timebox df2["weekday"] = df2['last_update'].map(lambda d: str(d.weekday()) + "-" + d.strftime("%H:%M")) df2["weekno"] = df2['last_update'].map(lambda d: d.isocalendar()[1]) serietemp = df2.ix[:,["lissage","weekday","weekno"]] piv = serietemp.pivot ("weekday", "weekno", "lissage") piv.plot() # pour visualiser les données plt.show()
exercice 2 : données manquantes
beg = "4-16:00" piv = thispiv piv.ix[beg:,31] = numpy.NaN mx = numpy.array(piv.as_matrix()) for i,k in enumerate(piv.index) : if k >= beg and numpy.isnan(piv.ix[k,31]): ave_week = numpy.average( mx[~numpy.isnan(mx[:,2]),2]) ave_hour = numpy.average( mx[i, ~numpy.isnan(mx[i,:])] ) piv.ix[k,31] = (ave_week*ave_hour)**0.5 piv.plot() plt.show()
obtenir les données
from pyensae import download_data download_data("SQLiteSpy.zip", website = 'xd') # 2 secondes download_data("td8_velib.zip", website = 'xd') # 22 secondes (~7 Mo)
obtenir les données
from pyensae import import_flatfile_into_database dbf = "td8_velib.db3" import_flatfile_into_database(dbf, "td8_velib.txt") # 2 secondes import_flatfile_into_database(dbf, "stations.txt", table="stations") # 2 minutes
obtenir les données (2)
from pyensae import download_data download_data("td8_velib.db3.zip", website = 'xd') # 40 secondes (~12 Mo)
SELECT ... WHERE
-- sélectionner les données sur une plage horaire donnée SELECT * FROM td8_velib WHERE last_update >= '2013-09-13 10:00:00' AND last_update <= '2013-09-13 11:00:00' -- sélectionner certaines colonnes et ordonner les valeurs SELECT available_bike_stands, available_bikes FROM td8_velib WHERE last_update >= '2013-09-13 10:00:00' AND last_update <= '2013-09-13 11:00:00' ORDER BY available_bike_stands DESC ; -- compter le nombre d'emplacements de chaque station SELECT last_update, available_bike_stands + available_bikes AS place, number FROM td8_velib WHERE last_update >= '2013-09-13 10:00:00' AND last_update <= '2013-09-13 11:00:00' ORDER BY place DESC ;
SELECT ... MIN, MAX
-- maximum de vélos disponibles sur toutes la base SELECT MAX(available_bike_stands) FROM td8_velib -- minimum, maximum de vélos disponibles sur toutes la base SELECT MIN(available_bike_stands) FROM td8_velib UNION ALL SELECT MAX(available_bike_stands) FROM td8_velib -- ajouter des informations SELECT "min" AS label, MIN(available_bike_stands) FROM td8_velib UNION ALL SELECT "max" AS label, MAX(available_bike_stands) FROM td8_velib
SELECT DISTINCT COUNT FROM
-- tous les numéros de stations de façon unique SELECT DISTINCT number FROM td8_velib -- compter le nombre de stations (1230) SELECT COUNT(*) FROM ( SELECT DISTINCT number FROM td8_velib )
nombre de vélo par date
SELECT last_update, SUM(available_bikes) AS velo_disponible FROM td8_velib GROUP BY last_update ORDER BY last_update
GROUP BY, COUNT, DISTINCT
SELECT last_update, SUM(available_bikes) AS velo_disponible, COUNT(DISTINCT number) AS stations FROM td8_velib --WHERE last_update >= "2013-09-10 11:30:19" GROUP BY last_update ORDER BY last_update
deux clés
SELECT last_update, CASE WHEN available_bikes>0 THEN 1 ELSE 0 END AS vide, COUNT(*) AS nb FROM td8_velib WHERE last_update >= "2013-09-10 11:30:19" GROUP BY last_update, vide ORDER BY last_update
intersection entre deux tables
SELECT A.*, B.name -- ajout du nom au bout de chaque ligne FROM td8_velib AS A JOIN stations AS B ON A.number == B.number
distribution temporelle
SELECT A.*, 1.0 * A.available_bikes / B.nb_velo AS distribution_temporelle FROM td8_velib AS A JOIN ( SELECT number, SUM(available_bikes) AS nb_velo FROM td8_velib WHERE last_update >= "2013-09-10 11:30:19" GROUP BY number ) AS B ON A.number == B.number WHERE A.last_update >= "2013-09-10 11:30:19"
lire des données depuis une base de données SQLite3
import sqlite3 conn = sqlite3.connect(dbf) # on ouvre une connexion sur la base de données data = conn.execute("SELECT * FROM stations") #on exécute une requête SQL for d in data : # on affiche le résultat print (d) # conn.close() # on ferme la connexion
compter le nombre de dates distinctes
SELECT COUNT(*) FROM ( SELECT DISTINCT last_update FROM td8_velib ) ;
première et dernière date
SELECT MIN(last_update), MAX(last_update) FROM td8_velib ;
exercice 2
SELECT number, COUNT(*) AS nb FROM td8_velib WHERE available_bikes==0 AND last_update >= '2013-09-10 11:30:19' GROUP BY number ORDER BY nb DESC
exercice 3 : plage horaires de cinq minutes où il n'y a aucun vélo disponible
SELECT nb, COUNT(*) AS nb_station FROM ( -- requête de l'exercice précédent SELECT number, COUNT(*) AS nb FROM td8_velib WHERE available_bikes==0 AND last_update >= '2013-09-10 11:30:19' GROUP BY number ) GROUP BY nb
exercice 4 : distribution horaire par station et par tranche de 5 minutes
SELECT A.number, A.heure, A.minute, 1.0 * A.nb_velo / B.nb_velo_tot AS distribution_temporelle FROM ( SELECT number, heure, minute, SUM(available_bikes) AS nb_velo FROM td8_velib WHERE last_update >= '2013-09-10 11:30:19' GROUP BY heure, minute, number ) AS A JOIN ( SELECT number, heure, minute, SUM(available_bikes) AS nb_velo_tot FROM td8_velib WHERE last_update >= '2013-09-10 11:30:19' GROUP BY number ) AS B ON A.number == B.number --WHERE A.number in (8001, 8003, 15024, 15031) -- pour n'afficher que quelques stations ORDER BY A.number, A.heure, A.minute
Zone de travail et zone de résidence
SELECT number, SUM(distribution_temporelle) AS velo_jour FROM ( -- requête de l'exercice 4 SELECT A.number, A.heure, A.minute, 1.0 * A.nb_velo / B.nb_velo_tot AS distribution_temporelle FROM ( SELECT number, heure, minute, SUM(available_bikes) AS nb_velo FROM td8_velib WHERE last_update >= '2013-09-10 11:30:19' GROUP BY heure, minute, number ) AS A JOIN ( SELECT number, heure, minute, SUM(available_bikes) AS nb_velo_tot FROM td8_velib WHERE last_update >= '2013-09-10 11:30:19' GROUP BY number ) AS B ON A.number == B.number ) WHERE heure >= 10 AND heure <= 16 GROUP BY number
JOIN avec la table stations et les stations "travail"
SELECT C.number, name, lat, lng, velo_jour FROM ( -- requête de la partie précédente SELECT number, SUM(distribution_temporelle) AS velo_jour FROM ( -- requête de l'exercice 4 SELECT A.number, A.heure, A.minute, 1.0 * A.nb_velo / B.nb_velo_tot AS distribution_temporelle FROM ( SELECT number, heure, minute, SUM(available_bikes) AS nb_velo FROM td8_velib WHERE last_update >= '2013-09-10 11:30:19' GROUP BY heure, minute, number ) AS A JOIN ( SELECT number, heure, minute, SUM(available_bikes) AS nb_velo_tot FROM td8_velib WHERE last_update >= '2013-09-10 11:30:19' GROUP BY number ) AS B ON A.number == B.number ) WHERE heure >= 10 AND heure <= 16 GROUP BY number ) AS C INNER JOIN stations ON C.number == stations.number
récupération des données velib pour ce TD
from pyensae import download_data import pandas download_data("td9_data.zip", website = 'xd') file1 = "td9_full.txt" tbl = pandas.read_csv (file1, sep = "\t")
premier graphe
import pylab from pandas.tools.plotting import scatter_plot gr = tbl.groupby(['lat','lng'], as_index = False).agg(lambda x: len(x)) scatter_plot(gr, "lat", "lng" ) pylab.show()
fichier osm_essai.html
<html><body> <div id="mapdiv"></div> <script src="http://www.openlayers.org/api/OpenLayers.js"></script> <script> map = new OpenLayers.Map("mapdiv"); map.addLayer(new OpenLayers.Layer.OSM()); var proj = new OpenLayers.Projection("EPSG:4326"); var zoom=16; var markers = new OpenLayers.Layer.Markers( "Markers" ); map.addLayer(markers); var lonLat = new OpenLayers.LonLat( -0.1279688 ,51.5077286 ).transform(proj, map.getProjectionObject() ); markers.addMarker(new OpenLayers.Marker(lonLat)); var lonLat2 = new OpenLayers.LonLat( -0.1279688 ,51.5067286 ).transform(proj, map.getProjectionObject() ); markers.addMarker(new OpenLayers.Marker(lonLat2)); map.setCenter (lonLat, zoom); </script> </body></html>
fichier osm_essai.html
# ... ajouter des choses ici lines = [ ] for i,row in enumerate(gr.values) : y = lat = row[1] x = lng = row[0] # utiliser i,x,y pour construire la ligne de javascript correspondant à la station i lines.append(line) text = "\n".join( lines ) html = html.replace("__VELIB__", text) with open("velib.html", "w") as f : f.write(html)
lancer directement le navigateur
import webbrowser webbrowser.open(<url>)
File: seance9_d3js.tex, line 134
agatha,frank agatha,toni alice,andrew alice,april alice,bette ...
File: seance9_d3js.tex, line 145
var links = [ {source: "Microsoft", target: "Amazon", type: "licensing"}, {source: "Microsoft", target: "HTC", type: "licensing"}, {source: "Samsung", target: "Apple", type: "suit"}, // ... ] ;
conversion des données d'un fichier texte au javascript
with open("td9_graph_lworld.txt", "r") as f : lines = f.readlines() links =[] for line in lines : spl = line.strip("\n\r ").split(",") if len(spl) == 2 : l = { "source":spl[0],"target":spl[1],"type":"-"} links.append(l) l = { "source":spl[1],"target":spl[0],"type":"-"} links.append(l) with open("td9_graph_lworld.js", "w") as f : f.write ("var links = [\n") for l in links : f.write("{") f.write( ",".join ( [ "{0}:'{1}'".format (k,v) for k,v in l.items() ] ) ) f.write("},\n") f.write("\n];\n")
lancer directement le navigateur
import pyensae pyensae.download_data("td9_graph_lworld.zip", website = 'xd')
astuce pour modifier le texte et sa taille
// bien placé, le code suivant modifie le texte affiché et sa taille d3.select(this) .select("text") .style("font-size", "10px") .text(function(d,i){return d.name + "**" ;});
Utilisation d'OpenStreetMap pour visualiser des données
#coding:latin-1 import sys sys.path.append("../../../../program/python/pyensae/src") # ligne inutile from pyensae import download_data import pandas download_data("td9_data.zip", website = 'xd') file1 = "td9_full.txt" tbl = pandas.read_csv (file1, sep = "\t") from pandas.tools.plotting import scatter_plot gr = tbl.groupby(['lng','lat'], as_index = False).agg(lambda x: len(x)) # voir http://dev.openlayers.org/docs/files/OpenLayers/Marker-js.html pour changer le marker html = """ <html><body> <div id="mapdiv"></div> <script src="http://www.openlayers.org/api/OpenLayers.js"></script> <script> map = new OpenLayers.Map("mapdiv"); map.addLayer(new OpenLayers.Layer.OSM()); var proj = new OpenLayers.Projection("EPSG:4326"); var zoom=13; var markers = new OpenLayers.Layer.Markers( "Markers" ); map.addLayer(markers); __VELIB__ map.setCenter (lonLat0, zoom); </script> </body></html> """ position =""" var lonLat{0} = new OpenLayers.LonLat( {1} ,{2} ).transform(proj, map.getProjectionObject() ); markers.addMarker(new OpenLayers.Marker(lonLat{0})); """ lines = [ ] for i,row in enumerate(gr.values) : y = lat = row[1] x = lng = row[0] line = position.format(i,x,y) lines.append(line) text = "\n".join( lines ) html = html.replace("__VELIB__", text) with open("velib.html", "w") as f : f.write(html)
Les stations Vélib dans les zones de travail
#coding:latin-1 import sys sys.path.append("../../../../program/python/pyensae/src") # ligne inutile from pyensae import download_data import pandas download_data("td9_data.zip", website = 'xd') file1 = "td9_full.txt" tbl = pandas.read_csv (file1, sep = "\t") from pandas.tools.plotting import scatter_plot gr = tbl.groupby(['lng','lat'], as_index = False).agg(lambda x: len(x)) # voir http://dev.openlayers.org/docs/files/OpenLayers/Marker-js.html pour changer le marker html = """ <html><body> <div id="mapdiv"></div> <script src="http://www.openlayers.org/api/OpenLayers.js"></script> <script> map = new OpenLayers.Map("mapdiv"); map.addLayer(new OpenLayers.Layer.OSM()); var proj = new OpenLayers.Projection("EPSG:4326"); var zoom=13; var markers = new OpenLayers.Layer.Markers( "Markers" ); map.addLayer(markers); __VELIB__ map.setCenter (lonLat0, zoom); </script> </body></html> """ position =""" var lonLat{0} = new OpenLayers.LonLat( {1} ,{2} ).transform(proj, map.getProjectionObject() ); markers.addMarker(new OpenLayers.Marker(lonLat{0})); """ lines = [ ] for i,row in enumerate(gr.values) : y = lat = row[1] x = lng = row[0] line = position.format(i,x,y) lines.append(line) text = "\n".join( lines ) html = html.replace("__VELIB__", text) with open("velib.html", "w") as f : f.write(html)
Le réseau L-World
<!DOCTYPE html> <meta charset="utf-8"> <script src="http://d3js.org/d3.v2.js?2.9.1"></script> <script src="td9_graph_lworld.js"></script> <style> .link { fill: none; stroke: #666; stroke-width: 1.5px; } .node circle { fill: #ccc; stroke: #fff; stroke-width: 1.5px; } text { font: 10px sans-serif; pointer-events: none; } </style> <body> <script> var nodes = {}; // Compute the distinct nodes from the links. links.forEach(function(link) { link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); link.target = nodes[link.target] || (nodes[link.target] = {name: link.target}); }); var width = 960, height = 500; var force = d3.layout.force() .nodes(d3.values(nodes)) .links(links) .size([width, height]) .linkDistance(60) .charge(-300) .on("tick", tick) .start(); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var link = svg.selectAll(".link") .data(force.links()) .enter().append("line") .attr("class", "link"); var node = svg.selectAll(".node") .data(force.nodes()) .enter().append("g") .attr("class", "node") .call(force.drag); node.append("circle") .attr("r", 8); node.append("text") .attr("x", 12) .attr("dy", ".35em") .text(function(d) { return d.name; }); function tick() { link .attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); node .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); } </script>
Le réseau L-World avec des événements
<!DOCTYPE html> <meta charset="utf-8"> <script src="http://d3js.org/d3.v2.js?2.9.1"></script> <script src="td9_graph_lworld.js"></script> <style> .link { fill: none; stroke: #666; stroke-width: 1.5px; } .node circle { fill: #ccc; stroke: #fff; stroke-width: 1.5px; } text { font: 10px sans-serif; pointer-events: none; } </style> <body> <script> var nodes = {}; // Compute the distinct nodes from the links. links.forEach(function(link) { link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); link.target = nodes[link.target] || (nodes[link.target] = {name: link.target}); }); var width = 960, height = 800; var force = d3.layout.force() .nodes(d3.values(nodes)) .links(links) .size([width, height]) .linkDistance(30) .charge(-300) .on("tick", tick) .start(); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var link = svg.selectAll(".link") .data(force.links()) .enter().append("line") .attr("class", "link"); var node = svg.selectAll(".node") .data(force.nodes()) .enter().append("g") .attr("class", "node") .on("mouseover", mouseover) // on ajoute deux événements: la souris passe au-dessus d'un noeud .on("mouseout", mouseout) // la sortie sort de la zone du noeud .call(force.drag); // pour qu'on puisse tirer les noeuds node.append("circle") .attr("r", 8); node.append("text") .attr("x", 12) .attr("dy", ".35em") .text(function(d) { return d.name; }) .style("font-size", "10px") ; function tick() { link .attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); node .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); } // la fonction suivante définit ce qui doit se passe au cas où le curseur passe au-dessus d'un noeud function mouseover() { d3.select(this) .select("text") .style("font-size", "30px") .text(function(d,i){return "** " + d.name + " **" ;}); d3.select(this) .style("fill", "red") .select("circle").transition() .duration(750) .attr("r", 16) .style("fill", "yellow"); } // la fonction suivante définit ce qui doit se passe au cas où le curseur sort de la zone du noeud function mouseout() { d3.select(this) .select("text") .style("font-size", "10px") .text(function(d,i){return d.name ;}); d3.select(this) .style("fill", "grey") .select("circle").transition() .duration(350) .attr("r", 8) .style("fill", "grey"); } </script>
Le fichier HTML contenant le code javascript.
<!DOCTYPE html> <!-- http://jsfiddle.net/KSAbK/1/ --> <!-- https://leanpub.com/D3-Tips-and-Tricks/read --> <meta charset="utf-8"> <style> body { font: 10px sans-serif; } .plot { fill: rgba(250, 250, 255, 0.6); } .grid .tick { stroke: lightgrey; opacity: 0.7; } .grid path { stroke-width: 0; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .x.axis path { display: none; } .line { fill: none; stroke: steelblue; stroke-width: 1.5px; } </style> <body> <script src="http://d3js.org/d3.v3.js"></script> <script src="td9_by_hours_data.js"></script> <!-- the data, contains the variable data used by the following script, it looks like the following --> <!-- data = [ {'velo': 12817.0, 'last_update': '10/9/13 11:35', 'minute': 35.0, 'heure': 11.0, 'place': 25202.0, 'name': '10/9/13 11:35', 'roulant': 225.0, 'somme': 38019.0} ,{'velo': 12744.0, 'last_update': '10/9/13 11:40', 'minute': 40.0, 'heure': 11.0, 'place': 25273.0, 'name': '10/9/13 11:40', 'roulant': 227.0, 'somme': 38017.0} ... ] ; --> <script> // defines the graph area (usually the same for for every graph) margin = { top: 20, right: 20, bottom: 20, left: 45 }; width = 800 - margin.left - margin.right; height = 500 - margin.top - margin.bottom; // defines the range of each axis var x = d3.time.scale() .domain(d3.extent(data, function (d) { return d.last_update; })) .range([0, width]); var y = d3.scale.linear() .domain(d3.extent(data, function (d) { return d.velo; })) .range([height, 0]); // graph type, also defines the columns to be used (last_update and velo in this case) var line = d3.svg.line() .x(function (d) { return x(d.last_update); }) .y(function (d) { return y(d.velo); }); // defines the function to call when zooming var zoom = d3.behavior.zoom() .x(x) //.y(y) .on("zoom", zoomed); // creates a svg section in the body section svg = d3.select('body') .append("svg") .attr('width', width + margin.left + margin.right) .attr('height', height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") .call(zoom); svg.append("rect") .attr("width", width) .attr("height", height) .attr("class", "plot"); // two functions uses for the zoom var make_x_axis = function () { return d3.svg.axis() .scale(x) .orient("bottom") .ticks(5); }; var make_y_axis = function () { return d3.svg.axis() .scale(y) .orient("left") .ticks(10); }; // defines the axis var xAxis = d3.svg.axis() .scale(x) .orient("bottom") .ticks(10); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0, " + height + ")") .call(xAxis); var yAxis = d3.svg.axis() .scale(y) .orient("left") .ticks(10); svg.append("g") .attr("class", "y axis") .call(yAxis); svg.append("g") .attr("class", "x grid") .attr("transform", "translate(0," + height + ")") .call(make_x_axis() .tickSize(-height, 0, 0) .tickFormat("")); svg.append("g") .attr("class", "y grid") .call(make_y_axis() .tickSize(-width, 0, 0) .tickFormat("")); // objects for the zooming var clip = svg.append("clipPath") .attr("id", "clip") .append("rect") .attr("x", 0) .attr("y", 0) .attr("width", width) .attr("height", height); var chartBody = svg.append("g") .attr("clip-path", "url(#clip)"); chartBody.append("path") .datum(data) .attr("class", "line") .attr("d", line); // zooming functions function zoomed() { //console.log(d3.event.translate); // display information in the logging console of the browser (using developping tools) //console.log(d3.event.scale); svg.select(".x.axis").call(xAxis); svg.select(".y.axis").call(yAxis); svg.select(".x.grid") .call(make_x_axis() .tickSize(-height, 0, 0) .tickFormat("")); svg.select(".y.grid") .call(make_y_axis() .tickSize(-width, 0, 0) .tickFormat("")); svg.select(".line") .attr("class", "line") .attr("d", line); } </script> </body> </html>
données incluses dans un script javascript
data = [ {'velo': 12817.0, 'last_update': '10/9/13 11:35', 'minute': 35.0, 'heure': 11.0, 'place': 25202.0, 'name': '10/9/13 11:35', 'roulant': 225.0, 'somme': 38019.0} ,{'velo': 12744.0, 'last_update': '10/9/13 11:40', 'minute': 40.0, 'heure': 11.0, 'place': 25273.0, 'name': '10/9/13 11:40', 'roulant': 227.0, 'somme': 38017.0} ,{'velo': 12674.0, 'last_update': '10/9/13 11:45', 'minute': 45.0, 'heure': 11.0, 'place': 25349.0, 'name': '10/9/13 11:45', 'roulant': 221.0, 'somme': 38023.0} ,{'velo': 12646.0, 'last_update': '10/9/13 11:50', 'minute': 50.0, 'heure': 11.0, 'place': 25380.0, 'name': '10/9/13 11:50', 'roulant': 218.0, 'somme': 38026.0} ,{'velo': 12568.0, 'last_update': '10/9/13 11:55', 'minute': 55.0, 'heure': 11.0, 'place': 25457.0, 'name': '10/9/13 11:55', 'roulant': 219.0, 'somme': 38025.0} // ... ] ; var parseDate = d3.time.format("%d/%m/%Y %H:%M").parse; for (var i = 0; i < data.length; i++) { element = data[i] ; element['last_update'] = parseDate(element['last_update']) ; }
récupération des données pour le plus court chemin
import pyensae pyensae.download_data("matrix_distance_7398.zip", website = "xd")
File: seance10_pdyn.tex, line 30
Boulogne-Billancourt Beauvais 85597 Courbevoie Sevran 26564 Colombes Alfortville 36843 Bagneux Marcq-En-Baroeul 233455 ...
lire le fichiers des distance avec pandas
import pandas df = pandas.read_csv("matrix_distance_7398.txt", sep="\t") print (df.head())
choix aléatoires des skieurs et des paires
import random skieur = [ random.gauss(1.75, 0.1) for i in range(0,10) ] paires = [ random.gauss(1.75, 0.1) for i in range(0,15) ] skieurs.sort() paires.sort()
récupération de la liste des villes (sans doublons)
vil = { } for row in df.values : vil [row[0]] = 0 vil [row[1]] = 1 vil = list(vil.keys()) print (len(vil))
construction d'un dictionnaire { (a,b):d, (b,a):d }
dist = { } for row in df.values : a = row[0] b = row[1] dist[a,b] = dist[b,a] = row[2] print (len(dist))
distance Charleville-Mezieres --> Bordeaux
print ( dist["Charleville-Mezieres","Bordeaux"] )
initialisation du tableau d
d = { } d['Charleville-Mezieres'] = 0 for v in vil : d[v] = 1e10 for v,w in dist : if v == 'Charleville-Mezieres': d[w] = dist[v,w]
une itération de l'algorithme de Dikjstra
for v,w in dist : d2 = d[v] + dist[v,w] if d2 < d[w] : d[w] = d2
l'algorithme de Dikjstra
for i in range(0,len(d)) : for v,w in dist : d2 = d[v] + dist[v,w] if d2 < d[w] : d[w] = d2
coût de la meilleure distribution des skis
p = { } p [-1,-1] = 0 for n,taille in enumerate(skieurs) : p[n,-1] = p[n-1,-1] + taille for m,paire in enumerate(paires ) : p[-1,m] = 0 for n,taille in enumerate(skieurs) : for m,paire in enumerate(paires) : p1 = p.get ( (n ,m-1), 1e10 ) p2 = p.get ( (n-1,m-1), 1e10 ) + abs(taille - paire) p[n,m] = min(p1,p2) print (p[len(skieurs)-1,len(paires)-1])
récupération de la meilleure distribution
p = { } p [-1,-1] = 0 best = { } for n,taille in enumerate(skieurs) : p[n,-1] = p[n-1,-1] + taille for m,paire in enumerate(paires ) : p[-1,m] = 0 for n,taille in enumerate(skieurs) : for m,paire in enumerate(paires) : p1 = p.get ( (n ,m-1), 1e10 ) p2 = p.get ( (n-1,m-1), 1e10 ) + abs(taille - paire) p[n,m] = min(p1,p2) if p[n,m] == p1 : best [n,m] = n,m-1 else : best [n,m] = n-1,m-1 print (p[len(skieurs)-1,len(paires)-1]) chemin = [ ] pos = len(skieurs)-1,len(paires)-1 while pos in best : print (pos) chemin.append(pos) pos = best[pos] chemin.reverse() print (chemin)
construction aléatoire d'un mot
import random def mot_alea (l) : l = [ chr(97+random.randint(0,25)) for i in range(l) ] return "".join(l)
mesure du temps
for k in cherche : i = mots.index(k)
construction aléatoire d'un mot
import random def mot_alea (l) : l = [ chr(97+random.randint(0,25)) for i in range(l) ] return "".join(l) taille = 20 N = 100000 mots = [ mot_alea(10) for _ in range (N) ]
mesure du temps recherche simple
import time debut = time.clock() for k in cherche : i = mots.index(k) fin = time.clock() print ("recherche simple",fin - debut)
mesure du temps recherche dichotomique
# recherche dichotomique def dicho (mots, x) : a = 0 b = len(mots)-1 while a < b : m = (a+b)//2 t = mots[m] if t < x : b = m-1 elif t == m : return else : a = m+1 return a mots.sort() debut = time.clock() for k in cherche : i = dicho(mots, k) fin = time.clock() print ("dichotomie",fin - debut)
construction du trie
def build_trie(mots) : trie = { } for m in mots : r = trie for c in m : if c not in r : r[c] = { } r = r[c] return trie
rechercher dans le trie
def lookup(trie, m) : r = trie for c in m : if c in r : r = r[c] else : return False return True
mesurer du temps pour le trie
debut = time.clock() for k in cherche : i = lookup(trie, k) fin = time.clock()
programme pour mesurer les différents temps de recherche
import random, time def mot_alea (l) : l = [ chr(97+random.randint(0,25)) for i in range(l) ] return "".join(l) for N in [100,200,500,1000,2000,5000,10000,20000,50000,100000,200000] : for taille in [5,10,20,50,100] : n = 1000 mots = [ mot_alea(10) for _ in range (N) ] cherche = [ mot_alea(10) for _ in range(0,n) ] mots += cherche if True : # recherche dichotomique def dicho (mots, x) : a = 0 b = len(mots)-1 while a < b : m = (a+b)//2 t = mots[m] if t < x : b = m-1 elif t == m : return else : a = m+1 return a mots.sort() debut = time.clock() for k in cherche : i = dicho(mots, k) fin = time.clock() print ("dichotomie\t",N,"\t",taille,"\t",(fin - debut)/len(cherche)) if True : # recherche dichotomique dico = { m:0 for m in mots } debut = time.clock() for k in cherche : i = dico[k] fin = time.clock() print ("dictionnaire\t",N,"\t",taille,"\t",(fin - debut)/len(cherche)) if True : # trie def build_trie(mots) : trie = { } for m in mots : r = trie for c in m : if c not in r : r[c] = { } r = r[c] return trie def lookup(trie, m) : r = trie for c in m : if c in r : r = r[c] else : return False return True trie = build_trie(mots) debut = time.clock() for k in cherche : assert lookup(trie, k) fin = time.clock() print ("trie\t",N,"\t",taille,"\t",(fin - debut)/len(cherche)) if False : # recherche simple debut = time.clock() for k in cherche : i = mots.index(k) fin = time.clock() print ("recherche simple\t",N,"\t",taille,"\t",(fin - debut)/len(cherche))