Python Cours
Python Cours
Langage Python
Fondamentaux
Cours
PRINCIPAL ATELIER
COURS METEO
PYTHON VIEWER
COMPLEMENT
IHM
PYQT
COMPLEMENT
CALCULS
SCIENTIFIQUES
ANNEXE
REGLES DE
CODAGE
Introduction
Environnement de développement
Bases du langage
Fonctions et modules
Classes et programmation orientée objet
Paquetages standards
Conclusion
Annexe
05/10/2020 © Copyright 2020 Cyril Keime & Arnaud Bêche 6
INTRODUCTION
Code source
Plusieurs
étapes
Compilateur
Code assembleur
Code objet
Assembleur (ou code binaire)
Linker
Exécutable
(ou éditeur de liens)
MAÎTRISE DE LA MACHINE
Code source
Pas de
compilation
Code de machine
Interpréteur virtuelle (bytecode)
Exécution
Machine virtuelle
#include <iostream>
#include <string>
using namespace std;
C++ int main() {
8 lignes
(1983) string msg = "Hello,world!";
cout << msg << endl;
return 0;
}
A Objet 1 Objet 3 B
Objet 2
• Un développeur peut donc coder chaque objet et le tester
unitairement. OK avec Python
L=
a b c d e
>> 0 1 2 3 …
len(L)-1
… -len(L) -4 -3 -2 -1 <<
1 inclus, 3 exclus, -4 inclus, -2 exclus
Sous-liste de 2 éléments : 3-1 = -2-(-4) = 2
L[1:3] == L[-4:-2] == L[1:-2] == L[-4:3]
Le premier / le dernier
EXERCICE
a[0] / a[-1]
Le nième élément depuis le début / la fin
a[n-1] / a[-n] Créer deux listes de 3 éléments, a et b.
Créer une troisième liste contenant, dans
• Extraire des sous-listes : l’ordre :
Toute la liste (ie copier une liste !) 1. Les deux premiers éléments de a
b = a[:]
Tous les éléments, sauf le premier 2. Les deux derniers éléments de b
a[1:]
Les deuxième et troisième éléments
a[1:3] Afficher la liste créée.
Les trois premiers éléments
a[:3]
Les trois derniers éléments
a[-3:]
Taille d’une liste L : len(L)
e = [3, 2, 1]
Une liste dispose de méthodes f = sorted(e)
très utiles : cf Tutorial print(f)
5.1. More on Lists e.sort()
print(e)
Indice :
• Ce code est équivalent à :
Utiliser le paramètre key pour spécifier la
fonction de calcul de la clé.
Employee = namedtuple(
'Employee', ['name', 'id'])
def getkey(x):
return x.telephone
sort(key=getkey)
ou bien :
Consulter la
documentation !
sort(key=lambda x:x.telephone)
if x > 0:
Créer une liste vide, et une autre non vide.
x -= 1 Test sur des nombres Utiliser successivement chacune de ces
elif x == 0:
x = 10 deux variables comme expression d’une
else: condition.
x = -1
Idem avec des chaînes de caractères.
if s == 'Lorem': Test sur des chaînes de
if s != 'Lorem': caractères
while expression:
pass
• Gérer une erreur run-time est possible Demander à l’utilisateur de saisir un entier.
grâce aux exceptions. Si l’utilisateur saisit une valeur invalide,
gérer l’exception et renvoyer -1.
• Voici un exemple très simple de code
fatal : Indice :
1/0 Déterminer d’abord l’exception à gérer en
• Et de gestion d’exceptions : faisant un essai sans bloc try.
try:
1/0
except ZeroDivisionError:
print('Division par 0.')
except:
print('Erreur inattendue.')
result1 = 2.54
– Listes, boucle et condition result2 = float('+00002.540')
print('Result: ' + str(result1))
print('Result: ' + str(result2*100))
– Conversions nombre / chaîne de caractères print('Result: ' + str(int(result2)*100))
a = 1
b = 11
– Echange de deux valeurs a, b = b, a
print(a, b)
• La valeur par défaut d’un argument est la def myfunctionC(param1, param2='a', param3=False, param4=0):
print(param1, param2, param3, param4)
valeur que prend l’argument s’il n’est pas
myfunctionA(1, 'a')
spécifié lors de l’appel de la fonction. myfunctionB(1, 'a')
myfunctionB(1, 'a', param3=True)
myfunctionB(1, 'a', param4=1)
• Par ailleurs, lors de l’appel d’une fonction, myfunctionB(1,
myfunctionB(1,
'a',
'a',
param4=1, param3=True)
True, 1)
il est possible de spécifier la valeur d’un myfunctionC(1)
myfunctionC(1, 'b')
argument quelconque de deux façons : myfunctionC(1, param4=1, param3=True, param2='b')
def getheadtemperature(config):
"""Get head temperature (°C)."""
simu, t = config
if simu:
headtemperature = [25 + i*2.5 for i in range(24)]
return headtemperature[t]
else:
return testbench.gettemperature()
def getemittedpower(config):
"""Get emitted power (W).""" Un exemple à étudier !
simu, t = config
if simu:
emittedpower =\
[1000, 1025, 1050, 1075] +\
[1100 - i*50 for i in range(20)]
return emittedpower[t]
else:
return testbench.getpower()
05/10/2020 © Copyright 2020 Cyril Keime & Arnaud Bêche 37
Les fonctions (4/4)
def runtest(simu=False):
"""Run test (24 h)."""
reporttemplate = '{:4d}; {:4.1f}; {:4.0f}'
report = []
report.append('{:4}; {:4}; {:4}'.format('time','temp','pow'))
for t in range(24):
headtemperature = getheadtemperature((simu, t))
emittedpower = getemittedpower((simu, t))
report.append(reporttemplate.format(
t,
headtemperature,
emittedpower))
for line in report:
print(line)
Un exemple à étudier !
#runtest()
simu = True
runtest(simu)
a = 5
• Méthode 2 : formater une chaîne de b = 6
manière immédiate : f-strings print(f'{a} + {b} = {a+b}')
print(f'{a:2d} + {b:2d} = {a+b:3d}')
• Un module peut donc être réutilisé, via Importer le paquetage standard permettant
la commande import, dans un autre de gérer la date et l’heure.
module ou script Python.
Afficher l’heure courante.
• Ce mécanisme est fondamental pour
organiser le code correctement, et
permettre sa maintenance.
import module
import module as name
• La commande import permet aussi de from module import object
from module import object as name
réutiliser un ensemble complet de
modules, appelé paquetage (ou
package).
#!/usr/bin/python3
• Un module doit être organisé, et sa # -*- coding: utf-8 -*-
structure peut être normalisée. """
Multi-line comment.
(module)
• Ci-contre un exemple de normalisation, """
if __name__ == '__main__':
mytest()
05/10/2020 © Copyright 2020 Cyril Keime & Arnaud Bêche 41
Les modules (3/3)
• Commande import :
– import mymodule
sys.path est la liste des dossiers
– Dans ce cas la condition de fin est fausse, et
pouvant contenir un module
la fonction de test n’est pas exécutée.
– Les constantes, fonctions et classes du
module importé sont maintenant disponibles !
en-but
D2 Déplacement d'un robot :
R2
r1.deplacer([r2, d1, d2], w, h)
4 objets « Robot », 1 objet « Plateau »,
y 1 objet « Jeu »
class Robot:
def __init__(self, equipe, but, x=0, y=0):
self.equipe = equipe
self.but = but
self.x = x
self.y = y
if self.but > 0:
self.angle = 90
else:
self.angle = -90
def deplacer(self, autres_robots, xmax, ymax):
# coder ici une stratégie de déplacement vers le but
# self.x = ...
# self.y = ...
# self.angle = ...
pass
class Plateau:
def __init__(self, width, height):
self.width = width
self.height = height
class Jeu:
def __init__(self, width, height):
self.plateau = Plateau(width, height)
self.liste_robots = [ Robot("R", self.plateau.width, 0, 0),
Robot("R", self.plateau.width, 0, self.plateau.height),
Robot("D", 0, self.plateau.width, 0),
Robot("D", 0, self.plateau.width, self.plateau.height)]
def next(self):
# déplacer tous les robots
for robot in self.liste_robots:
autres_robots = self.liste_robots[:]
autres_robots.remove(robot)
robot.deplacer(autres_robots, self.plateau.width, self.plateau.height)
# une équipe a-t-elle gagné ? (en pseudo-code)
si tous les robots R sont arrivés à droite:
return "R"
sinon si tous les robots D sont arrivés à gauche:
return "D"
if __name__ == "__main__":
jeu = Jeu(20, 10)
while True:
vainqueur = jeu.next()
if vainqueur:
print(f"L'équipe {vainqueur} a gagné")
break
• Remarques :
__repr__() remplace __str__() si celle-ci
n’est pas définie. En pratique,
toujours définir
__repr__()
__str__() d’un conteneur (list par exemple)
utilise __repr__() pour le contenu.
EXERCICE
Partir des fichiers model.py, view.py et game.py fournis (disponibles sur learnpython.ovh).
Dans le module model.py :
Compléter la classe Point
Créer les attributs x et y (de type entier) dans le constructeur
Implémenter la méthode __repr__ A faire également :
Ajouter une méthode permettant d’ajouter deux objets Point (__add__) • Tester la comparaison de 2 objets Point avant
d’implémenter la méthode __eq__
Ajouter une méthode permettant de comparer deux objets Point (__eq__) • Analyser le comportement de Python lors de
Compléter la classe Entity la « copie » d’un objet, par exemple :
Attributs de la classe définis dans le constructeur : p1 = Point(1, 2)
p2 = p1
Utiliser la classe Point pour stocker la position courante de l’entité (Réponse : création d’une référence et non copie !)
Utiliser la classe Point pour stocker la position précédente de l’entité
Utiliser une chaîne de caractères pour stocker le nom de l’entité
Implémenter la méthode __repr__
Méthode move() : implémenter la fonction pour déplacer l’entité de 1 case (diagonales autorisées) de manière aléatoire mais en
respectant les règles suivantes :
L’entité ne doit pas rester sur place
L’entité ne doit pas revenir à sa position précédente
L’entité doit rester dans le cadre fourni en arguments (xmin, ymin, xmax, ymax)
Important : Tester ces classes pendant le codage ! Pour cela, créer une fonction de test dès le début et tester les fonctionnalités au fur
et à mesure qu’elles sont implémentées.
EXERCICE
EXERCICE
Créer une classe capable de représenter un nombre complexe et de traiter les opérations suivantes :
• Retourner la partie réelle
• Retourner la partie imaginaire
• Implémenter __repr__()
• Retourner le module
• Retourner l’argument
• Modifier la valeur en inversant le nombre complexe
• Modifier la valeur en ajoutant un autre nombre complexe.
Pour les plus rapides : définir des opérateurs pour cette classe : +, *
Note : complexe est un type de base en Python. Voir la documentation !
class RobotBob(Robot):
def deplacer(self, autres_robots, xmax, ymax):
# méthode deplacer programmée par Bob
pass
class Jeu:
def __init__(self, width, height):
self.plateau = Plateau(width, height)
self.liste_robots = [ RobotAlice("R", self.plateau.width, 0, 0),
RobotAlice("R", self.plateau.width, 0, self.plateau.height),
RobotBob("D", 0, self.plateau.width, 0),
RobotBob("D", 0, self.plateau.width, self.plateau.height)]
EXERCICE
Important : Tester ces classes pendant le codage ! Pour cela, créer une fonction de test dès le début et tester les fonctionnalités au fur
et à mesure qu’elles sont implémentées.
Pour les plus rapides : Dériver la classe Entity pour créer une classe TeleportableEntity qui implémente une entité capable de se téléporter
n’importe où (en restant dans le tableau) tous les 5 déplacements (le reste du temps elle se déplace de manière aléatoire comme une
entité normale).
1. Écrire une classe FigureGeometrique définissant une interface de classe contenant les fonctions
Perimetre() et Surface(). Ajouter également à la classe FigureGeometrique un attribut privé nommé
« NomObjet » de type chaîne de caractères. Implémenter la méthode __repr__().
2. Écrire une classe Rectangle et une classe Cercle héritées de la classe FigureGeometrique et
implémentant les fonctions Perimetre() et Surface(). Le constructeur des classes Rectangle et Cercle permet
d’initialiser le nom et les dimensions des objets créés.
4. Créer et initialiser des objets des classes Rectangle, Carre et Cercle puis stocker ces objets dans une
liste.
5. A l’aide d’une boucle, afficher le nom, le périmètre et la surface de chaque objet, sans réaliser de test
sur le type ou le nom de l’objet.
class MyClass:
pickle — Python object serialization def __init__(self, a):
self.a = a
• The pickle module implements a
fundamental, but powerful algorithm for # Serialize
serializing and de-serializing a Python import pickle
from myclass import MyClass
object structure. “Pickling” is the l = [MyClass(123), MyClass('abc'),
process whereby a Python object MyClass(10**10)]
hierarchy is converted into a byte f = open('myclasslist.bin', 'wb')
pickle.dump(l, f,
stream, and “unpickling” is the inverse
pickle.HIGHEST_PROTOCOL)
operation, whereby a byte stream is f.close()
converted back into an object hierarchy.
Pickling (and unpickling) is alternatively
# Deserialize
known as “serialization”, “marshalling,” import pickle
[1] or “flattening”, however, to avoid f = open('myclasslist.bin', 'rb')
confusion, the terms used here are l = pickle.load(f)
f.close()
“pickling” and “unpickling”.
for instance in l:
print(instance.a)
• The unittest unit testing framework was originally inspired by JUnit and has a similar
flavor as major unit testing frameworks in other languages. It supports test
automation, sharing of setup and shutdown code for tests, aggregation of tests into
collections, and independence of the tests from the reporting framework.
Pratiquer !
05/10/2020 © Copyright 2020 Cyril Keime & Arnaud Bêche 67
M E R C I
# isinstance
a = 5
if isinstance(a, float):
print('a -> float')
elif isinstance (a, int):
print('a -> int')
print(isinstance ('', str))
# Opérateur +
class Book:
def __init__(self, title, nbpages):
self.title = title
self.nbpages = nbpages
def __repr__(self):
return '{} : {:d} pages'.format(self.title, self.nbpages)
def __add__(self, other):
return Book(' / '.join([self.title, other.title]),
self.nbpages + other.nbpages)
a = Book('Pavé', 1000)
b = Book('Résumé', 1)
print(a+b)
05/10/2020 © Copyright 2020 Cyril Keime & Arnaud Bêche 70
Morceaux de code
# * et **
def myfunc(*args, **kwargs):
s = ' '.join(args)
for k,v in kwargs.items():
s += ' {}={}'.format(k,v)
return s
print(myfunc('a'))
print(myfunc('a', 'b'))
print(myfunc('a', 'b', hello='world', good='bye'))
# set
a = {1,2,99,4,1,1,2,1,6,1,1,1,1,1,1,9,99,2}
print(a)
print(len(a))
b = [1,2,99,4,1,1,2,1,6,1,1,1,1,1,1,9,99,2]
c = list(set(b))
c.sort()
print(c)
# Générateurs
# En lecture seule une seule fois et de longueur inconnue !
generator = (x**2 for x in range(3))
for val in generator:
print(val)
for val in generator: # vide...
print(val)
# yield
# Dans une fonction, la transforme en générateur !
def compute(exp):
mylist = range(3)
for i in mylist:
yield i**exp
generator1 = compute(2)
generator2 = compute(3)
for val in generator1:
print(val)
for val in generator2:
print(val)
# for/else
def search(data, value):
for v in data:
if v == value:
print('FOUND')
break
else:
print('NOT FOUND')
v = None
return v
print(search([1, 42, 99, 51], 42))
print(search([1, 42, 99, 51], 43))
# with
with open('expourfinir3.py') as f:
for i,line in enumerate(f):
if i == 19:
print(line.strip())
break
05/10/2020 © Copyright 2020 Cyril Keime & Arnaud Bêche 73
Morceaux de code
# enum
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
for const in Color:
print(const.value)
print(Color.RED is Color.RED)
print(Color.RED is Color.GREEN)
# itertools
import itertools
data = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]
print(data)
print(list(itertools.accumulate(data, max)))
print(list(itertools.compress(data, [1,0,1,0,1,1])))
# next
def gencolours():
while(True):
yield 'RED'
yield 'GREEN'
yield 'BLUE'
colours = gencolours()
for i in range(10):
print(next(colours))