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'estce que Python ? Un langage Une suite d'outils sous licence libre Une bibliothèque en standard bien fournie Une plateforme 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 minibook : 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#numerictypesintfloatlongcomplex 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#sequencetypesstrunicodelisttuple bytearraybufferxrange et http://docs.python.org/2/library/stdtypes.html#mutablesequencetypes 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#listcomprehensions 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 horsfonction (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