Leçons de niveau 13

Informatique et sciences du numérique/Le langage Python

Une page de Wikiversité.
Sauter à la navigation Sauter à la recherche
Début de la boite de navigation du chapitre
Le langage Python
Icône de la faculté
Chapitre no 9
Leçon : Informatique et sciences du numérique
Chap. préc. :Le projet
Chap. suiv. :Le langage Java
fin de la boite de navigation du chapitre
Icon falscher Titel.svg
En raison de limitations techniques, la typographie souhaitable du titre, « Informatique et sciences du numérique : Le langage Python
Informatique et sciences du numérique/Le langage Python
 », n'a pu être restituée correctement ci-dessus.

Présentation[modifier | modifier le wikicode]

Le langage Python[1] est un langage développé depuis 1990 par Guido van Rossum, aidé de nombreux contributeurs[2]. Ce langage est disponible gratuitement, et est fourni avec de nombreuses extensions très utiles :

  • la bibliothèque graphique Tkinter[3]
  • l'environnement de développement IDLE[4] simple et efficace pour des projets pas trop ambitieux
  • des bibliothèques de fonctions comme math, random, time, turtle, matplotlib...
  • enfin la documentation de Python est très complète, et il existe de nombreux tutoriaux disponibles gratuitement

Contrairement à de nombreux langages comme le C, le C++ ou Java, le langage Python n'utilise pas d'accolades pour délimiter la structure du code. À la place, Python utilise l'indentation, c'est-à-dire le décalage du début d'une ligne par rapport au début de la ligne précédente. Il faut être attentif à la signification de ce décalage.

Le but de cette page est de proposer une approche très rapide de Python, et de proposer quelques ressources.

Pour installer Python et IDLE[5] (il s'agit de la version 3.2.3).

Premiers pas[modifier | modifier le wikicode]

Python comme calculatrice : entiers, réels[modifier | modifier le wikicode]

235*12
235**12
12**235
235/12
235//12
235%12
235**12%12
235**(12%12)
a=235*12+3
b=a%12
print a,b

from math import * 	#on importe les fonctions du module math

atan(1) #degrés ou radians ?
sqrt(2)
help('math') #une fonction utile !

À retenir

  • Python peut calculer sur des nombres entiers (de taille quelconque) ou bien sur des valeurs approchées de nombres réels.
  • Les parenthèses jouent le même rôle qu'en mathématiques : donner l’ordre dans lequel on doit faire les opérations, ou bien donner l'argument d'une fonction.
  • Avec le mot clé import on peut utiliser des fonctions déjà construites ; par exemple ici on dit qu'on a importé le module math.
  • La fonction help permet d'obtenir de l'aide sur un module, elle prend en argument une chaîne de caractères ; Python est capable de travailler avec d'autres types d'objets que les nombres.

Types de données : listes et chaînes[modifier | modifier le wikicode]

liste=range(10)
liste2=range(3,25,5)
liste3=range(100,0,-7)
print liste,liste2,liste3
len(liste), len(liste2),len(liste3)
liste3
liste3.sort() #la fonction sort() est une méthode de la classe list
liste3
liste2
liste2[2:4]
len(liste2[2:4])

liste=range(10,40,3)
liste
liste[0] #le premier élément de la liste est l'élément de rang 0
liste[4]
liste[4]=12
liste
liste[6:] #de l'élément numéro 6 (inclus) jusqu'à la fin de la liste
liste[:4] #du début de la liste jusqu'à l'élément de rang 3 (le quatrième élément, donc)
liste.append(25)
liste
liste.append(72)
72 in liste 
43 in liste 
#attention à ce qui suit !!!
autreliste=liste
autreliste[4]=156
autreliste
liste
autreliste=liste[:]
autreliste[4]='chabada' #les éléments d'une liste ne sont pas forcément des nombres
autreliste
liste
 

alphabet='abcdefghijklmnopqrstuvwxyz'
alphabet[8:25:3]	#un cousin d'Astérix
'a' in alphabet,'A' in alphabet
name='Cucaracha'
salut='Bonjour mon petit'
ch=salut+name #le signe + signifie qu'on concatène les deux chaînes (on les écrit à la suite) 
ch
ch=salut+' '+name
ch
ch.upper()
len(ch)
'ba:na:na'.split(':') #découpe une chaîne
'ba:na:na'.split('a') 
ch[3] #un caractère unique (une chaîne de longueur 1)
ch[3]='z'
chbis=ch[:3]+'z'+ch[4:]


À retenir

  • Une liste est un ensemble ordonné d'éléments, séparés par des virgules, et placés entre crochets.
  • Chaque élément de la liste peut être un nombre, une chaîne, ou même une liste (qui elle-même peut contenir des éléments qui sont des listes...)
  • Le mot range permet de construire des listes de nombres (en progression arithmétique).
  • Les crochets permettent de découper une partie liste ou d'une chaîne
  • Le mot len permet d'obtenir la longueur d'une liste ou d'une chaîne.
  • À chaque classe d'objet sont associées des méthodes, ce sont des fonctions qui sont appelées en utilisant notation .méthode() comme par exemple sort() pour trier une liste.
  • Une méthode peut avoir des arguments, en plus de l’objet auquel elle s'applique.
  • Le mot in permet de tester l'appartenance d'un objet à une liste.
  • Des valeurs séparées par des virgules forment un tuple, qui est affiché entouré de parenthèses. Ce n’est pas le même type d'objet qu'une liste.
  • On ne peut pas modifier individuellement les caractères d'une chaîne (on dit qu'une chaîne n’est pas mutable)

