Olivier Guibé - LMRS, fortement inspiré d'un document de Pierre Navaro (IRMAR).

Programmation de base

En Python, pas de {/} de begin/end, de ; en fin de ligne. Toute la structure des boucles, tests, définition des routines se fait par indentation (puisqu'il est indispensable de le faire, autant que cela serve de structure).

In [1]:
def f(x):
    return x**2
print(f(4))
16

Le while ou tant que

  • Le ':' après la condition du while
  • Le corps du while indenté
In [2]:
# et un PGCD
a, b = 123456789, 532341
while a%b!=0: ## !a%b==0 
     a, b = b, a%b
print(b)
9

Le si alors sinon ou if

Les tests sont

True, False, and, or, not, ==, is, !=, is not, >, >=, <, <=
In [16]:
x = 42
if x < 0:
    x = 0
    print('négative met zéro')
elif x == 0:
    print('Zéro')
elif x == 1:
    print('c\'est un')
else:
    print('c\'est plus que un')
c'est plus que un

Pas de case of (ou switch) en Python. On peut faire du elif ou utiliser un dictionnaire.

La boucle

La boucle se fait sur un itérateur. Sur une chaîne de caractère : les caractères, sur une liste : les éléments de la liste

In [19]:
s=0
for i in range(0,11):
    s+=i
print(s==55) # car je connais la formule 10*11/2 !
True

Pour une boucle décroissante, deux solutions, range avec pas négatif ou reversed(range) avec pas positif. Par exemple pour calculer une approximation de $e$ avec la méthode de Horner, $$ e=\sum_{n=0}^{\infty} \frac{1}{n!} $$ En s'arrêtant bien avant l'infini

In [3]:
s=1
for i in range(100,0,-1):
    s=1+ 1/i*s
print(s)
2.718281828459045
In [4]:
N=1000; s=1
for i in reversed(range(1,N+1)):
    s/=i
    s+=1
print(s)
2.718281828459045

break ou comment tuer une boucle

In [5]:
for n in range(2, 10):  # n = 2,3,4,5,6,7,8,9
   for x in range(2, n): # x = 2, ..., n-1
      if n % x == 0:     # reste de la division euclidienne
         print (n, " = ", x, "*", n//x)
         break  # stop la boucle sur x
      else:
         print(" %d est un nombre premier" % n)
 3 est un nombre premier
4  =  2 * 2
 5 est un nombre premier
 5 est un nombre premier
 5 est un nombre premier
6  =  2 * 3
 7 est un nombre premier
 7 est un nombre premier
 7 est un nombre premier
 7 est un nombre premier
 7 est un nombre premier
8  =  2 * 4
 9 est un nombre premier
9  =  3 * 3

enumerate ou la correspondance position/élément

In [31]:
primes =  [1,2,3,5,7,11,13]
for idx, ele in enumerate (primes):
    print(idx, " --- ", ele) 
print(list(enumerate(primes)))
0  ---  1
1  ---  2
2  ---  3
3  ---  5
4  ---  7
5  ---  11
6  ---  13
[(0, 1), (1, 2), (2, 3), (3, 5), (4, 7), (5, 11), (6, 13)]

Définition d'une fonction: def

In [1]:
def is_palindrome( s ):
    "renvoie True si s est un palindrome"
    return s == s[::-1]

is_palindrome("kayak")
Out[1]:
True
  • Attention à l'indentation

Variables globales/locales

Sauf instruction spécifique, une variable définie dans une fonction n'altère pas la variable de même nom définie en dehors de cette fonction.

  • toutes les variables définies dans une fonction sont supposées locales
  • l'ajout de global permet de modifier globalement la variable
In [9]:
pi = 1.
def deg2rad(theta):
    pi = 3.14
    return theta * pi / 180.

print(deg2rad(45))
print(pi)
0.785
1.0
In [11]:
def rad2deg(theta):
    return theta*180./pi

print(rad2deg(0.785))
pi = 3.14
print(rad2deg(0.785))
from math import pi
print(pi)
45.0
45.0
3.141592653589793
In [12]:
def deg2rad(theta):
    global pi
    pi = 3.14
    return theta * pi / 180

pi = 1
print(deg2rad(45))
0.785
In [13]:
print(pi)
3.14

Définition de listes

Python permet de construire une liste d'une façon particulière, nommée la "compréhension de liste".

In [14]:
li = [1, 9, 8, 4]
[elem**2 for elem in li]
Out[14]:
[1, 81, 64, 16]
In [2]:
[n*n for n in range(1,10)]
Out[2]:
[1, 4, 9, 16, 25, 36, 49, 64, 81]
In [4]:
[n*n for n in range(1,10) if n%2==0]
Out[4]:
[4, 16, 36, 64]
In [5]:
[n+1 if n&1 else n//2 for n in range(1,10) ]
Out[5]:
[2, 1, 4, 2, 6, 3, 8, 4, 10]

map ou appliquer une fonction à une séquence

In [15]:
from math import sin, pi; res = map(sin,[i*pi/6 for i in range(0,12)])
print(res)
<map object at 0x7f85c84a94a8>

Depuis Python 3.x, map appliquée à une liste, un itérateur (type range) retourne un objet de type map et pas une liste. Cela est plus rapide et économise la mémoire. Pour afficher le résultat list ou * sont là.

In [16]:
print(*res)
0.0 0.49999999999999994 0.8660254037844386 1.0 0.8660254037844387 0.49999999999999994 1.2246467991473532e-16 -0.4999999999999997 -0.8660254037844384 -1.0 -0.8660254037844386 -0.5000000000000004

map avec sa fonction

In [17]:
def add(x,y):
    return x+y

L1 = [1, 2, 3]
L2 = [4, 5, 6]
print(*(map(add,L1,L2)))
5 7 9

Fonction récursive

Python permet évidemment des définitions récursives ! Et comme une fonction permet de définir une fonction, voici un exemple de définition récursive de l'escalier de Cantor (ne pas aller trop loin) et du tracé de la courbe représentative.

In [18]:
# un oral de Centrale, avec illustration Python
import numpy as np  #la vectorisation
import matplotlib.pyplot as plt # tracé de fonctions
def T(f,x):
    # le découpage façon Cantor
    s=f(3*x)/2*((0<=x)&(x<1/3)) + .5*((x>=1/3)*(x<=2/3))+(f(3*x-2)+1)/2*((x>2/3)&(x<=1))
    return s
def I(x):
    # l'identité
    return x

def TR(f,n):
    if n==1:
        def rT(x):
            return T(f,x)
        return rT
    if (n>1):
        return TR(TR(f,1),n-1)
In [19]:
print(TR(I,3)(.4))
plt.plot(np.linspace(0,1,100),TR(I,9)(np.linspace(0,1,100)))
plt.show()
0.5