Éléments de syntaxe Python

Les variables ne sont pas typées

In [1]:
x = 13
In [2]:
x = "toto"
In [3]:
x = 10

Le bloc 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.

In [4]:
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

In [5]:
if x is not None and 5 < x < 100 and (True or False):
    print "Oui"
Oui

Boucle while

In [6]:
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

In [9]:
x
Out[9]:
100

Listes et boucle for

In [7]:
L = [1, 2, 10, 15]
for x in L:
    print x + 10
11
12
20
25
In [8]:
for x in L:
    if x > 10:
        print x - 10
    else:
        print x
1
2
10
5

Fonctions

In [9]:
def tot(a, b):
    c = a + b
    return c
In [10]:
x = tot(14, 5)
In [11]:
x
Out[11]:
19

Les variables d'une fonction sont (généralement) locales à la fonction

In [12]:
c
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-12-2cd6ee2c70b0> in <module>()
----> 1 c

NameError: name 'c' is not defined
In [13]:
tot("Hello ", 'world')
Out[13]:
'Hello world'
In [14]:
tot("Hello", 13)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-37d325c0ab11> in <module>()
----> 1 tot("Hello", Integer(13))

<ipython-input-9-957743e6310d> in tot(a, b)
      1 def tot(a, b):
----> 2     c = a + b
      3     return c

/local/SageMath-6.10/src/sage/structure/element.pyx in sage.structure.element.RingElement.__add__ (/local/SageMath-6.10/src/build/cythonized/sage/structure/element.c:15852)()
   1649         elif PyInt_CheckExact(left):
   1650             return (<RingElement>right)._add_long(PyInt_AS_LONG(left))
-> 1651         return coercion_model.bin_op(left, right, add)
   1652 
   1653     cdef RingElement _add_long(self, long n):

/local/SageMath-6.10/src/sage/structure/coerce.pyx in sage.structure.coerce.CoercionModel_cache_maps.bin_op (/local/SageMath-6.10/src/build/cythonized/sage/structure/coerce.c:9736)()
   1067         # We should really include the underlying error.
   1068         # This causes so much headache.
-> 1069         raise TypeError(arith_error_message(x,y,op))
   1070 
   1071     cpdef canonical_coercion(self, x, y):

TypeError: unsupported operand parent(s) for '+': '<type 'str'>' and 'Integer Ring'
In [15]:
tot("Hello", str(13))
Out[15]:
'Hello13'
In [16]:
tot("Hello", '13')
Out[16]:
'Hello13'
In [17]:
tot(5, '13')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-73dbb636c993> in <module>()
----> 1 tot(Integer(5), '13')

<ipython-input-9-957743e6310d> in tot(a, b)
      1 def tot(a, b):
----> 2     c = a + b
      3     return c

/local/SageMath-6.10/src/sage/structure/element.pyx in sage.structure.element.RingElement.__add__ (/local/SageMath-6.10/src/build/cythonized/sage/structure/element.c:15852)()
   1649         elif PyInt_CheckExact(left):
   1650             return (<RingElement>right)._add_long(PyInt_AS_LONG(left))
-> 1651         return coercion_model.bin_op(left, right, add)
   1652 
   1653     cdef RingElement _add_long(self, long n):

/local/SageMath-6.10/src/sage/structure/coerce.pyx in sage.structure.coerce.CoercionModel_cache_maps.bin_op (/local/SageMath-6.10/src/build/cythonized/sage/structure/coerce.c:9736)()
   1067         # We should really include the underlying error.
   1068         # This causes so much headache.
-> 1069         raise TypeError(arith_error_message(x,y,op))
   1070 
   1071     cpdef canonical_coercion(self, x, y):

TypeError: unsupported operand parent(s) for '+': 'Integer Ring' and '<type 'str'>'
In [18]:
tot('5', '13')
Out[18]:
'513'

Plus sur les listes

In [19]:
A = [1, 2, 3] + [100, 11, 5]
In [20]:
A
Out[20]:
[1, 2, 3, 100, 11, 5]
In [21]:
A.index(100)
Out[21]:
3
In [22]:
A[3]
Out[22]:
100
In [23]:
A.append(354)
In [24]:
A
Out[24]:
[1, 2, 3, 100, 11, 5, 354]

Classes

La méthode spéciale __init__ est le constructeur de la classe

In [25]:
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

In [26]:
p = Point(10, 15)
In [27]:
p.x
Out[27]:
10
In [28]:
p.y
Out[28]:
15
In [29]:
p.montrer()
(10,15)

Les champs des classes sont dynamiques: on peut en ajouter à souhait