Boucle for[modifier | modifier le wikicode]

for i in range(20):
	print 'le carré de '+str(i)+' est '+str(i**2)

for i in alphabet:	#i est un caractère
	print 'le code ASCII de '+i+' est '+str(ord(i))
	j=ord(i)-32 #j est un entier
	print str(j)+' code la lettre '+chr(j)

#l'indentation est indispensable pour préciser la ou #les instruction(s) qui doivent être répétée(s)

[i**2 for i in range(20)]
[[i,i**2] for i in range(20)]
[i ** 2 for i in range(20) if i%2==0]

À retenir

  • La boucle for est une construction fondamentale, car elle permet de répéter des instructions plusieurs fois.
  • Le : annonce une indentation ; toutes les lignes qui ont cette même indentation seront répétées.
  • La fonction str transforme n’importe quel type d'objet en chaîne de caractères, ord renvoie le code numérique d'un caractère, chr transforme un nombre en caractère de façon réciproque.
  • Quelques façons amusantes de définir une liste, penser à noter dans le grimoire ces puissantes invocations.

Définir une nouvelle fonction[modifier | modifier le wikicode]

#une fonction qui renvoie le cube de son argument
def cube(n):
	return n*n*n

cube(235)
cube(23.5)	#le typage est dynamique !

#La suite de Fibonacci 1,1,2,3,5,8....
#chaque terme est la somme des deux termes précédents 
def fibo(n):
	a,b=1,1
	for i in range(2,n+1):
		a,b=b,a+b
		print 'u('+str(i)+')= '+str(b)#débogage
	return b

fibo(5)
fibo(500)

#une définition possible de la factorielle 
def facto(n):
	t=1
	for i in range(1,n+1):
		t=t*i
	return t

facto(5)
facto(10)
facto(100)



Les structures if elif else et while[modifier | modifier le wikicode]

#les suites de Syracuse
def syracuse(n):
	while n>1:
		if n%2==0:
			n=n//2
		else:
			n=n*3+1
		print n,	 #la virgule évite le passage à la ligne

syracuse(25)
syracuse(250)
syracuse(2**16)
syracuse(2**16-1)

#un problème fondamental, le pb de l'arrêt : est-on certain que l'algorithme va s'arrêter ?

#modifier la fonction syracuse pour qu'elle renvoie le nombre d'étapes, le maximum atteint

def decomp(n):	#renvoie les facteurs premiers d'un entier
	i=2
	diviseurs=[]
	while n>1:
		while n%i==0:
			n=n//i
			diviseurs.append(i)
		i=i+1

decomp(350)
decomp(1024)
decomp(3500000234)

#Quelle est la plus petite puissance de 2 supérieure à un nombre donné ? 

def lg(n):
	i=0
	k=1
	while k<n:
		i=i+1
		k=k*2
	return i 	#on renvoie l'exposant ;
		#on aurait pu renvoyer la puissance

lg(1000)
lg(10**9)
lg(10**90)
10**90
2**299


La méthode d'Euler version graphique[modifier | modifier le wikicode]

