Introduction à Python

Transcription

Introduction à Python
Introduction à Python
Nicolas Dumoulin [email protected]
16 Mai 2013
Préambule
Ce document est librement réutilisable selon les termes de la licence GNU FDL version 1.2 et
supérieures.
Vous pouvez charger ce document interactif en version notebook (extension .ipynb), en démarrant ipython notebook depuis le répertoire contenant ce document, ou bien en faisant glisser le
document sur la page web du notebook après l'avoir démarré. Voir aussi la documentation de
notebook.
Qu'est­ce que Python ?
Un langage
Une suite d'outils sous licence libre
Une bibliothèque en standard bien fournie
Une plate­forme pour faire :
Des applications sur poste client (Qt)
Des applications pour le web (Django)
Des surcouches à des codes de calculs (C, C++, Fortran, …)
Du bidouillage interactif
Ressources en lignes :
Documentation officielle : http://docs.python.org/ (Notament le Tutorial et la Library
reference)
Dive into Python : http://www.diveintopython.net/
IPython mini­book : http://ipython.rossant.net/
SciPy Cookbook : http://www.scipy.org/Cookbook
Deux modes d'utilisation :
Mode interactif (console)
Exécution de script
Premier contact, démarrer la console interactive : python3 ou python (version 2.x selon les
systèmes) Pour quitter la console : [Ctrl] + [D]
In [26]: 3*2
Out[26]: 6
In [27]: 2 + 5 / 2
Out[27]: 4
On peut taper une opération arithmétique et on obtient le résultat.
Variables et types de données
Le typage d'une variable est dynamique, le type est inféré lors de l'affectation.
In [28]: i = 1
d = 0.5
s = "bonjour"
In [29]: nb = 3 + 2j
type(nb)
Out[29]: complex
In [30]: type(i)
. . .
In [31]: type(d)
. . .
In [32]: type(s)
. . .
La variable spéciale _ contient la dernière valeur affichée
In [33]: 3*2
Out[33]: 6
In [34]: _+2
Out[34]: 8
Chaînes de caractère
In [35]: s1 = "N'importe quoi" # avec des guillemets double, cela permet d'u
In [35]: s1 = "N'importe quoi" # avec des guillemets double, cela permet d'u
s2 = 'N\'importe quoi' # avec des guillemets simple, l'apostrophe d
s3 = 'Je disais "N\'importe quoi"' # avec des guillemets simple, ce
s4 = """Je disais "N'importe quoi" """ # avec trois guillemets doub
s5 = """Les triples guillemets permettent d'écrire
plusieurs lignes"""
print(s5)
Les triples guillemets permettent d'écrire
plusieurs lignes
In [36]: i + d
Out[36]: 1.5
Problème avec des types non compatibles
i+s
On doit alors transtyper (caster) les variables
In [37]: "Votre valeur est : "+str(d)
Out[37]: 'Votre valeur est : 0.5'
In [38]: str(i) + s
Out[38]: '1bonjour'
Variables booléenes
In [39]: true = True
vrai = true
faux = False
del vrai # supprime la variable
Opérateurs et fonctions de base
On les trouve sous le nom de builtin functions dans la documentation anglophone.
La fonction print() permet d'afficher le contenu d'une variable, et plus généralement une chaîne
de caractère.
In [40]: print(s1)
print("Ceci est un entier : "+str(i))
N'importe quoi
Ceci est un entier : 1
La fonction help() permet d'obtenir la documentation d'une fonction (python 3).
La fonction len permet de connaître la taille d'un tableau
In [41]: len("Bonjour")
Out[41]: 7
Opérateurs et fonctions arithmétiques
Documentation : http://docs.python.org/2/library/stdtypes.html#numeric­types­int­float­long­complex
In [42]: 5/2 # division entière en python 2.x mais division flottante à part
Out[42]: 2
In [43]: 5.0/2
Out[43]: 2.5
In [44]: 5.0//2
Out[44]: 2.0
In [45]: int(5.0//2) # conversion de float en int
Out[45]: 2
In [46]: 5%2 # reste de la division entière
Out[46]: 1
Opérateurs booléens
In [47]: b = True
"oui" == "oui"
Out[47]: True
In [48]: 3+1 == 4 and 5*2 == 20
Out[48]: False
In [49]: b == False or not 2 == 2 # utilisation du "et" logique et de la nég
Out[49]: False
In [50]: not b == False and not 2 == 2 # la négation ne sera appliquée qu'à
In [50]: not b == False and not 2 == 2 # la négation ne sera appliquée qu'à
Out[50]: False
In [51]: not (b == False and not 2 == 2) # notez la différence avec les pare
Out[51]: True
Structures de contrôle
Documentation : http://docs.python.org/2/tutorial/controlflow.html
Attention à l'indentation !
In [52]: i = 30
if i<30:
print("petit")
elif i==30:
print ("i vaut 30")
print("fin")
else:
print ("grand")
if i%5 == 0:
print("multiple de 5")
i vaut 30
fin
multiple de 5
In [53]: if i==30: print("OK")
OK
La fonction range permet de créer des intervalles
In [54]: len(range(3,10))
Out[54]: 7
In [55]: for i in range(4):
print i
print "ici, c'est la boucle"
print "ici, c'est fini"
0
ici, c'est la boucle
1
ici, c'est la boucle
2
ici, c'est la boucle
3
ici, c'est la boucle
ici, c'est fini
In [56]: i=0
while i<5:
print("i monte")
i += 1 # i = i + 1
print(i)
i monte
i monte
i monte
i monte
i monte
5
Structures de données
Les listes (tableaux)
L'indiçage des séquences commence à 0
In [57]: t = [ 'un', 'deux', 'trois', 3.14 ]
t[0]
Out[57]: 'un'
Documentation : http://docs.python.org/2/library/stdtypes.html#sequence­types­str­unicode­list­tuple­
bytearray­buffer­xrange et http://docs.python.org/2/library/stdtypes.html#mutable­sequence­types
Les chaînes de caractères sont des tableaux
In [58]: s = "Bonjour, comment allez-vous?"
s[0:7] # slicing
Out[58]: 'Bonjour'
In [59]: s[:7]
Out[59]: 'Bonjour'
In [60]: s[9:16]
Out[60]: 'comment'
In [61]: s[-1]
Out[61]: '?'
In [62]: t[-1]='!' # modification du dernier élément du tableau
t
Out[62]: ['un', 'deux', 'trois', '!']
Petit exercice pour suivre les références d'objets
In [63]: s1="un"
s2="deux"
s3 = s2
s2 = "rien"
print (s3) # s3 n'est pas modifé
deux
In [64]: l2 = [2,4,6]
l3 = l2
l4 = l2[:] # le slicing produit un nouveau tableau et donc un nouve
l2[2]=12
print(l3) # l3 subit la modification sur l2, car les deux référence
print(l4) # l4 n'est pas affecté, car il ne référence pas le même o
[2, 4, 12]
[2, 4, 6]
In [65]: s[:-5]
Out[65]: 'Bonjour, comment allez-'
In [66]: len(s)
Out[66]: 28
In [67]: print("vous" in s) # test d'appartenance
True
Pour faire une boucle sur les éléments du tableau :
In [68]: for element in t:
print(element)
un
deux
trois
!
Si vous voulez aussi l'indice, la fonction zip est pour vous :
In [69]: for indice,element in zip(range(len(t)),t):
In [69]: for indice,element in zip(range(len(t)),t):
print(str(indice) + " -> " + element)
0 -> un
1 -> deux
2 -> trois
3 -> !
Comment fonctionne l'affectation multiple
In [70]: a,b = 1,2
print ("a = "+str(a))
print("b = "+str(b))
a=1
b=2
zip retourne une liste d'éléments à 2 valeurs, qui sont donc affectés dans la boucle aux variables
indice et element
In [71]: zip(range(len(t)),t)
Out[71]: [(0, 'un'), (1, 'deux'), (2, 'trois'), (3, '!')]
Les dictionnaires
Listes d'associations clé/valeur
In [72]: d = {'Janvier':31,'Février':28,'Mars':31,'Avril':30,'Mai':31,
'Juillet':31,'Août':31,'Septembre':30,'Octobre':31,'Novembre'
print(d)
print(d['Septembre'])
for cle,valeur in d.items():
if valeur==30:
print(cle)
d.pop('Septembre')
# print(d['Septembre']) # n'existe plus
print('Septembre' in d)
{'D\xc3\xa9cembre': 31, 'F\xc3\xa9vrier': 28, 'Juillet': 31,
'Janvier': 31, 'Juin': 30, 'Mars': 31, 'Septembre': 30,
'Avril': 30, 'Novembre': 30, 'Octobre': 31, 'Mai': 31,
'Ao\xc3\xbbt': 31}
30
Juin
Septembre
Avril
Novembre
False
Affichage disgracieux dû à l'encodage en unicode, mieux géré avec python 3. Plus d'information sur
la gestion de l'unicode avec Python 2.7.x ici.
Un peu de programmation fonctionnelle avec les « compréhensions de
listes »
Documentation : http://docs.python.org/2/tutorial/datastructures.html#list­comprehensions
In [73]: t = [1,4,8,5,4,7,10]
Comment récupérer les nombres pairs ?
Avec une boucle classique :
In [74]: resultat = []
for element in t:
if element%2 == 0:
resultat.append(element)
print(resultat)
[4, 8, 4, 10]
Avec les compréhensions de listes :
In [75]: [element for element in t if element%2 == 0]
Out[75]: [4, 8, 4, 10]
In [76]: [cle for cle,valeur in d.items() if valeur==30]
Out[76]: ['Juin', 'Avril', 'Novembre']
Avec la fonction filter et une fonction anonyme lambda
In [77]: resultat = filter(lambda element:element%2 == 0, t) # prend en argu
print(resultat)
resultat = list(resultat) # nécessaire en python 3 car filter retou
print(resultat)
def monfiltre(element):
return element%2 == 0
print(filter(monfiltre, t)) # utilisation d'une fonction nommé et n
[4, 8, 4, 10]
[4, 8, 4, 10]
[4, 8, 4, 10]
In [78]: reduce(lambda x,y:x+y, t)
Out[78]: 39
map(lambda x:str(x), t) # applique une fonction à chaque élément
In [79]: map(lambda x:str(x), t) # applique une fonction à chaque élément
Out[79]: ['1', '4', '8', '5', '4', '7', '10']
In [80]: map(str, t) # simplification de l'exemple précédent, car la fonctio
Out[80]: ['1', '4', '8', '5', '4', '7', '10']
Écrire des fonctions
In [81]: def salut(nom):
print("Salut " + nom)
salut("Nicolas")
Salut Nicolas
In [82]: def salut2(nom, majuscule):
message = "Salut " + nom
if majuscule:
message = message.upper()
print(message)
salut2("Nicolas", True)
# salut2("Nicolas") # erreur car il faut 2 arguments
SALUT NICOLAS
In [83]: def salut3(nom, majuscule=True):
message = "Salut " + nom
if majuscule:
message = message.upper()
print(message)
salut3("Nicolas")
salut3("Nicolas", False)
salut3("Nicolas", majuscule=False) # argument nommé pour plus de cl
SALUT NICOLAS
Salut Nicolas
Salut Nicolas
Fonction avec retour de valeur en utilisant l'instruction return
In [84]: def selection(liste, pair=True):
return [element for element in liste if (element%2 == 0)
print(selection([1,4,7,12]))
print(selection([1,4,7,12], pair=False))
[4, 12]
[1, 7]
Les scripts
Pour graver dans la silice vos fabuleuses lignes de code, vous pouvez les écrire dans un fichier.
Exemple avec ce fichier script.py :
a=3
b=4
print(a*b)
Vous pouvez déclarer plusieurs fonctions dans votre scripts et du code principal (hors fonction, qui
sera exécuté) :
def salut(nom):
print("Salut " + nom)
salut("Nicolas")
Pour exécuter ce script :
dans un terminal : python script.py
dans ipython : %run script.py
In [85]: %run script.py
bonjour("Robert")
Bonjour Nicolas
Bonjour Robert
Les fichiers
In [86]: f = open('script.py', 'r')
print("Lit la ligne suivante dans le fichier :")
print(f.readline())
print("Lit le reste du fichier")
print(f.read())
f.close()
Lit la ligne suivante dans le fichier :
def bonjour(nom):
Lit le reste du fichier
print("Bonjour " + nom)
bonjour("Nicolas")
In [87]: sortie = open('sortie.txt', 'w')
In [87]: sortie = open('sortie.txt', 'w')
for valeur in ['un','deux','trois']:
sortie.write(valeur + "\n")
sortie.close()
In [88]: %%bash
cat sortie.txt
un
deux
trois
In [89]: with open('sortie.txt', 'r') as f:
num = 1
for ligne in f:
print(str(num) + " : " + ligne)
num += 1
1 : un
2 : deux
3 : trois
Les modules
Documentation : http://docs.python.org/2/tutorial/modules.html
Les bibliothèques additionnelles fournissent des fonctions et données supplémentaires en utilisant
des modules pour éviter les conflits de nommage. Pour accéder à ces fonctions, vous devez au
préalable importer le module correspondant.
In [90]: import math
print(math.pi)
from math import pi
print(pi)
from math import *
print(pi)
from math import pi as monpi
print(monpi)
3.14159265359
3.14159265359
3.14159265359
3.14159265359
Ces modules peuvent être fournis par votre installation python, mais aussi par de simples scripts
python.
In [91]: import script
script.bonjour("Paul")
Bonjour Paul
Le chargement du script a provoqué l'exécution du code hors­fonction (bonjour("Nicolas")).
Nous pouvons alors modifier notre script pour que ce code d'exemple (ou par défaut) ne soit exécuté
que lorsque le script est invoqué directement :
if __name__ == "__main__":
bonjour("Nicolas")
In [92]: import script2
from script2 import bonjour
bonjour('Nicolas')
Bonjour Nicolas
In [93]: %%bash
cat script2.py
mavariable = "depuis le script"
def bonjour(nom):
"""Affiche un message de bienvenue
"""
mavariable = "Bonjour "
print(mavariable + nom)
if __name__=="__main__":
import sys
print(sys.argv)
bonjour(sys.argv[1])
print("mavariable = "+ mavariable)
Utilisation d'arguments avec %run
In [94]: %run script2.py Bernard
['script2.py', 'Bernard']
Bonjour Bernard
mavariable = depuis le script
Modules intéressants
sys
sys.argv contient les arguments d'un script
if __name__ == "__main__":
import sys
bonjour(sys.argv[1])
csv http://docs.python.org/2/library/csv.html
In [95]: import csv
with open('donnees.csv','r') as f:
for ligne in csv.reader(f):
print(map(int,ligne))
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
math http://docs.python.org/2/library/math.html
In [96]: import math
math.cos(math.pi)
Out[96]: -1.0
In [97]: from math import *
exp(0)
Out[97]: 1.0
urllib2 http://docs.python.org/2/library/urllib2.html et json
http://docs.python.org/2/library/json.html
Pour s'amuser avec les données en ligne
In [98]: import urllib2
donnees = urllib2.urlopen('http://overpass-api.de/api/interpreter?d
import json
aeds = len(json.loads(donnees)[u'elements'])
print str(aeds) + " défibrillateurs à moins de 500 mètres d'ici"
. . .
Aperçu des classes et exceptions
Documentation : http://docs.python.org/3/tutorial/errors.html
In [99]: class Signet:
def __init__(self, name, url):
self.name = name
self.url = url
def updateURL(self, url):
self.url = url
def test(self):
import urllib2
try:
urllib2.urlopen(self.url)
except urllib2.URLError:
return False
return True
docPython = Signet("doc python", "http://docs.python.org")
print(docPython.url)
print(docPython.test())
docPython.updateURL("http://")
print(docPython.url)
print(docPython.test())
http://docs.python.org
True
http://
False