Les variables ne sont pas typées
x = 13
x
13
x = "toto"
x
'toto'
type(x)
<type 'str'>
x = 10
if
¶Pas d'accolades {
en Python : c'est l'indentation (espaceement à gauche) qui délimite les blocs. La convention veut que chaque nouveau bloc imbriqué ajoute 4 espaces d'indentation.
if x <= 14:
print "Hello"
x += 5
print x
elif x == 15:
print x
else:
print x - 20
Hello 15
Une condition plus complexe avec des connecteurs logiques et des multi-comparaisons
if x is not None and 5 < x < 100 and (True or False):
print "Oui"
Oui
while
¶x = 75
while x < 100:
x += 1
print x
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Les variables de la boucle while
ne sont pas locales à la boucle
x
100
for
¶L = [1, 2, 10, 15]
for a in L:
b = a + 10
print b
11 12 20 25
Encore une preuve du fait que les variables des boucles ne sont pas locales
a, b
(15, 25)
On peut imbrique les blocs, bien sûr
for x in L:
if x > 10:
print x - 10
else:
print x
1 2 10 5
def tot(a, b):
c = a + b
return c
x = tot(14, 5)
x
19
Les variables d'une fonction sont (généralement) locales à la fonction
c
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-15-2cd6ee2c70b0> in <module>() ----> 1 c NameError: name 'c' is not defined
Puisque l'opérateur +
est polymorphique (il fonctionne sur plusieurs types), la fonction tot
l'est aussi
tot(5.2, 4.1)
9.30000000000000
tot("Hello ", 'world')
'Hello world'
Mais cela ne veut pas dire qu'on peut additionner tout et n'importe quoi: les conversions de type ne sont pas implicite en Python (mais elle le sont parfois en Sage)
tot("Hello", 13)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-18-37d325c0ab11> in <module>() ----> 1 tot("Hello", Integer(13)) <ipython-input-12-957743e6310d> in tot(a, b) 1 def tot(a, b): ----> 2 c = a + b 3 return c /local/SageMath-8.0/src/sage/rings/integer.pyx in sage.rings.integer.Integer.__add__ (/local/SageMath-8.0/src/build/cythonized/sage/rings/integer.c:10936)() 1604 return y 1605 -> 1606 return coercion_model.bin_op(left, right, operator.add) 1607 1608 cpdef _add_(self, right): /local/SageMath-8.0/src/sage/structure/coerce.pyx in sage.structure.coerce.CoercionModel_cache_maps.bin_op (/local/SageMath-8.0/src/build/cythonized/sage/structure/coerce.c:10448)() 1102 # We should really include the underlying error. 1103 # This causes so much headache. -> 1104 raise bin_op_exception(op, x, y) 1105 1106 cpdef canonical_coercion(self, x, y): TypeError: unsupported operand parent(s) for +: '<type 'str'>' and 'Integer Ring'
tot("Hello", str(13))
'Hello13'
tot("Hello", '13')
'Hello13'
A = [1, 2, 3] + [100, 11, 5]
A
[1, 2, 3, 100, 11, 5]
A[3]
100
A.index(100)
3
A[3]
100
A.append(354)
A
[1, 2, 3, 100, 11, 5, 354]
A[2:4]
[3, 100]
A[1:5:2]
[2, 100]
A[-1]
354
A[:-2]
[1, 2, 3, 100, 11]
La méthode spéciale __init__
est le constructeur de la classe
class Point():
def __init__(self, x, y):
self.x = x
self.y = y
def montrer(self):
print "(" + str(self.x) + "," + str(self.y) + ")"
Le constructeur est appelé implicitement à la création d'un objet
p = Point(10, 15)
p.x
10
p.y
15
p.montrer()
(10,15)
Les champs des classes sont dynamiques: on peut en ajouter à souhait
p.c = 56
p.c
56
p.montrer()
(10,15)
p
<__main__.Point instance at 0x7f2cab07f5a8>
On peut ajouter aussi des méthodes à une classe déjà définie
def affichage(self):
print "Dans __repr__"
# L'opérateur % sur les chaines de caractères est simlaire au printf en C
return "(%d, %d)" % (self.x, self.y)
Point.__repr__ = affichage
p = Point(10, 15)
La méthode spéciale __repr__
modifie la façon dont les objets s'affichent
p
Dans __repr__
(10, 15)
def euclidepol (A,B):
A0 = A; A1 = B
S0 = 1; S1 = 0
T0 = 0; T1 = 1
while A1 != 0:
Q = A0//A1
U = A1; A1 = A0 - Q*A1; A0 = U
U = S1; S1 = S0 - Q*S1; S0 = U
U = T1; T1 = T0 - Q*T1; T0 = U
return (A0,S0,T0)
A.<X> = QQ[]
a, b = X^2-1, (X-1)^2
g, u, v = euclidepol(a, b)
g
2*X - 2
u, v
(1, -1)
u*a + v*b == g
True
def irreducible(k, n):
A.<x> = k[]
p = x^n
while not p.is_irreducible():
p = A.random_element(n)
return p.monic()
irreducible(QQ, 3)
x^3 - 3/2*x^2 - 45/2*x + 3/4
irreducible(GF(7), 100)
x^100 + 3*x^99 + 6*x^98 + 4*x^97 + 5*x^96 + 2*x^95 + x^94 + 6*x^93 + 2*x^92 + 2*x^91 + 2*x^90 + 2*x^89 + x^88 + 2*x^87 + x^86 + x^85 + 4*x^84 + x^83 + 3*x^82 + 6*x^81 + 3*x^80 + 2*x^79 + 4*x^78 + 5*x^77 + x^76 + 6*x^75 + 5*x^74 + 5*x^73 + x^72 + 2*x^71 + 6*x^70 + 3*x^69 + 4*x^68 + 3*x^67 + 3*x^66 + 5*x^64 + 4*x^62 + 4*x^61 + 2*x^60 + 4*x^59 + 5*x^57 + 5*x^56 + 2*x^55 + 4*x^54 + 2*x^53 + 2*x^52 + 2*x^51 + 2*x^50 + 6*x^49 + 5*x^48 + x^47 + 5*x^46 + 5*x^44 + 3*x^43 + 3*x^42 + 3*x^41 + 4*x^39 + 2*x^38 + 3*x^36 + 6*x^35 + 3*x^34 + 6*x^33 + 4*x^32 + 5*x^31 + x^30 + 2*x^29 + 4*x^28 + 5*x^27 + 2*x^26 + 2*x^25 + 3*x^24 + 3*x^23 + 2*x^22 + 3*x^21 + 4*x^20 + 2*x^19 + 2*x^18 + 5*x^16 + 5*x^15 + 2*x^14 + 3*x^13 + 5*x^12 + 4*x^11 + 2*x^9 + 4*x^8 + 6*x^7 + 2*x^6 + 6*x^4 + 5*x^3 + 2*x^2 + 6*x + 6
def lexico_irred(p, n):
A.<x> = GF(p)[]
P = x^n
while not P.is_irreducible():
# print P
for i in range(n):
if P[i] != p-1:
P += x^i
break
for j in range(i):
P -= P[j] * x^j
return P
lexico_irred(3, 10)
x^10 + 2*x^2 + 1
lexico_irred(101, 21)
x^21 + 2*x + 1