#!/usr/bin/python
# -*- coding: utf-8 -*-

from Tkinter import *
from math import *
from time import sleep

#des méthodes d'intégration numérique

def euler1(f,x0,y0,h,n):
    l=[]
    x=x0
    y=y0
    pente=eval(f)
    l.append([x,y,pente])
    for i in range(n):
        x=x+h
        y=y+pente*h
        pente=eval(f)
        l.append([x,y,pente])
    return(l)

def rk4ode1(f,x0,y0,h,n):
    l=[]
    x=x0
    y=y0
    l.append([x,y,eval(f)])
    for i in range(n):
        xx=x
        yy=y
        k1=eval(f)
        x=x+h/2.0
        y=y+k1*h/2.0
        k2=eval(f)
        y=yy+k2*h/2
        k3=eval(f)
        x=xx+h
        y=yy+h*k3
        k4=eval(f)
        pente=(k1+2*k2+2*k3+k4)/6
        y=yy+pente*h
        l.append([x,y,pente])
    return(l)


#la grosse fonction, appelée par le bouton du même nom

def traite(meth=1):
    #récupérer les paramètres
    f=ent1.get()
    x0=eval(ent2.get())
    y0=eval(ent3.get())
    xmax=eval(ent4.get())
    h=eval(ent5.get())
    n=int((xmax-x0)*1.0/h)
    #print f,x0,y0,h,n
    #calculer les points
    if meth==1:
        l=euler1(f,x0,y0,h,n)
    else:
        l=rk4ode1(f,x0,y0,h,n)
        
    #trouver mins et maxs et les afficher
    lab1.configure(text='xmin= '+str(x0))
    lab2.configure(text='xmax= '+str(xmax))
    u=y0
    v=y0
    for i in range(n+1):
        t=l[i][1]
        if t<u:
            u=t
        if t>v:
            v=t
    ymin=u
    ymax=v
    if ymin>0:
        ymin=0
    if ymax<0:
        ymax=0
    lab3.configure(text='ymin= '+str(ymin))
    lab4.configure(text='ymax= '+str(ymax))
    #tracer les axes, avec les petites flèches qui vont bien
    can.delete(ALL)
    xmin=x0-2*h
    if xmin*(xmax+2*h)<=0:
        axey=int(500*(-xmin)/(2*h+xmax-xmin))
        can.create_line(axey,0,axey,299,fill='black')
        can.create_line(axey,0,axey-5,5)
        can.create_line(axey,0,axey+5,5)
    axex=290-int(280*(-ymin)/(ymax-ymin))
    can.create_line(0,axex,499,axex,fill='black')
    can.create_line(494,axex-5,499,axex,fill='black')
    can.create_line(494,axex+5,499,axex,fill='black')
    fen.update_idletasks()
    
    #tracer point par point en affichant les valeurs successives de x, y et y'
    #print l
    lab7.configure(text='x=')
    lab8.configure(text='y=')
    ent1.delete(0,END)
    ent1.insert(0,str(l[0][2]))
    ent1.update()
    ent2.delete(0,END)
    ent2.insert(0,str(l[0][0]))
    ent2.update()
    ent3.delete(0,END)
    ent3.insert(0,str(l[0][1]))
    ent3.update()
    fen.update_idletasks()
    for i in range(n):
        if i<6:
            sleep(1.5)
        else:
            sleep(0.5)
        x1=int((l[i][0]-xmin)/(xmax+2*h-xmin)*500)
        y1=290-int((l[i][1]-ymin)/(ymax-ymin)*280)
        x2=int((l[i+1][0]-xmin)/(xmax+2*h-xmin)*500)
        y2=290-int((l[i+1][1]-ymin)/(ymax-ymin)*280)
        can.create_line(x1,y1,x2,y2,fill='red')
        ent1.delete(0,END)
        ent1.insert(0,str(l[i+1][2]))
        ent1.update()
        ent2.delete(0,END)
        ent2.insert(0,str(l[i+1][0]))
        ent2.update()
        ent3.delete(0,END)
        ent3.insert(0,str(l[i+1][1]))
        ent3.update()
        fen.update_idletasks()
        #print [x1,y1,x2,y2],
        
    #on remet les champs utilisateur dans l'état initial
    lab7.configure(text='x0=')
    lab8.configure(text='y0=')
    ent1.delete(0,END)
    ent1.insert(0,f)
    ent2.delete(0,END)
    ent2.insert(0,str(x0))
    ent3.delete(0,END)
    ent3.insert(0,str(y0))
    fen.update_idletasks()