In [30]:
p.c = 56
In [31]:
p.c
Out[31]:
56
In [32]:
p.montrer()
(10,15)
In [33]:
p
Out[33]:
<__main__.Point instance at 0x7f4fac30d998>

On peut ajouter aussi des méthodes à une classe déjà définie

In [35]:
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
In [36]:
p = Point(10, 15)

La méthode spéciale __repr__ modifie la façon dont les objets s'affichent

In [37]:
p
Dans __repr__
Dans __repr__
Out[37]:
(10, 15)

Mettre plusieurs instructions sur la même ligne

In [38]:
x = 10; y = 15
In [39]:
x, y
Out[39]:
(10, 15)

C'est différent de l'assignement multiple

In [40]:
x, y = 10, 15
In [41]:
x, y
Out[41]:
(10, 15)
In [42]:
x, y = y, x
In [43]:
x, y
Out[43]:
(15, 10)
In [44]:
x = y; y = x
In [45]:
x, y
Out[45]:
(10, 10)

Exercice 6.1

In [46]:
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)
In [47]:
A.<X> = QQ[]
In [48]:
a, b = X^2-1, (X-1)^2
g, u, v = euclidepol(a, b)
In [49]:
g
Out[49]:
2*X - 2
In [50]:
u, v
Out[50]:
(1, -1)
In [51]:
u*a + v*b == g
Out[51]:
True

listes et tuples

In [52]:
x = [1, 2, 3]
In [53]:
x
Out[53]:
[1, 2, 3]
In [54]:
type(x)
Out[54]:
<type 'list'>
In [55]:
y = (1, 2, 3)
In [56]:
y
Out[56]:
(1, 2, 3)
In [57]:
type(y)
Out[57]:
<type 'tuple'>
In [58]:
x[0]
Out[58]:
1
In [59]:
y[0]
Out[59]:
1

La différence principale entre listes et tuples est que les listes sont modifiables, alors que les tuples ne le sont pas.

In [60]:
x[0] = 15
In [61]:
x
Out[61]:
[15, 2, 3]
In [62]:
y[0] = 15
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-62-723d94629f47> in <module>()
----> 1 y[Integer(0)] = Integer(15)

TypeError: 'tuple' object does not support item assignment
In [63]:
L = [(1,2), (5,6), (7,8)]
for x,y in L:
    print x+y
3
11
15

Exercice 6.2

In [64]:
def irreducible(k, n):
    A.<x> = k[]
    p = x^n
    while not p.is_irreducible():
        p = A.random_element(n)
    return p.monic()
In [65]:
irreducible(QQ, 3)
Out[65]:
x^3 + 20*x^2 - 4/3*x - 4
In [66]:
irreducible(GF(7), 100)
Out[66]:
x^100 + 2*x^99 + 4*x^98 + 6*x^97 + 3*x^96 + x^95 + 4*x^94 + 5*x^93 + x^92 + 4*x^90 + 2*x^89 + 6*x^88 + x^86 + 6*x^85 + x^84 + 5*x^83 + 6*x^80 + 5*x^79 + 2*x^77 + 2*x^76 + 5*x^75 + 5*x^74 + 6*x^73 + 6*x^72 + 2*x^71 + 5*x^70 + 4*x^68 + 3*x^67 + 2*x^66 + x^65 + 2*x^64 + 2*x^63 + 3*x^62 + 3*x^60 + 6*x^59 + 2*x^58 + 6*x^57 + 3*x^56 + 6*x^55 + 3*x^54 + 2*x^53 + 3*x^52 + 5*x^51 + 4*x^50 + 5*x^49 + 3*x^47 + 5*x^46 + 6*x^45 + 6*x^44 + 2*x^43 + 2*x^42 + 4*x^41 + x^40 + 6*x^38 + 3*x^37 + 2*x^35 + x^33 + 5*x^32 + 6*x^31 + 6*x^29 + 5*x^28 + 6*x^25 + 5*x^23 + 6*x^22 + 2*x^21 + 4*x^20 + 5*x^19 + 4*x^18 + 2*x^17 + 2*x^16 + 2*x^15 + 5*x^13 + 3*x^12 + 5*x^10 + 5*x^9 + x^7 + 6*x^6 + 3*x^5 + 6*x^4 + x^2 + 4*x + 3

Exercice 6.3

In [67]:
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
In [68]:
lexico_irred(3, 10)
Out[68]:
x^10 + 2*x^2 + 1
In [69]:
lexico_irred(101, 21)
Out[69]:
x^21 + 2*x + 1
In [ ]: