Une introduction à Python 2 Olivier Gauthé Sommaire 1 Introduction 1 2 Environnement 2.1 Installation . . . . . 2.2 Windows . . . . . . . 2.3 Linux et macOS . . . 2.4 Utilisation de Spyder . . . . 2 2 2 2 2 . . . . . 3 3 4 5 5 5 . . . . . . . . 3 Premier pas sur Python 3.1 Une calculatrice . . . . . 3.2 Les variables . . . . . . . 3.3 Les listes . . . . . . . . . 3.4 Les booléens . . . . . . . 3.5 Les fonctions prédéfinies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Les boucles 6 5 Les fonctions 7 6 Lire et écrire dans un fichier 8 7 Écrire un programme dans un fichier 9 8 Quelques éléments de calcul numérique 10 9 Le calcul formel avec SymPy 11 9.1 Pourquoi le calcul formel ? . . . . . . . . . . . . . . . . . . . . . 11 9.2 Premiers pas sur SymPy . . . . . . . . . . . . . . . . . . . . . . 11 1 Introduction Ce tutoriel s’adresse à des étudiants qui n’ont jamais fait de Python auparavant. Par contre, il part du principe qu’ils ont déjà été initié à la programmation et comprennent les concepts de variable ou de boucle. Python est un langage de programmation qui recherche avant tout la simplicité et la lisibilité, en particulier il est très proche du langage humain. C’est 1 un langage de programmation complet, qui offre bien plus de possibilités qu’un langage comme MATLAB, restreint au calcul mathématique. De plus, Python dispose de bibliothèques scientifiques très fournies. Sa principale limite reste la performance : un code en Python s’écrit rapidement mais s’exécutera lentement. L’ENS Ulm propose un très bon tutoriel pour Python à destination des classes préparatoires. L’auteur recommande également le tutoriels d’Open Classrooms ainsi que celui de Tutorials Point (en anglais). Attention cependant, Open Classrooms utilise Python 3, ce qui change notamment la syntaxe de la division entière et celle de la fonction print. La documentation officielle de Python 2 se trouve ici. Celle de SymPy se trouve là : là. Enfin, une documentation complète sur l’utilisation scientifique de Python, notamment de SymPy se trouve ici. 2 2.1 Environnement Installation Pour être certain de disposer de tous les modules nécessaires et avoir une interface unique, nous travaillerons à partir de la distribution Anaconda Python. Suivre les instructions de la page de téléchargement pour l’installer. Il n’est pas nécessaire de disposer des droits administrateurs. 2.2 Windows Lancer le programme Python(x,y). Celui-ci propose de lancer Spyder ou IPython en console (plus minimaliste). Lancer Spyder en cliquant sur l’icône du serpent rouge. 2.3 Linux et macOS Sur Linux ou macOS, on peut utiliser Python ou IPython (Interactive Python) directement dans la console, en rentrant python ou ipython dans un terminal. Pour que tout le monde ait la même interface, on va également utiliser Spyder. Lancer Spyder en rentrant spyder dans un terminal. 2.4 Utilisation de Spyder Spyder est un environnement de développement pour Python. Il fournit une interface graphique avec une console en bas à droite, des informations au-dessus et un script à gauche. Avant tout chose, se placer dans un répertoire dédié : créer un nouveau répertoire avec l’explorateur de fichier, puis se placer dans ce répertoire avec Spyder : le répertoire courant de Spyder est affiché en haut à droite (voir image). Par défaut, ce répertoire est $HOME/.config/spyder sur Linux. 2 On peut rentrer le code directement dans la console, ou alors utiliser le script de la partie gauche, le sauvegarder et l’exécuter avec la touche F5. Par défaut, le script est sauvegardé dans le répertoire courant de Spyder, d’où l’importance d’être dans un répertoire dédié. La console peut être Python ou IPython, IPython se voulant plus interactif et plus facile d’accès pour le débutant : on peut créer une nouvelle console du type voulu avec un clic droit sur l’onglet de la console. Dans ce qui suit, on utilise la console Python (d’où les »> ), mais le résultat serait le même avec une console IPython. 3 Premier pas sur Python 3.1 Une calculatrice Essayer les opérations classiques dans la console : >>> >>> >>> >>> >>> 1 + 1 2*3 3.14 + 2.72 1 + 3.14 1j*1j Le calcul entre floats n’est pas exact, on a une erreur d’arrondi. En Python 2, la division entre entier par défaut est la division euclidienne. Le reste s’obtient avec %, il est toujours positif. Les puissances s’écrivent avec ** : ab → a**b ; les priorités opératoires sont usuelles et les opérations se font de la gauche vers la droite. >>> 10/3 >>> 10%3 >>> -1%2 3 >>> 10./3 >>> 1 + 2*3%4 3.2 Les variables On assigne une variable avec le signe =. Le nom d’une variable est sensible à la casse, aussi long qu’on le souhaite et peut contenir des chiffres, sauf le premier caractère. Ne pas utiliser d’accents et autres caractères spéciaux. >>> a = 1 >>> A = 2 >>> a + A On peut assigner plusieurs variables sur une seule ligne, ou échanger deux variables. Pour afficher une variable, on utilise print (attention, syntaxe différente en Python 3) >>> >>> >>> >>> a,b,c print a,b = print = 1,2,3 a,b,c b,a a,b Une variable Python a un type. Celui-ci est dynamique et peut changer sans créer d’erreur. Utiliser des noms de variables logiques : on s’attend à ce que x soit un réel, pas un entier ! >>> >>> >>> >>> >>> >>> >>> i = 5 print i type(i) c = 1.0 type(c) c = "Paul Sabatier" type(c) Pour modifier une variable, on peut utiliser les opérateurs +=, -=, *= etc : >>> >>> >>> >>> >>> n = 1 n += 3 n n *= 2 n On peut effectuer des opérations entre variables de différents types, en général tant que cela a un sens Python se débouille. >>> >>> >>> >>> >>> >>> >>> s1, s2 = "Paul", "Sabatier" n = 3 x = 3.14 n + True n* x s1 + " " + s2 s1 + n # erreur 4 Pour une chaîne de caractère, on peut utiliser indifféremment guillemets ", apostrophes ’, ou triples guillemets """. On peut y insérer une valeur avec la syntaxe .format : >>> print ’1 + 1 = {}’.format(1+1) >>> a = 3 >>> print """a^2 = {}, a*2 = {}""".format(a**2,a*2) 3.3 Les listes Une liste Python s’écrit entre crochets []. Elle peut contenir des variables de type différents : >>> maListe = [1, 3.14, "spam", 2+2, "eggs"] >>> print maListe >>> type(maListe) On accède à un élément d’une liste avec l’opérateur []. On accède à sa longueur avec la fonction len. En Python, les indices vont de 0 à len(maListe) -1. >>> len(maListe) >>> print maListe[0], maListe[1], maListe[2] >>> print maListe[len(maList)] # erreur On peut ajouter ou supprimer des éléments à une liste : >>> >>> >>> >>> 3.4 maListe maListe += ["bacon"] maListe.remove("eggs") maListe Les booléens Un booléen est une variable qui vaut True ou False. On peut leur appliquer les opérateurs and, or, not (équivalent à !). >>> b = True >>> type(b) >>> not b or (b and not b) 3.5 Les fonctions prédéfinies Python dispose d’un certain nombre fonction prédéfinies : >>> >>> >>> >>> max(1,2) l = [1,2,3,4,5] print max(l), min(l), sum(l) int(3.5) 5 Pour obtenir plus d’information sur une fonction ou une variable, IPython autorise la syntaxe ?x. Attention, cette aide n’est pas disponible dans la console Python de base. Pour les variables, type donne l’information la plus utile. Pour les fonctions, l’aide en ligne reste en général plus claire : https://docs. python.org/2.7/. 4 Les boucles Le principe de Python est que la syntaxe est fixée par l’indentation : tout nouveau bloc d’instruction implique une indentation supplémentaire, et s’arrête quand cette indentation disparaît. À la fin d’une série d’instruction, en sortant du dernier niveau d’indentation, il faut passer une ligne. La syntaxe de la boucle for est for x in E: ne pas oublier les " :" ! Cette syntaxe est très générale et permissive : on peut itérer sur tout contenu itérable, comme une liste, une chaîne de caractère, un tuple... Pour une boucle sur des entiers, on utilise range pour construire l’ensemble des nombres voulus et itérer dessus. La convention Python est l’intervalle ouvert : range(m,n) contient les nombres de m à n − 1. >>> ... ... >>> ... ... >>> >>> ... ... >>> >>> ... ... for i in range(10): print i for i in range(3,12): print i, # noter la difference avec et sans virgule s = "Sabatier" for char in s: print char, maListe = [1, 3.14, 4, "eggs"] for x in maListe: print x, On peut imbriquer des instructions et des boucles en ajoutant un niveau d’indentation à chaque fois. Les autres instructions ont une syntaxe proche, toujours avec un :. La syntaxe d’une instruction conditionnelle est if boolean:, les opérateurs >, <, >=, <=, ==, != ont le résultat attendu. La syntaxe while est while boolean: Exemple de conditions imbriquées : >>> for i in range(5): ... j = 0 ... while j<6: ... if i+j == 2: ... print "{} + {} = 2".format(i,j) ... elif i+j == 3: 6 ... ... ... ... ... print "{} + {} = 3".format(i,j) else: print i,j, "ni 2 ni 3" j += 1 Le nombre d’espace utilisées pour l’indentation n’a pas d’importance, il faut juste utiliser le même au sein d’un même bloc d’instruction. 5 Les fonctions La syntaxe pour déclarer une fonction est def func(arg): Encore une fois, on indente dans le corps de la fonction et on passe une ligne pour signaler la fin du bloc d’instruction : >>> def somme(i,j): ... return i+j ... >>> somme(1,2) Les fonctions sont surchargées par défaut : tant que les opérations utilisées ont un sens pour les types considérées, la fonction marche avec les variables données. On peut passer des arguments par défaut en rajoutant un = >>> >>> ... ... >>> >>> somme("Paul ","Sabatier") def somme2(x,y=2): return x+y somme2(1,3) somme2(1) On peut manipuler une fonction comme n’importe quelle variable (regarder son type), et la prendre comme argument d’une autre fonction. Il faut par contre toujours veiller à ce que les opérations aient un sens et que les arguments soient les bons. >>> type(somme) >>> def g(x,y,f): ... return f(x,y) + x ... >>> g(1,2,somme) Python est très laxiste sur ce que peut faire une fonction : elle peut utiliser une variable globale définie en dehors de la fonction, renvoyer des variables de types différents selon les cas, renvoyer une ou plusieurs variables, ne rien renvoyer... Cependant, par cohérence et pour la lisibilité, il convient de toujours renvoyer le même nombre de valeurs avec le même type. La fonction s’arrête lorsqu’elle arrive à un return. Exemple : 7 >>> m = 3 >>> def f(n): ... if not n%3: ... return n+m ... if n%3 == 1: ... return 2*n+1 ... if n%3 == 2 and n%2 == 1: ... return 2*n+2 ... return 0 ... On peut également définir une fonction avec la syntaxe f = lambda arg: result. Une lambda fonction a une syntaxe très simple et permet de définir des rapidement des fonctions. Il est conseillé de ne les utiliser que dans des cas très simple : pas plus d’une ligne. La syntaxe def est en général plus claire. >>> f = lambda x,y: x + y >>> f(1,1) >>> type(f) Python autorise une fonction à modifier ses arguments. En général mieux vaut éviter de le faire, le résultat est souvent contre-intuitif et rend le code plus difficile à lire. 6 Lire et écrire dans un fichier On utilise le mot-clé with et la fonction open. On passe le nom du fichier et le mode de lecture comme argument à open et on ajoute un niveau d’indentation : le fichier est accessible à l’intérieur de ce bloc d’instruction, toujours défini par l’indentation. Python s’assure tout seul que le fichier est bien ouvert, qu’il existe dans le cas d’une lecture et que tout se passe bien, en particulier que dans tous les cas le fichier est bien fermé à la fin du bloc d’instruction. Par défaut, les fichiers sont ouverts dans le répertoire courant, il faut donc veiller à travailler dans un répertoire dédié (indiqué en haut à droite). On peut aussi spécifier un chemin dans le nom du fichier. Les actions possibles dans un fichier sont spécifiées par le mode d’ouverture du fichier. Celles-ci sont : — "r" read — "w" write — "a" append — "b" binary >>> with open("fichier1.txt","w") as myFile: ... myFile.write("Paul Sabatier\n") ... myFile.write("Toulouse {}\n".format(3)) ... 8 Regarder avec un bloc note ce que contient le fichier. Comparer avec ce qui se passe lorsqu’on enlève le \n. On peut bien sûr mettre une boucle à l’intérieur du bloc with open et écrire un texte différent à chaque itération. Il y a beaucoup de méthodes possibles pour récupérer les données une fois le fichier ouvert, en voici quelques-unes, regarder l’aide en ligne pour en trouver d’autres. >>> ... ... ... >>> >>> ... ... ... >>> ... ... with open(filename,"r") as myFile: line1 = myFile.readline() # read first line line2 = myFile.readline() # read second line print line1, line2 with open(file2,"r") as myFile: for line in myFile: # read line by line print line with open(file3,"r") as myFile: data = myFile.readlines() # store the whole file La dernière méthode permet de récupérer la totalité du contenu du fichier d’un coup, mais il faut faire attention à ce que le fichier ne soit pas trop gros pour ne pas saturer la mémoire. Pour sauvegarder de gros objets (tableaux de nombre...) et les recharger directement dans l’environnement, regarder l’aide en ligne du module pickle. 7 Écrire un programme dans un fichier La console Python n’est pas un environnement pratique pour écrire de longs scripts : si on fait une erreur à un endroit, on est obligé de réécrire tout le bloc d’instructions depuis le début. Il est donc utile d’écrire un script dans un fichier annexe. L’extension d’un fichier de code Python est .py. Dans Spyder, il suffit d’utiliser l’éditeur de script à gauche. Par défaut le script s’appelle temp.py et est sauvegardé dans le répertoire courant, mais on peut le renommer et le sauvegarder comme on veut. Une fois le fichier sauvegardé, on l’exécute dans Spyder en appuyant sur la touche F5. Pour exécuter un script directement dans la console Linux, il faut se placer dans le répertoire où se trouve le script et rentrer python monScript.py Pour rester dans Python une fois l’exécution du script terminée, on rajoute le flag -i. Cela permet de rester dans l’environnement Python une fois le programme terminé. Les variables et fonctions utilisées dans le script sont toujours définies, comme si on avait juste copié collé les instructions dans la console. python -i monScript.py 9 8 Quelques éléments de calcul numérique Pour faire du calcul numérique avec Python, on utilise le module NumPy (Numeric Python). On appelle un module avec le mot-clé import. On utilise le mot-clé as pour raccourcir le nom à appeler : >>> import numpy as np Le module NumPy fournit une liste de fonctions usuelles en mathématiques : sqrt, exp, cos, sin, log, log2 , log10 , floor, ceil, round... Le tutoriel officiel contient beaucoup d’informations. Quelques exemples : >>> print np.exp(1.0), np.exp(np.pi*1j), np.sin(np.pi/2) >>> print np.log(np.exp(1)), np.log2(8.0), np.log10(100) >>> print np.angle(1j), np.abs(1+1j), np.sqrt(2) NumPy fournit des tableaux très performants pour le calcul matriciel : >>> >>> >>> >>> >>> >>> X, Y = np.zeros(3), np.ones(3) Z = X + 2*Y A = np.array([0,1,2]) id3 = np.eye(3) mat = np.array([[0,1,2],[3,4,5],[6,7,8]]) mat1 = np.zeros((3,3)) Comme pour les listes, on accède à un élément du tableau avec les crochets. Les indices vont toujours de 0 à n − 1. Pour un tableau à plusieurs dimensions, on met plusieurs indices dans les crochets : Z[0] est la première ligne de Z, Z[0,0] est le coefficient (0, 0), première ligne première colonne. On peut également initialiser un tableau avec une liste, comme ici pour A. Noter les doubles parenthèses : np.zeros prend un seul argument, un tuple. On peut définir des tableaux de toute taille et de toute forme, à tout moment on peut récupérer la taille d’un tableau avec la variable membre shape : >>> print mat.shape >>> mat2 = 2*np.ones(mat.shape) >>> print mat2 Les opérations algébriques usuelles ainsi que les fonctions NumPy peuvent être appliquée directement sur un tableau et sont effectuées terme à terme, et ce de manière beaucoup plus rapide qu’en faisant une boucle sur tous les éléments du tableau. Le produit scalaire, le produit matriciel et plus généralement, tout produit tensoriel se font avec la fonction dot. L’opérateur * effectue la multiplication terme à terme. >>> >>> >>> >>> >>> >>> >>> np.exp(A) np.cos(mat) np.dot(A,Z) np.dot(mat,A) np.dot(mat,mat2) np.dot(id3,mat) id3*mat 10 NumPy possède de nombreux outils pour les nombres aléatoires : >>> np.random.random() >>> np.random.random(4) >>> np.random.random((4,4)) Enfin, NumPy propose toutes les options utiles de slicing avec ":" : >>> mat1[1,:] >>> mat[1:3,0:2] Pour une utilisation plus avancée, le module scipy (Scientific Python) contient toutes les fonctionnalités qu’on attend d’une bibliothèque scientifique : algèbre linéaire, fonctions spéciales, analyse de Fourier... Pour tracer des courbes, on utilisera le module matplotlib. 9 9.1 >>> ... ... ... ... ... ... >>> >>> >>> 9.2 Le calcul formel avec SymPy Pourquoi le calcul formel ? def f(x): y = x**-1 print "x*y =", print "x*y*x*y print "x*x*y*y print "y*y*x*x x*y =", x*y*x*y =", x*x*y*y =" ,y*y*x*x f(2) f(1e-300) print np.angle(-1), np.angle(np.conjugate(np.exp(np.pi*1j))) Premiers pas sur SymPy Appeler SymPy. On va appeler tous les éléments du module, de manière à ne pas devoir rajouter un radical (comme np pour numpy) à chaque fois. >>> from sympy import * On aurait pu faire comme pour NumPy et utiliser import Sympy as sp. Il faudrait alors ajouter un préfixe sp. à tous les objets SymPy utilisés. L’important est de ne pas avoir de conflit de nomination : les modules SymPy et NumPy fournissent tous les deux la fonction exp, par exemple, mais les deux fonctions ont des comportements différents. Il faut donc s’assurer qu’on appelle bien la bonne, et donc qu’elles aient un nom différent. Ici, on appelle la fonction NumPy avec np.exp et la fonction SymPy avec exp (ou sp.exp si on a utilisé as sp lors de l’appel de SymPy) : pas de problème. Ce qui suit reproduit en grande partie le tutoriel officiel. Quelques exemples de base : 11 >>> >>> >>> >>> >>> >>> >>> a = Rational(1,2) b = Rational(1,4) a*2 a + b pi**2 pi.evalf() (pi + exp(1)).evalf(100) L’infini s’écrit oo >>> oo + 1 >>> oo > 1000 Les variables symboliques SymPy doivent être déclarée explicitement. Elles peuvent ensuite êtres utilisées comme des variables classiques : >>> >>> >>> >>> x = Symbol(’x’) x = Symbol(’y’) x + y + x - y (x + y)**2 Reprendre la fonction f définie plus haut et lancer f(x), avec x défini comme symbole SymPy. 12