def rk4():
    traite(2)

#l'interface graphique

fen=Tk()
fen.title("Euler d'ordre 1 ISN Curie")

cad1=Frame(fen)
cad1.grid(row=0)
can=Canvas(cad1,width=500,height=300,bg='ivory')
can.grid(row=0,column=0,rowspan=4,columnspan=6,padx=5,pady=5)
lab1=Label(cad1,text='xmin= ')
lab1.grid(row=0,column=6,sticky=W) #xmin
lab2=Label(cad1,text='xmax= ')
lab2.grid(row=1,column=6,sticky=W) #xmax
lab3=Label(cad1,text='ymin= ')
lab3.grid(row=2,column=6,sticky=W) #ymin
lab4=Label(cad1,text='ymax= ')
lab4.grid(row=3,column=6,sticky=W) #ymax

cad2=Frame(fen)
cad2.grid(row=1)
lab5=Label(cad2,text="y'=")
lab5.grid(row=4,column=0) # "y'="
ent1=Entry(cad2)
ent1.grid(row=4,column=1,columnspan=3,sticky=W) # y' en fn de x et y
lab6=Label(cad2,text='xmax=')
lab6.grid(row=4,column=4) #xmax entrée utilisateur
ent4=Entry(cad2)
ent4.grid(row=4,column=5,sticky=W)
lab7=Label(cad2,text='x0=')
lab7.grid(row=5,column=0) #x0 entrée utilisateur
ent2=Entry(cad2)
ent2.grid(row=5,column=1,sticky=W)
lab8=Label(cad2,text='y0=') 
lab8.grid(row=5,column=2) #y0 entrée utilisateur
ent3=Entry(cad2)
ent3.grid(row=5,column=3,sticky=W)
lab9=Label(cad2,text='h=')
lab9.grid(row=5,column=4) # h entrée utilisateur
ent5=Entry(cad2)
ent5.grid(row=5,column=5,sticky=W)
but1=Button(cad2,command=traite,text='Euler')
but1.grid(row=5,column=6)
but1=Button(cad2,command=rk4,text='RK4')
but1.grid(row=5,column=7)

#des valeurs par défaut pour tester le programme
ent1.insert(0,'x')
ent2.insert(0,'0')
ent3.insert(0,'-2')
ent4.insert(0,'5')
ent5.insert(0,'0.5')

fen.mainloop()


Le Grimoire[modifier | modifier le wikicode]

Il est conseillé à toute personne se lançant dans la programmation de noter des fragments de code "qui marchent" sur un cahier spécial : Le Grimoire. Il est difficile de se rappeler de toutes les fonctions, méthodes et autres constructions dont on peut avoir besoin pour écrire un programme, sauf si on programme tous les jours. Noter sur ce Grimoire les fragments de code dont on a déjà eu besoin est une façon efficace pour progresser en programmation sans avoir besoin de se poser encore et encore les mêmes questions techniques.

Des livres et des tutoriaux[modifier | modifier le wikicode]

Des fiches d'exercice[modifier | modifier le wikicode]

Ces exercices permettent d'approfondir certains aspects du langage Python ou de certaines de ses bibliothèques. Ils sont construits sur le principe suivant :

  • on tape le code
  • on observe le résultat
  • on modifie un peu le code
  • on prend des notes dans son grimoire !

Manipulations de listes[modifier | modifier le wikicode]

Manipulation de chaînes : un peu de cryptographie[modifier | modifier le wikicode]

Fichiers et encodage utf-8[modifier | modifier le wikicode]

Construction d'une interface graphique avec Tkinter[modifier | modifier le wikicode]

Threads et sockets[modifier | modifier le wikicode]

  1. http://fr.wikipedia.org/wiki/Python_(langage)
  2. http://fr.wikipedia.org/wiki/Python_(langage)
  3. http://fr.wikibooks.org/wiki/Programmation_Python/Tkinter
  4. http://fr.wikipedia.org/wiki/IDLE_(Python)
  5. python.org/ftp/python/3.2.3/python-3.2.3.msi