Python
Python
Python
Une variable est un espace mémoire dans lequel il est possible de stocker
une valeur (une donnée).
Ouvrir IDLE :
Démarrer → Programmes → Python → IDLE (Python GUI)
0- Noms de variables
Le nom d'une variable s'écrit avec des lettres (non accentuées), des
chiffres ou bien l'underscore _
Le nom d'une variable ne doit pas commencer par un chiffre.
En langage Python, l'usage est de ne pas utiliser de lettres majuscules
pour nommer les variables (celles-ci sont réservées pour nommer les
classes).
Exemple : age, mon_age, temperature1
A éviter : Age, AGE, MonAge, monAge, Temperature1
4- Le type list (liste)
Une liste est une structure de données.
Le premier élément d'une liste possède l'indice (l'index) 0.
Dans une liste, on peut avoir des éléments de plusieurs types.
>>> infoperso = ['Pierre', 'Dupont', 17, 1.75,
72.5]
>>> # la liste infoperso contient 5 éléments de
types str, str, int, float et float
>>> print(type(infoperso))
<class 'list'>
>>> print(infoperso)
['Pierre', 'Dupont', 17, 1.75, 72.5]
>>> print('Prénom : ', infoperso[0]) #
premier élément (indice 0)
Prénom : Pierre
>>> print('Age : ', infoperso[2]) # le
troisième élément a l'indice 2
Age : 17
>>> print('Taille : ', infoperso[3]) # le
quatrième élément a l'indice 3
Taille : 1.75
La fonction range() crée une liste d'entiers régulièrement espacés :
>>> maliste = range(10)
>>> print(list(maliste))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(type(maliste))
<class 'range'>
>>> maliste = range(1,10,2) # range(début,fin
non comprise,intervalle)
>>> print(list(maliste))
[1, 3, 5, 7, 9]
>>> print(maliste[2]) # le troisième
élément a l'indice 2
5
On peut créer une liste de listes, qui s'apparente à un tableau à 2
dimensions (ligne, colonne) :
0 1 2
10 11 12
20 21 22
>>> maliste = [[0, 1, 2], [10, 11, 12], [20, 21,
22]]
>>> print(maliste[0])
[0, 1, 2]
>>> print(maliste[0][0])
0
>>> print(maliste[2][1]) # élément à la
troisième ligne et deuxième colonne
21
>>> maliste[2][1] = 69 # nouvelle
affectation
>>> print(maliste)
[[0, 1, 2], [10, 11, 12], [20, 69, 22]]
5- Le type bool (booléen)
Deux valeurs sont possibles : True et False
>>> choix = True
>>> print(type(choix))
<class 'bool'>
Les opérateurs de comparaison :
Opérateu
Signification Remarques
r
< strictement inférieur
<= inférieur ou égal
strictement
>
supérieur
>= supérieur ou égal
== égal Attention : deux signes ==
!= différent
>>> b = 10
>>> print(b > 8)
True
>>> print(b == 5)
False
>>> print(b != 10)
False
>>> print(0 <= b <= 20)
True
Les opérateurs logiques : and, or, not
>>> note = 13.0
>>> mention_ab = note >= 12.0 and note < 14.0 # ou
bien : mention_ab = 12.0 <= note < 14.0
>>> print(mention_ab)
True
>>> print(not mention_ab)
False
>>> print(note == 20.0 or note == 0.0)
False
L'opérateur in s'utilise avec des chaînes (type str) ou des listes
(type list) :
>>> chaine = 'Bonsoir'
>>> # la sous-chaîne 'soir' fait-elle partie de la
chaîne 'Bonsoir' ?
>>> resultat = 'soir' in chaine
>>> print(resultat)
True
>>> print('b' in chaine)
False
>>> maliste = [4, 8, 15]
>>> # le nombre entier 9 est-il dans la liste ?
>>> print(9 in maliste)
False
>>> print(8 in maliste)
True
>>> print(14 not in maliste)
True
6- Le type dict (dictionnaire)
Un dictionnaire stocke des données sous la forme clé ⇒ valeur
Une clé est unique et n'est pas nécessairement un entier (comme c'est le
cas de l'indice d'une liste).
>>> moyennes = {'math': 12.5, 'anglais': 15.8} #
entre accolades
>>> print(type(moyennes))
<class 'dict'>
>>> print(moyennes['anglais']) # entre
crochets
15.8
>>> moyennes['anglais'] = 14.3 # nouvelle
affectation
>>> print(moyennes)
{'anglais': 14.3, 'math': 12.5}
>>> moyennes['sport'] = 11.0 # nouvelle
entrée
>>> print(moyennes)
{'sport': 11.0, 'anglais': 14.3, 'math': 12.5}
7- Autres types
Nous avons vu les types les plus courants.
Il en existe bien d'autres :
complex (nombres complexes, par exemple 1+2.5j)
tuple (structure de données)
set (structure de données)
file (fichiers)
...
Exercices
Exercice 1.1 ☆ Afficher la taille en octets et en bits d'un fichier de 536
ko.
On donne : 1 ko (1 kilooctet) = 210 octets !!!
1 octet = 1 byte = 8 bits
Premier script
Nous allons commencer par créer le script Condition1.py :
Ouvrir IDLE :
Démarrer → Programmes → Python → IDLE (Python GUI)
File → New Window
Copier puis coller le code source ci-dessous :
# script Condition1.py
L'instruction else
Une instruction else est toujours associée à une instruction if
Syntaxe
if expression:
bloc d'instructions 1 # attention à
l'indentation
else: # else est au même niveau
que if
bloc d'instructions 2 # attention à
l'indentation
# suite du programme
Si l'expression est vraie (True) alors le bloc d'instructions 1 est exécuté.
Si l'expression est fausse (False) alors c'est le bloc d'instructions 2 qui est
exécuté.
# script Condition2.py
Syntaxe
if expression 1:
bloc d'instructions 1
elif expression 2:
bloc d'instructions 2
elif expression 3:
bloc d'instructions 3 # ici deux instructions
elif, mais il n'y a pas de limitation
else:
bloc d'instructions 4
# suite du programme
Si l'expression 1 est vraie alors le bloc d'instructions 1 est exécuté, et on
passe à la suite du programme.
Si l'expression 1 est fausse alors on teste l'expression 2 :
si l'expression 2 est vraie on exécute le bloc d'instructions 2, et on
passe à la suite du programme.
si l'expression 2 est fausse alors on teste l'expression 3, etc.
Le bloc d'instructions 4 est donc exécuté si toutes les expressions sont
fausses (c'est le bloc "par défaut").
Parfois il n'y a rien à faire.
Dans ce cas, on peut omettre l'instruction else :
if expression 1:
bloc d'instructions 1
elif expression 2:
bloc d'instructions 2
elif expression 3:
bloc d'instructions 3
# suite du programme
L'instruction elif évite souvent l'utilisation de conditions imbriquées (et
souvent compliquées).
Exemple
# script Condition5.py
# ce script fait la même chose que Condition4.py
Exercices
Exercice 2.1 ★ Le numéro de sécurité sociale est constitué de 13 chiffres
auquel s'ajoute la clé de contrôle (2 chiffres).
La clé de contrôle est calculée par la formule : 97 - (numéro de sécurité
sociale modulo 97)
Ecrire un script qui contrôle la validité d'un numéro de sécurité sociale.
On pourra utiliser la fonction int()pour convertir le type str en
type int.
Exemple :
>>>
Entrer votre numéro de sécurité sociale (13
chiffres) --> 1891126108268
Entrer votre clé de contrôle (2 chiffres)
--------------> 91
Votre numéro de sécurité sociale est valide.
>>>
Entrer votre numéro de sécurité sociale (13
chiffres) --> 2891126108268
Entrer votre clé de contrôle (2 chiffres)
--------------> 91
Votre numéro de sécurité sociale est INVALIDE !
>>>
Exercice 2.2 ★ Nombre entier non signé et signé
Dans un octet, on peut stocker un nombre entier compris entre
0b00000000 = 0 et 0b11111111 = 255 (entier non signé, en numération
binaire naturel).
On peut aussi stocker un entier compris entre -128 et +127 (entier signé,
représentation dite en complément à deux).
En complément à deux, les nombres négatifs sont codés de la manière
suivante :
-1 correspond à 255 en binaire naturel
-2 correspond à 254 en binaire naturel
...
-127 correspond à 129 en binaire naturel
-128 correspond à 128 en binaire naturel
1) Ecrire un script qui donne la correspondance entre entier signé et entier
non signé.
Par exemple :
>>>
Entrer un entier signé en complément à deux (-128 à
+127): 25
La représentation en binaire naturel est : 25
>>>
Entrer un entier signé en complément à deux (-128 à
+127): -15
La représentation en binaire naturel est : 241
2) Ecrire un script qui donne la correspondance entre entier non signé et
entier signé.
Par exemple :
>>>
Entrer un nombre entier (0 à 255): 250
Cela représente l'entier signé : -6
Exercice 2.3 ★ Ecrire un script qui demande la note au bac et qui affiche
la mention correspondante.
Par exemple :
>>>
Note au bac (sur 20) : 13.5
Bac avec mention Assez Bien
>>>
Note au bac (sur 20) : 10.9
Bac avec mention Passable
>>>
Note au bac (sur 20) : 4
Recalé
>>>
Exercice 2.4 ★ Ecrire un script qui calcule l'indice de masse corporelle
(IMC) d'un adulte et qui en donne l'interprétation (corpulence normale,
surpoids...).
Par exemple :
>>>
Votre taille en cm ? 170
Votre masse en kg ? 68.5
IMC = 23.70 kg/m²
Interprétation : corpulence normale
>>>
Exercice 2.5 ★★ Ecrire un script qui résout l'équation du second degré :
ax² + bx + c = 0
Par exemple :
>>>
Résolution de l'équation du second degré : ax² + bx
+ c = 0
Coefficient a ? 1
Coefficient b ? -0.9
Coefficient c ? 0.056
Discriminant : 0.586
Deux solutions :
0.0672468158199
0.83275318418
>>>
Résolution de l'équation du second degré : ax² + bx
+ c = 0
Coefficient a ? 2
Coefficient b ? 1.5
Coefficient c ? 4
Discriminant : -29.75
Il n'y a pas de solution.
L'instruction while
Syntaxe
while expression: # ne pas oublier le signe
de ponctuation ':'
bloc d'instructions # attention à
l'indentation
# suite du programme
Si l'expression est vraie (True) le bloc d'instructions est exécuté, puis
l'expression est à nouveau évaluée.
Le cycle continue jusqu'à ce que l'expression soit fausse (False) : on
passe alors à la suite du programme.
L'instruction for
Syntaxe
for élément in séquence :
bloc d'instructions
# suite du programme
Les éléments de la séquence sont issus d'une chaîne de caractères ou bien
d'une liste.
chaine = 'Bonsoir'
for lettre in chaine: # lettre est la
variable d'itération
print(lettre)
print("Fin de la boucle")
La variable lettre est initialisée avec le premier élément de la séquence
('B').
Le bloc d'instructions est alors exécuté.
Puis la variable lettre est mise à jour avec le second élément de la
séquence ('o') et le bloc d'instructions à nouveau exécuté...
Le bloc d'instructions est exécuté une dernière fois lorsqu'on arrive au
dernier élément de la séquence ('r') :
>>>
B
o
n
s
o
i
r
Fin de la boucle
Exemple avec les éléments d'une liste
# script Boucle5.py
maliste = ['Pierre', 67.5, 18]
for element in maliste:
print(element)
print("Fin de la boucle")
Là, on affiche dans l'ordre les éléments de la liste :
>>>
Pierre
67.5
18
Fin de la boucle
Fonction range()
for i in range(1,5):
print(i)
print("Fin de la boucle")
>>>
[1, 2, 3, 4]
1
2
3
4
Fin de la boucle
Table de multiplication
La création d'une table de multiplication paraît plus simple avec une
boucle for qu'avec une boucle while :
# script Boucle7.py
L'instruction break
L'instruction break provoque une sortie immédiate d'une
boucle while ou d'une boucle for.
Astuce
Si vous connaissez le nombre de boucles à effectuer, utiliser une
boucle for.
Autrement, utiliser une boucle while (notamment pour faire des boucles
sans fin).
Exercices
Exercice 3.1 ★ Ecrire un script qui affiche toutes les tables de
multiplication (de 1 à 10).
Exercice 3.5 ★☆
1) Ecrire le script du jeu de devinette suivant :
>>>
Le jeu consiste à deviner un nombre entre 1 et
100 :
---> 50
trop petit !
---> 75
trop petit !
---> 87
trop grand !
---> 81
trop petit !
---> 84
trop petit !
---> 85
Gagné en 6 coups !
2) Quelle est la stratégie la plus efficace ?
3) Montrer que l'on peut deviner un nombre en 7 coups maximum.
Bibliographie : La dichotomie
Remarque : pour créer un nombre entier aléatoire entre 1 et 100 :
import random
nombre = random.randint(1,100)
Exercice 3.6 ★★ Code de César
En cryptographie, le code de César est une technique de chiffrement
élémentaire qui consiste à décaler une lettre de 3 rangs vers la droite :
A→D
B→E
...
Z→C
1) Ecrire le script de ce codage.
Par exemple :
>>>
Message à coder ? abcdefghijklmnopqrstuvwxyz
defghijklmnopqrstuvwxyzabc
>>>
Message à coder ? Monty Python's Flying Circus
prqwb sbwkrq'v ioblqj flufxv
On pourra utiliser la chaîne 'abcdefghijklmnopqrstuvwxyz' et la
méthode find() de la classe str.
Pour obtenir de l'aide sur cette méthode :
>>> help(str.find)
2) Ecrire le script du décodage.
Par exemple :
>>>
Message à décoder ? prqwb sbwkrq'v ioblqj flufxv
monty python's flying circus
Exercice 3.7 ★★ Ecrire un script qui donne l'évolution de la suite
convergente : un+1 = un/2 + 1/un
Par exemple :
>>>
Valeur initiale ? 20
Jusqu'à quel rang ? 10
0 20.0
1 10.05
2 5.12450248756
3 2.75739213842
4 1.74135758045
5 1.44494338196
6 1.41454033013
7 1.41421360012
8 1.41421356237
9 1.41421356237
10 1.41421356237
>>>
Exercice 3.8 ★★ Fraction continue infinie
L'instruction def
Syntaxe
def nom_de_la_fonction(parametre1, parametre2,
parametre3, ...):
""" Documentation
qu'on peut écrire
sur plusieurs lignes """ # docstring entouré de 3
guillemets (ou apostrophes)
mapremierefonction()
Cette fonction affiche 'Bonjour'
Exemple n°2
La fonction suivante simule le comportement d'un dé à 6 faces.
Pour cela, on utilise la fonction randint() du module random.
# script Fonction2.py
def tirage_de():
""" Retourne un nombre entier aléatoire entre 1
et 6 """
import random
valeur = random.randint(1, 6)
return valeur
>>> print(tirage_de())
3
>>> print(tirage_de())
6
>>> resultat = tirage_de()
>>> print(resultat)
1
Exemple n°3
# script Fonction3.py
def tirage_de():
""" Retourne un nombre entier aléatoire entre 1
et 6 """
import random
valeur = random.randint(1, 6)
return valeur
# début du programme
info()
while True:
choix = input()
if choix == 'q':
break
print("Tirage :", tirage_de())
>>>
Touche q pour quitter
Touche Enter pour continuer
Tirage : 5
Tirage : 6
q
>>>
Exemple n°4
Une fonction avec deux paramètres :
# script Fonction4.py
# définition de fonction
def tirage_de2(valeur_min, valeur_max):
""" Retourne un nombre entier aléatoire entre
valeur_min et valeur_max """
import random
return random.randint(valeur_min, valeur_max)
# début du programme
for i in range(5):
print(tirage_de2(1, 10)) # appel de la
fonction avec les arguments 1 et 10
>>>
6
7
1
10
2
>>>
Exemple n°5
Une fonction qui retourne une liste :
# script Fonction5.py
# définition de fonction
def tirage_multiple_de(nombretirage):
""" Retourne une liste de nombres entiers
aléatoires entre 1 et 6 """
import random
resultat = [random.randint(1, 6) for i in
range(nombretirage)] # compréhension de listes (Cf.
annexe)
return resultat
# début du programme
print(tirage_multiple_de(10))
>>>
[4, 1, 3, 3, 2, 1, 6, 6, 2, 5]
>>> help(tirage_multiple_de)
Help on function tirage_multiple_de in module
__main__:
tirage_multiple_de(nombretirage)
Retourne une liste de nombres entiers
aléatoires entre 1 et 6
Exemple n°6
Une fonction qui affiche la parité d'un nombre entier.
Il peut y avoir plusieurs instructions return dans une fonction.
L'instruction return provoque le retour immédiat de la fonction.
# script Fonction6.py
# définition de fonction
def parite(nombre):
""" Affiche la parité d'un nombre entier """
if nombre%2 == 1: # L'opérateur % donne le
reste d'une division
print(nombre, 'est impair')
return
if nombre%2 == 0:
print(nombre, 'est pair')
return
>>> parite(13)
13 est impair
>>> parite(24)
24 est pair
def mafonction():
a = 20 # variable locale à la fonction
print(a)
return
>>> print(a) # nous sommmes dans l'espace
global du programme
10
>>> mafonction() # nous sommes dans l'espace
local de la fonction
20
>>> print(a) # de retour dans l'espace
global
10
Nous avons deux variables différentes qui portent le même nom a
def mafonction():
global a # la variable est maintenant globale
a = 20
print(a)
return
>>> print(a)
10
>>> mafonction()
20
>>> print(a)
20
Remarque : il est préférable d'éviter l'utilisation de
l'instruction global car c'est une source d'erreurs (on peut ainsi modifier
le contenu d'une variable globale en croyant agir sur une variable locale).
La sagesse recommande donc de suivre la règle suivante :
ne jamais affecter dans un bloc de code local une variable de même
nom qu'une variable globale
Exercices
Exercice 4.1 ☆
1) Ecrire une fonction carre() qui retourne le carré d'un nombre :
>>> print(carre(11.11111))
123.4567654321
2) Avec une boucle while et la fonction carre(), écrire un script qui
affiche le carré des nombres entiers de 1 à 100 :
>>>
1² = 1
2² = 4
3² = 9
...
99² = 9801
100² = 10000
Fin du programme
Exercice 4.2 ☆
1) Ecrire une fonction qui retourne l'aire de la surface d'un disque de
rayon R.
Exemple :
>>> print(airedisque(2.5))
19.6349540849
2) Ajouter un paramètre qui précise l'unité de mesure :
>>> print(airedisque2(4.2, 'cm'))
55.4176944093 cm²
Exercice 4.3 ★
1) Ecrire une fonction qui retourne la factorielle d'un nombre entier N.
On rappelle que : N ! = 1×2×...×(N-1)×N
Exemple :
>>> print(factorielle(50))
304140932017133780436126081660647688443776415689605
12000000000000
2) Comparez avec le résultat de la fonction factorial() du
module math.
Exercice 4.4 ★
1) A l'aide de la fonction randint() du module random, écrire une
fonction qui retourne un mot de passe de longueur N (chiffres, lettres
minuscules ou majuscules).
On donne :
chaine =
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn
opqrstuvwxyz'
>>> print(password(10))
mHVeC5rs8P
>>> print(password(6))
PYthoN
2) Reprendre la question 1) avec la fonction choice() du
module random.
Pour obtenir de l'aide sur cette fonction :
>>> import random
>>> help(random.choice)
3) Quel est le nombre de combinaisons possibles ?
4) Quelle durée faut-il pour casser le mot de passe avec un logiciel
capable de générer 1 million de combinaisons par seconde ?
Lien utile : www.exhaustif.com/Generateur-de-mot-de-passe-en.html
Exercice 4.5 ★ Ecrire une fonction qui retourne une carte (au hasard)
d'un jeu de Poker à 52 cartes.
On utilisera la fonction choice() ou randint() du module random.
On donne :
ListeCarte =
['2s','2h','2d','2c','3s','3h','3d','3c','4s','4h',
'4d','4c','5s','5h','5d','5c',
'6s','6h','6d','6c','7s','7h','7d','7c','8s','8h','
8d','8c','9s','9h','9d','9c',
'Ts','Th','Td','Tc','Js','Jh','Jd','Jc','Qs','Qh','
Qd','Qc','Ks','Kh','Kd','Kc','As','Ah','Ad','Ac']
>>> print(tiragecarte())
7s
>>> print(tiragecarte())
Kd
Exercice 4.6 ★★
1) Ecrire une fonction qui retourne une liste de N cartes différentes d'un
jeu de Poker à 52 cartes.
Noter qu'une fonction peut appeler une fonction : on peut donc réutiliser
la fonction tiragecarte() de l'exercice précédent.
Exemple :
>>> print(tirage_n_carte(2))
['As', 'Ah']
>>> print(tirage_n_carte(25))
['Jc', 'Jh', 'Tc', '2d', '3h', 'Qc', '8d', '7c',
'As', 'Td', '8h', '9c', 'Ad', 'Qh',
'Kc', '6s', '5h', 'Qd', 'Kh', '9h', '5d', 'Js',
'Ks', '5c', 'Th']
2) Simplifier le script avec la fonction shuffle() ou sample() du
module random.
Exercice 4.7 ★ Ecrire une fonction qui retourne une grille de numéros du
jeu Euro Millions.
On utilisera la fonction sample() du module random.
>>> print(euromillions())
[37, 23, 9, 11, 49, 2, 11]
>>> print(euromillions())
[16, 32, 8, 30, 40, 6, 4]
Exercice 4.8 ★★
1) Ecrire une fonction qui retourne la valeur de la fonction
mathématique f(x)= 27x3 -27x2 -18x +8 :
>>> print(f(0), f(1), f(0.5), f(0.25), f(0.375))
8.0 -10.0 -4.375 2.234375 -1.123046875
2) On se propose de chercher les zéros de cette fonction par la méthode
de dichotomie.
Ecrire le script correspondant.
>>>
Recherche d'un zéro dans l'intervalle [a,b]
a? 0
b? 1
Précision ? 1e-12
0.5
0.25
0.375
0.3125
0.34375
0.328125
0.3359375
0.33203125
0.333984375
0.3330078125
0.33349609375
0.333251953125
...
...
0.333333333333
>>>
3) Chercher tous les zéros de cette fonction.
Annexe : représentation graphique de la fonction f(x)= 27x3 -27x2 -
18x +8 (graphique réalisé avec la librairie matplotlib de Python)
Exercices
Exercice 5.1
1) Compléter le script précédent de manière à ressaisir le nombre en cas
d'erreur.
Par exemple :
>>>
Entrer un nombre : salut !
salut ! n'est pas un nombre !
Entrer un nombre : 2,3
2,3 n'est pas un nombre !
Entrer un nombre : 2.3
L'inverse de 2.3 est : 0.434782608696
>>>
2) Compléter le script de manière à accepter la virgule comme séparateur
décimal.
Par exemple :
>>>
Entrer un nombre : 2,3
L'inverse de 2.3 est : 0.434782608696
>>>
On pourra utiliser la méthode replace() de la classe str
Ouvrir IDLE :
Démarrer → Programmes → Python → IDLE (Python GUI)
File → New Window
Copier puis coller le code source ci-dessous :
# -*- coding: utf-8 -*-
# CompteBancaire.py
class Compte:
"""Un exemple de classe :
gestion d'un compte bancaire"""
if __name__ == '__main__':
# Ce bloc d'instructions est exécuté si le
module est lancé en tant que programme autonome
# Instanciation de l'objet cb1 de la classe
Compte
cb1 = Compte(1000)
# formatage des données pour afficher deux
chiffres après la virgule et le signe
print("{:+.2f}".format(cb1.Solde()))
print("{:+.2f}".format(cb1.Credit(200)))
print("{:+.2f}".format(cb1.Debit(50.23)))
print("{:+.2f}".format(cb1.Solde()))
cb1.NouveauSolde(5100)
print("{:+.2f}".format(cb1.Solde()))
cb1+253.2
cb1-1000+100
cb1-cb1.Solde()
File → Save As
Répertoire : C:\PythonXX
Nom du fichier : CompteBancaire.py
Puis exécuter le module :
Run → Run Module (ou touche F5) :
>>>
+1000.00
+1200.00
+1149.77
+1149.77
+5100.00
Nouveau solde : +5353.20 €
Nouveau solde : +4353.20 €
Nouveau solde : +4453.20 €
Nouveau solde : +0.00 €
>>>
L'instruction class
La méthode spéciale __init__()
Documentation
La fonction help() est très utile.
On comprend ici l'intérêt de bien documenter ses programmes avec
les """docstrings""" :
>>> help(cb1)
Help on instance of Compte in module __main__:
class Compte
| Un exemple de classe :
| gestion d'un compte bancaire
|
| Methods defined here:
|
| Credit(self, somme)
| Crédite le compte de la valeur somme.
Retourne le solde.
|
| Debit(self, somme)
| Débite le compte de la valeur somme.
Retourne le solde.
|
| NouveauSolde(self, somme)
| Nouveau solde de compte avec la valeur
somme.
|
| Solde(self)
| Retourne le solde.
|
| __add__(self, somme)
| x.__add__(somme) <=> x+somme
| Crédite le compte de la valeur somme.
| Affiche 'Nouveau solde : somme'
|
| __init__(self, soldeInitial)
| Initialisation du compte avec la valeur
soldeInitial.
|
| __sub__(self, somme)
| x.__sub_(somme) <=> x-somme
| Débite le compte de la valeur somme.
| Affiche 'Nouveau solde : somme'
>>>
La fonction dir() retourne la liste des méthodes et attributs :
>>> dir(cb1)
['Credit', 'Debit', 'NouveauSolde', 'Solde',
'__add__',
'__doc__', '__init__', '__module__', '__sub__',
'solde']
Remarques
On peut instancier plusieurs objets d'une même classe :
>>> cb2 = Compte(10000)
>>> print(cb2.Credit(500))
10500.0
>>> cb3 = Compte(6000) # et encore un !
>>> cb3-500
Nouveau solde : +5500.00 €
>>>
Même si cela n'est pas recommandable, vous pouvez accéder directement
aux attributs d'instance :
>>> print(cb2.solde)
10500.0
>>> cb2.solde = 5000.0 # assignation de
l'attribut d'instance solde
>>> print(cb2.solde)
5000.0
>>> print(cb2.Solde())
5000.0
>>>
Notez que des mécanismes sont prévus pour personnaliser le mode
d'accès aux attributs : fonction property() ou décorateur @property
Autre exemple
Le module standard math est un module de fonctions.
Pour s'en convaincre :
>>> import math
>>> help(math)
Help on built-in module math:
NAME
math
FILE
(built-in)
DESCRIPTION
This module is always available. It provides
access to the
mathematical functions defined by the C
standard.
FUNCTIONS
acos(...)
acos(x)
acosh(...)
acosh(x)
trunc(...)
trunc(x:Real) -> Integral
DATA
e = 2.718281828459045
pi = 3.141592653589793
Le module math a également deux données (pi et e) :
>>> print(math.e) # donnée e du module math
(nombre d'Euler)
2.71828182846
>>> print(math.pi) # donnée pi du module
math (nombre pi)
3.14159265359
>>> print(math.sin(math.pi/4.0)) # fonction sin()
du module math (sinus)
0.707106781187
>>> print(math.sqrt(2.0)) # fonction sqrt() du
module math (racine carrée)
1.41421356237
>>> print(math.exp(-3.0)) # fonction exp() du
module math (exponentielle)
0.0497870683679
>>> print(math.log(math.e)) # fonction log() du
module math (logarithme népérien)
1.0
Héritage de classes
Si vous êtes familiarisé avec le module Tkinter, voici un exemple qui
montre toute la puissance des classes et de la notion d'héritage :
class EnterMessage(Frame):
""" Classe EnterMessage (Frame de saisie du mes
sage)
Cette classe dérive de la classe
Tkinter.Frame"""
def __init__(self, master=None):
"""Initialisation : création d'un widget Fr
ame"""
Frame.__init__(self, master, bg='navy')
self.pack(padx=10, pady=10)
self.CreateWidgets()
def CreateWidgets(self):
""" Création des widgets Entry et Button
dans le widget Frame """
self.NouveauMessage = StringVar()
Entry(master=self, textvariable=self.Nouvea
uMessage).pack(side=LEFT, padx=10, pady=10)
Button(master=self, text="Nouveau", fg="nav
y", command=self.Nouveau).pack(padx=10, pady=10)
def Nouveau(self):
""" Création d'une instance de la classe Ne
wPostIt """
if self.NouveauMessage.get() != "":
NewPostIt(master=self.master, message=s
elf.NouveauMessage.get())
self.NouveauMessage.set("")
class NewPostIt(Frame):
""" Classe post-it (Frame Post-It)
Cette classe dérive de la classe Tkinter.Frame"
""
def __init__(self, master=None, message=None):
"""Initialisation : création d'un widget Fr
ame"""
Frame.__init__(self, master, bg="maroon")
self.pack(side=LEFT, padx=10, pady=10)
self.CreateWidgets(message)
def CreateWidgets(self, message):
""" Création des widgets Label et Button da
ns le widget Frame"""
Label(master=self, text=message, fg='maroon
', bg='white').pack(padx=10, pady=10)
Button(master=self, text="Effacer", fg="nav
y", command=self.destroy).pack(padx=10, pady=10)
if __name__ == '__main__':
# création de la fenêtre principale
Mafenetre = Tk()
Mafenetre.title('Post-it')
Mafenetre['bg'] = 'bisque'
# Création d'une instance de la classe EnterMes
sage
EnterMessage(master=Mafenetre)
Mafenetre.mainloop()
Exercices
Exercice 6.0 ★ On s'intéresse au module CompteBancaire.
Dans les méthodes __add__() et __sub__(), remplacer la
ligne return self par simplement return
Tester ce nouveau code et expliquer la différence.
# script de.py
#(C) Fabrice Sincère
def NouveauLance():
nb = random.randint(1,6)
Texte.set('Résultat -> ' + str(nb))
Mafenetre.title('Dé à 6 faces')
Mafenetre.geometry('300x100+400+400')
Texte = StringVar()
NouveauLance()
Mafenetre.mainloop()
Ce code est détaillé ici.
from tkinter import *
# Création de la fenêtre principale
Mafenetre = Tk()
Mafenetre.title('Frame widget')
Mafenetre['bg']='bisque' # couleur de fond
# création d'un widget Frame dans la fenêtre princi
pale
Frame1 = Frame(Mafenetre,borderwidth=2,relief=GROOV
E)
Frame1.pack(side=LEFT,padx=10,pady=10)
# création d'un second widget Frame dans la fenêtre
principale
Frame2 = Frame(Mafenetre,borderwidth=2,relief=GROOV
E)
Frame2.pack(side=LEFT,padx=10,pady=10)
# création d'un widget Frame... dans un widget Fram
e
# le widget Frame1 est le parent du widget Frame3
# le parent du widget Frame1 est le widget Mafenetr
e (fenêtre principale)
Frame3 = Frame(Frame1,bg="white",borderwidth=2,reli
ef=GROOVE)
Frame3.pack(side=LEFT,padx=10,pady=10)
# création d'un widget Label et d'un widget Button
dans un widget Frame
Label(Frame1,text="RDV dentiste samedi à 15h").pack
(padx=10,pady=10)
Button(Frame1,text="Effacer",fg='navy',command=Fram
e1.destroy).pack(padx=10,pady=10)
Label(Frame2,text="Réviser le contrôle d'info").pac
k(padx=10,pady=10)
Button(Frame2,text="Effacer",fg='navy',command=Fram
e2.destroy).pack(padx=10,pady=10)
Label(Frame3,text="RDV dentiste à 10h",bg="white").
pack(padx=10,pady=10)
Button(Frame3,text="Effacer",fg='navy',command=Fram
e3.destroy).pack(padx=10,pady=10)
Mafenetre.mainloop()
# script mot_de_passe.py
#(C) Fabrice Sincère
from tkinter import *
from tkinter.messagebox import * # boîte de
dialogue
def Verification():
if Motdepasse.get() == 'python27':
# le mot de passe est bon : on affiche une
boîte de dialogue puis on ferme la fenêtre
showinfo('Résultat','Mot de passe
correct.\nAu revoir !')
Mafenetre.destroy()
else:
# le mot de passe est incorrect : on
affiche une boîte de dialogue
showwarning('Résultat','Mot de passe
incorrect.\nVeuillez recommencer !')
Motdepasse.set('')
Mafenetre.mainloop()
def carre():
""" Calcul du carré """
Resultat.set("Carré = "+str(float(Valeur.get())
**2))
# Création de la fenêtre principale (main window)
Mafenetre = Tk()
Mafenetre.title("Spinbox widget")
Valeur = StringVar()
Valeur.set(2.0)
# Création d'un widget Spinbox
boite = Spinbox(Mafenetre,from_=0,to=10,increment=0
.5,textvariable=Valeur,width=5,command=carre)
boite.pack(padx=30,pady=10)
# Création d'un widget Label
Resultat = StringVar()
carre()
Label(Mafenetre,textvariable=Resultat).pack(padx=30
,pady=10)
Mafenetre.mainloop()
def maj(nouvelleValeur):
# nouvelle valeur en argument
print(nouvelleValeur)
def plus():
Valeur.set(str(int(Valeur.get())+10))
print(Valeur.get())
def moins():
Valeur.set(str(int(Valeur.get())-10))
print(Valeur.get())
# Création de la fenêtre principale (main window)
Mafenetre = Tk()
Mafenetre.title("Scale widget")
Valeur = StringVar()
Valeur.set(50)
# Création d'un widget Scale
echelle = Scale(Mafenetre,from_=-
100,to=100,resolution=10,orient=HORIZONTAL,\
length=300,width=20,label="Offset",tickinterval=20,
variable=Valeur,command=maj)
echelle.pack(padx=10,pady=10)
# Création d'un widget Button (bouton +)
Button(Mafenetre,text="+",command=plus).pack(padx=1
0,pady=10)
# Création d'un widget Button (bouton -)
Button(Mafenetre,text="-",command=moins).pack(padx=
10,pady=10)
Mafenetre.mainloop()
# script cercle.py
#(C) Fabrice Sincère
from tkinter import *
import random
def Cercle():
""" Dessine un cercle de centre (x,y) et de
rayon r """
x = random.randint(0,Largeur)
y = random.randint(0,Hauteur)
r = 20
Canevas.create_oval(x-r, y-r, x+r, y+r,
outline='blue', fill='blue')
def Effacer():
""" Efface la zone graphique """
Canevas.delete(ALL)
Mafenetre.mainloop()
Ce code est détaillé ici.
def Cercle():
""" Dessine un cercle de centre (x,y) et de ray
on r """
x = random.randint(0,Largeur)
y = random.randint(0,Hauteur)
r = 10
# on dessine un cercle dans la zone graphique
item = Canevas.create_oval(x-r, y-r, x+r, y+r,
outline='black', fill='black')
print("Création du cercle (item" , item ,")")
# affichage de tous les items de Canevas
print(Canevas.find_all())
def Undo():
""" Efface le dernier cercle"""
if len(Canevas.find_all()) > 1:
item = Canevas.find_all()[-1]
# on efface le cercle
Canevas.delete(item)
print("Suppression du cercle
(item" , item ,")")
# affichage de tous les items de Canevas
print(Canevas.find_all())
def EffacerTout():
""" Efface tous les cercles"""
while len(Canevas.find_all()) > 1:
Undo()
# Création de la fenêtre principale (main window)
Mafenetre = Tk()
Mafenetre.title('Cible')
# Image de fond
photo = PhotoImage(file="tk_cible.gif")
# Création d'un widget Canvas (zone graphique)
Largeur = 550
Hauteur = 550
Canevas = Canvas(Mafenetre,width = Largeur, height
=Hauteur)
item = Canevas.create_image(0,0,anchor=NW, image=ph
oto)
print("Image de fond (item",item,")")
Canevas.pack()
# Création d'un widget Button
BoutonGo = Button(Mafenetre, text ='Tirer', command
= Cercle)
BoutonGo.pack(side = LEFT, padx = 10, pady = 10)
# Création d'un widget Button
BoutonEffacer = Button(Mafenetre, text ='Effacer le
dernier tir', command = Undo)
BoutonEffacer.pack(side = LEFT, padx = 10, pady = 1
0)
# Création d'un widget Button
BoutonEffacerTout = Button(Mafenetre, text ='Efface
r tout', command = EffacerTout)
BoutonEffacerTout.pack(side = LEFT, padx = 10, pady
= 10)
# Création d'un widget Button (bouton Quitter)
BoutonQuitter = Button(Mafenetre, text ='Quitter',
command = Mafenetre.destroy)
BoutonQuitter.pack(side = LEFT, padx = 10, pady = 1
0)
Mafenetre.mainloop()
Télécharger l'image de fond tk_cible.gif
def Ouvrir():
Canevas.delete(ALL) # on efface la zone graphiq
ue
filename = tkinter.filedialog.askopenfilename(t
itle="Ouvrir une image",filetypes=[('gif files','.g
if'),('all files','.*')])
print(filename)
photo = PhotoImage(file=filename)
gifdict[filename] = photo # référence
print(gifdict)
Canevas.create_image(0,0,anchor=NW,image=photo)
Canevas.config(height=photo.height(),width=phot
o.width())
Mafenetre.title("Image "+str(photo.width())+" x
"+str(photo.height()))
def Fermer():
Canevas.delete(ALL)
Mafenetre.title("Image")
def Apropos():
tkinter.messagebox.showinfo("A propos","Tutoria
l Python Tkinter\n(C) Fabrice Sincère")
# Main window
Mafenetre = Tk()
Mafenetre.title("Image")
# Création d'un widget Menu
menubar = Menu(Mafenetre)
menufichier = Menu(menubar,tearoff=0)
menufichier.add_command(label="Ouvrir une image",co
mmand=Ouvrir)
menufichier.add_command(label="Fermer l'image",comm
and=Fermer)
menufichier.add_command(label="Quitter",command=Maf
enetre.destroy)
menubar.add_cascade(label="Fichier", menu=menufichi
er)
menuaide = Menu(menubar,tearoff=0)
menuaide.add_command(label="A propos",command=Aprop
os)
menubar.add_cascade(label="Aide", menu=menuaide)
# Affichage du menu
Mafenetre.config(menu=menubar)
# Création d'un widget Canvas
Canevas = Canvas(Mafenetre)
Canevas.pack(padx=5,pady=5)
# Utilisation d'un dictionnaire pour conserver une
référence
gifdict={}
Mafenetre.mainloop()
Remarques
# dans le programme principal
gifdict = {}
# dans la fonction Ouvrir()
gifdict[filename] = photo
Si vous enlevez les lignes ci-dessus, l'ouverture des images ne fonctionne
plus correctement.
En effet, photo est une variable locale à la fonction Ouvrir(). En
dehors, elle n'existe plus et la référence à l'image est perdue.
Une manière de conserver la référence est d'utiliser un dictionnaire ou une
liste qui ont "naturellement" une portée globale :
# dans le programme principal
giflist = []
# dans la fonction Ouvrir()
giflist.append(photo)
On peut aussi rendre globale la variable photo avec ce code au début de
la fonction Ouvrir() :
global photo
Pour finir, la façon la plus élégante de résoudre ce genre de situation est
de pratiquer la programmation orientée objet (encapsulation dans une
classe) : voir le programme
import time
def maj():
# on arrive ici toutes les 1000 ms
heure.set(time.strftime('%H:%M:%S'))
Mafenetre.after(1000,maj)
Mafenetre = Tk()
Mafenetre.title("Heure courante")
# Création d'un widget Label
heure = StringVar()
Label(Mafenetre,textvariable=heure).pack(padx=10,pa
dy=10)
maj()
Mafenetre.mainloop()
def Cercle():
""" Dessine un cercle de centre (x,y) et de
rayon r """
global Arret
x = random.randint(0,Largeur)
y = random.randint(0,Hauteur)
r = 10
Canevas.create_oval(x-r, y-r, x+r, y+r,
outline='red', fill='red')
if Arret == False:
# appel de la fonction Cercle() après une
pause de 50 millisecondes
Mafenetre.after(50,Cercle)
def Arreter():
""" Arrêt de l'animation """
global Arret
Arret = True
def Demarrer():
""" Démarre l'animation """
global Arret
Canevas.delete(ALL)
if Arret == True:
Arret = False
Cercle() # un seul appel à cette fonction
Arret = True
# Création de la fenêtre principale (main window)
Mafenetre = Tk()
Mafenetre.title('Animation')
Mafenetre.mainloop()
from tkinter import *
import math,random
LARGEUR = 480
HAUTEUR = 320
RAYON = 15 # rayon de la balle
def deplacement():
""" Déplacement de la balle """
global X,Y,DX,DY,RAYON,LARGEUR,HAUTEUR
# rebond à droite
if X+RAYON+DX > LARGEUR:
X = 2*(LARGEUR-RAYON)-X
DX = -DX
# rebond à gauche
if X-RAYON+DX < 0:
X = 2*RAYON-X
DX = -DX
# rebond en bas
if Y+RAYON+DY > HAUTEUR:
Y = 2*(HAUTEUR-RAYON)-Y
DY = -DY
# rebond en haut
if Y-RAYON+DY < 0:
Y = 2*RAYON-Y
DY = -DY
X = X+DX
Y = Y+DY
# affichage
Canevas.coords(Balle,X-RAYON,Y-
RAYON,X+RAYON,Y+RAYON)
deplacement()
Mafenetre.mainloop()
def Clic(event):
""" Gestion de l'événement Clic gauche sur la
zone graphique """
# position du pointeur de la souris
X = event.x
Y = event.y
# on dessine un carré
r = 20
Canevas.create_rectangle(X-r, Y-r, X+r, Y+r,
outline='black',fill='green')
def Effacer():
""" Efface la zone graphique """
Canevas.delete(ALL)
Mafenetre.mainloop()
Ce code est détaillé ici.
def Clic(event):
""" Gestion de l'événement Clic gauche """
global DETECTION_CLIC_SUR_OBJET
# position du pointeur de la souris
X = event.x
Y = event.y
print("Position du clic -> ",X,Y)
# coordonnées de l'objet
[xmin,ymin,xmax,ymax] = Canevas.coords(Carre)
def Drag(event):
""" Gestion de l'événement bouton gauche enfonc
é """
X = event.x
Y = event.y
print("Position du pointeur -> ",X,Y)
if DETECTION_CLIC_SUR_OBJET == True:
# limite de l'objet dans la zone graphique
if X<0: X=0
if X>Largeur: X=Largeur
if Y<0: Y=0
if Y>Hauteur: Y=Hauteur
# mise à jour de la position de l'objet (dr
ag)
Canevas.coords(Carre,X-TailleCarre,Y-
TailleCarre,X+TailleCarre,Y+TailleCarre)
DETECTION_CLIC_SUR_OBJET = False
# Création de la fenêtre principale
Mafenetre = Tk()
Mafenetre.title("Drag and drop")
# Création d'un widget Canvas
Largeur = 480
Hauteur = 160
TailleCarre = 20
Canevas = Canvas(Mafenetre,width=Largeur,height=Hau
teur,bg ='white')
# Création d'un objet graphique
Carre = Canevas.create_rectangle(0,0,TailleCarre*2,
TailleCarre*2,fill='maroon')
# La méthode bind() permet de lier un événement ave
c une fonction
Canevas.bind('<Button-1>',Clic) # évévement clic ga
uche (press)
Canevas.bind('<B1-Motion>',Drag) # événement bouton
gauche enfoncé (hold down)
Canevas.focus_set()
Canevas.pack(padx=10,pady=10)
Mafenetre.mainloop()
def Clavier(event):
""" Gestion de l'événement Appui sur une touche
du clavier """
global PosX,PosY
touche = event.keysym
print(touche)
# déplacement vers le haut
if touche == 'a':
PosY -= 20
# déplacement vers le bas
if touche == 'q':
PosY += 20
# déplacement vers la droite
if touche == 'm':
PosX += 20
# déplacement vers la gauche
if touche == 'l':
PosX -= 20
# on dessine le pion à sa nouvelle position
Canevas.coords(Pion,PosX -10, PosY -10, PosX
+10, PosY +10)
pygame.mixer.init()
pygame.mixer.music.load("chavmusic7.mp3")
# réglage volume
pygame.mixer.music.set_volume(0.3)
son1 = pygame.mixer.Sound("balla1.ogg")
son1.set_volume(0.5)
son2 = pygame.mixer.Sound("death1.wav")
son2.set_volume(1.0)
def PlaySon1():
son1.play()
def PlaySon2():
son2.play()
def Music():
print(musique.get())
if musique.get() == 1:
# 1 (ON)
# joue en boucle
pygame.mixer.music.play(-1)
else:
# 0 (OFF)
pygame.mixer.music.stop()
# Création de la fenêtre principale (main window)
Mafenetre = Tk()
Mafenetre.title("Checkbutton widget + Pygame.mixer"
)
# Création d'un widget Button
Button(Mafenetre,text="son 1",command=PlaySon1).pac
k(side=LEFT,padx=10,pady=10)
# Création d'un widget Button
Button(Mafenetre,text="son 2",command=PlaySon2).pac
k(side=LEFT,padx=10,pady=10)
# Création d'un widget Checkbutton
musique = IntVar()
musique.set(1) # ON
Checkbutton(Mafenetre,text="Musique de fond",variab
le=musique,command=Music).pack(side=LEFT,padx=10,pa
dy=10)
Music()
Mafenetre.mainloop()
Télécharger le son death1.wav
Télécharger le son balla1.ogg
Télécharger la musique chavmusic7.mp3
Exercices
Exercice 7.1 ★ En s'inspirant des
scripts de.py et mot_de_passe.py, écrire une application avec
interface graphique qui calcule la racine carrée d'un nombre.
Par exemple, le calcul de √3 donne :
Exercice 7.2 ★ Reprendre le script mot_de_passe.py de manière à
limiter le nombre d'essais à trois.
Exercice 7.7 ★★
Ecrire un script qui tire une carte et l'affiche à une position aléatoire.
Liens utiles :
cormas.cirad.fr
deptinfo-ensip.univ-poitiers.fr
NomFichier = 'test.txt'
# création et ouverture du fichier test.txt en mode
write 'w' (écriture)
# si le fichier test.txt existe déjà, il est écrasé
Fichier = open(NomFichier, 'w') #
instanciation de l'objet Fichier de la classe file
Pickling
Un exemple de sauvegarde d'un dictionnaire :
import pickle
# récupération du dictionnaire
Fichier = open('data.txt', 'rb')
Dept = pickle.load(Fichier) # désérialisation
Fichier.close()
print(Dept)
print(Dept[36])
>>>
{75: 'Paris', 36: 'Indre', 30: 'Gard'}
Indre
Exercices
Exercice 8.1 : fichiers binaires et fichiers textes
Les fichiers suivants sont-ils de type binaire ou de type texte ?
Une photo au format JPEG
Une image au format PNG
Une image au format SVG
Un fichier audio au format MP3
Un document texte au format TXT
Une page web au format HTML
Un fichier exécutable (extension .exe)
Un document au format PDF
Un fichier compressé au format ZIP
Un script en langage Python (extension .py)
Exercice 8.2
1) Créer un fichier texte contenant une suite aléatoire de chiffres.
On utilisera la fonction randint() du module random.
Exemple
2) Avec un logiciel tel que 7-Zip, compresser le fichier avec différents
algorithmes (zip, gzip, bzip2).
Le taux de compression (en %) est donné par la formule : 100×(taille
initiale - taille après compression)/taille initiale
Comment expliquer ce taux de compression modeste (au mieux 57 %)?
Projet
Election des délégués de classe par un vote électronique
Ecrire un ensemble de scripts qui gère une élection par vote électronique.
On utilisera des fichiers pour stocker la liste électorale, les mots de passe,
la liste des candidats et le résultat des votes.
Pour une sécurité optimale, le vote se fera sur un ordinateur seul (sans
connexion réseau, sans connexion à Internet...).
Exemple d'interface :
>>>
Election des délégués de classe
Actuellement, 18 élèves ont voté (sur 30)
Identifiant ? martin
Mot de passe ?
L'authentification a réussi.
A voté !
Merci et bonne journée.
>>>
Résultat de l'élection des délégués de classe
Nombre de votants : 30 / 30
# script inversion_image_pgm.py
import imghdr, struct
print("Inversion d'une image PGM en mode binaire à
256 niveaux de gris\n")
NomFichierSource = 'image.pgm'
NomFichierDestination = 'imageInverse.pgm'
def Inversion(octet):
# cette fonction fait une inversion du niveau
de gris
# 0 (noir) -> 255 (blanc)
# 255 (blanc) -> 0 (noir)
return 255-octet
if imghdr.what(NomFichierSource)=='pgm': # test du
format de l'image
FichierSource = open(NomFichierSource,'rb')
TailleFichier = len(FichierSource.read())
print('\nTaille du fichier (en
octets) :',TailleFichier)
# extraction de l'en-tête
# la variable Entete est une chaîne d'octets
(type bytes)
Entete = FichierSource.read(TailleEntete)
FichierSource.close()
if NbPixel == len(Data):
print('Nombre de pixels :',Largeur*Hauteur)
print("Nombre d'octets de
données :",len(Data))
print("Taille de l'en-tête :",TailleEntete)
FichierDestination =
open(NomFichierDestination,'wb')
# écriture de l'en-tête du fichier
destination
FichierDestination.write(Entete)
FichierDestination.write(struct.pack('B',Inversion(
i)))
FichierDestination.close()
print('Travail terminé !')
else:
print('Erreur dans la saisie des
données !')
else:
print("Ce n'est pas une image PGM !")
>>>
Inversion d'une image PGM en mode binaire à 256
niveaux de gris
# Pillow 6.0.0
# importation du module Image de la librairie
Pillow
from PIL import Image
# ouverture de l'image
img = Image.open('photo.jpg')
# affichage de l'image
img.show()
# affichage de la taille de l'image (en pixels)
print(img.size)
# conversion au format PPM (en couleur) et
enregistrement de l'image
img.save('photo.ppm','PPM')
img.show()
# conversion en niveau de gris (pour obtenir le
format PGM)
img0 = img.convert('L')
# enregistrement dans le fichier image.pgm
img0.save('image.pgm')
img0.show()
# retournement de l'image
img1 = img0.rotate(180)
# affichage et enregistrement de l'image retournée
img1.show()
img1.save('image_retourne.pgm')
# miroir horizontal
img2 = img0.transpose(Image.FLIP_LEFT_RIGHT)
img2.show()
img2.save('image_miroir_horizontal.pgm')
# miroir vertical
img3 = img0.transpose(Image.FLIP_TOP_BOTTOM)
img3.show()
img3.save('image_miroir_vertical.pgm')
>>>
(480, 320)
Dessiner avec la librairie Pillow
Le module ImageDraw de la librairie Pillow permet de créer des formes
géométriques simples dans une image : ligne, cercle, rectangle, texte...
Voici un script qui fabrique l'image d'un camembert 2D (au format PNG) :
# script camembert.py
# Python 2.7 & Python 3
# Pillow 6.0.0
from PIL import Image,ImageDraw
# création d'une image 400x400 (fond blanc)
img = Image.new("RGB",(400,400),"#FFFFFF")
# création d'un objet Draw
dessin = ImageDraw.Draw(img)
# dessine un arc partiel et le remplit
dessin.pieslice((50,50,350,350),0,60,fill="blue")
dessin.pieslice((50,50,350,350),60,150,fill="gray")
dessin.pieslice((50,50,350,350),150,360,fill="red")
# dessine du texte
dessin.text((50,20),"camembert 2D",fill="red")
img.save("camembert.png","PNG")
img.show()
Exercices
Exercice 10.1 ★
1) Reprendre le script inversion_image_pgm.py de manière à
réduire l'image initiale à deux couleurs (noir et blanc) en utilisant un
seuil :
Exercice 10.2 ★★
Exercice 10.3 ★★
1) Reprendre le script inversion_image_pgm.py afin de faire une
transformation miroir horizontal :
Exercice 10.4 ★★
Nouvelle taille :
Hauteur en pixels ? 800
Largeur en pixels : 600
Chapitre 11 - Débogage
Le débogueur est un outil utile au débutant car il aide à comprendre le
fonctionnement d'un script existant.
Pour un professionnel, il permet le test et la mise au point d'un script en
cours de développement (détection et élimination des bugs).
Il existe plusieurs outils de déboguage sous Python, notamment le module
standard pdb (en ligne de commande).
Nous ne nous intéresserons qu'au débogueur de l'environnement IDLE (en
mode graphique).
Pas-à-pas grossier
Pour faire du pas-à-pas grossier, cliquer sur le bouton Over du débogueur
:
Noter que l'on peut observer le contenu des variables
(actuellement a vaut 4).
Pas-à-pas détaillé
Pour faire du pas-à-pas détaillé, cliquer sur le bouton Step du débogueur.
Pour sortir immédiatement d'une fonction, utiliser le bouton Out (en
particulier pour sortir du script PyShell.py qui gère la
fonction print()).
Exercices
Exercice 11.1 A l'aide du débogueur, étudier la fonction
récursive factorielle()qui retourne la factorielle d'un nombre
entier :
def factorielle(x):
if x < 2:
return 1
else:
result = x*factorielle(x-1)
return result
print(factorielle(5))
N.B. Une fonction récursive est une fonction qui s'appelle elle-même !
Exercice 11.2 A l'aide du débogueur, étudier la suite de Conway dont le
script est disponible ici :
conway3.py
>>>
0 1
1 11
2 21
3 1211
4 111221
5 312211
6 13112221
7 1113213211
8 31131211131221
9 13211311123113112211
10 11131221133112132113212221
...
Utilisation de Py2exe
A titre d'exemple, voici le script d'un jeu de puissance 4 :
jeu_puissance4.py
Remarques
si vous voulez disposer de la console en plus de l'interface graphique
(GUI),
remplacer setup(windows=["jeu_puissance4.py"]) par set
up(console=["jeu_puissance4.py"])
pour traiter plusieurs scripts en même temps, il suffit de compléter
la liste :
setup(windows=["jeu_puissance4.py","script2.py","
script3.py"])
Ouvrir l'interpréteur de commande de Windows (Démarrer → Exécuter →
cmd)
Placez-vous dans le répertoire courant de Python (commande cd : change
directory) :
> cd C:\Python27
puis lancer Py2exe :
> python setup.py py2exe
Le serveur
Avant toute chose, il faut lancer le serveur.
Le port par défaut est 50026 et le nombre de joueurs est 3.
Mais on peut choisir pour le numéro de port une valeur arbitraire comprise
entre 49152 et 65535, ainsi qu'un nombre quelconque de joueurs : il suffit
de modifier ces paramètres dans le script.
Les clients
Ici, on joue à trois en réseau local (chez vous, derrière votre box, par
exemple).
Pour se connecter au serveur, il faut connaître son adresse IP
(192.168.1.10) et le port qu'il utilise (50026).
Python étant multiplateforme, on peut mélanger les systèmes
d'exploitation : Windows, Linux, Mac...
Dans cet exemple :
le serveur et un client tournent sur le même ordinateur sous
Linux/Ubuntu (192.168.1.10)
un deuxième client sur un ordinateur sous Windows (192.168.1.11)
un troisième client sur un troisième ordinateur sous Linux/Ubuntu
(192.168.1.13)
Finalement, c'est Ubuntu qui gagne devant Windows ;)
Remarques
Cette application fonctionne mais est loin d'être parfaite : les pertes de
connexion ne sont pas gérées, etc...
Si vous avez testé cette application, cela m'intéresse d'avoir un retour de
votre part.
Installation
pypi.org/project/dc-electricity
pip install dc-electricity
Documentation
Version française
English version
Exemple 1
On s'intéresse au circuit électrique suivant :
Données :
E = 12 V ; R1 = 1 kΩ ; R2 = 2,7 kΩ et R3 = 1,8 kΩ
Télécharger les scripts exemple1.py et exemple1_bis.py
Ce script calcule les courants I1, I2 et I3, les tensions U1 et U2 et fait un
bilan de puissances.
>>> from dcelectricity.dc_fr import *
>>> E = Tension(12)
>>> E
Tension : 12.000000 V
>>> R1 = Resistance(1, 'k')
>>> R1
Résistance : 1000 Ω (1.000000 kΩ)
>>> R2 = Resistance(2.7, 'k')
>>> R3 = Resistance(1.8, 'k')
>>> R23 = R2//R3 # résistances en parallèle
>>> R23
Résistance : 1080 Ω (1.080000 kΩ)
>>> Req = R1 +R23 # résistances en série
>>> Req
Résistance : 2080 Ω (2.080000 kΩ)
>>> I1 = E/Req # Loi d'Ohm
>>> I1
Intensité du courant : 0.00576923 A (5.769231 mA)
>>> V1 = R1*I1 # Loi d'Ohm
>>> V1
Tension : 5.769231 V
>>> V2 = E -V1 # Loi des branches
>>> V2
Tension : 6.230769 V
>>> I2 = V2/R2 # Loi d'Ohm
>>> I2
Intensité du courant : 0.00230769 A (2.307692 mA)
>>> I3 = I1 -I2 # Loi des nœuds
>>> I3
Intensité du courant : 0.00346154 A (3.461538 mA)
Une autre approche :
>>> loi = Loi()
>>> # diviseur de tension
>>> V2 = loi.DiviseurTension(vtotal=E, r=R2//R3,
r2=R1)
>>> V2
Tension : 6.230769 V
>>> # Théorème de Millman
>>> masse = Tension(0)
>>> V2 = loi.Millman(v_r=[(E, R1), (masse, R2),
(masse, R3)])
>>> V2
Tension : 6.230769 V
>>> (E/R1)/(1/R1 +1/R2 +1/R3)
Tension : 6.230769 V
>>> V2/E
0.5192307692307693
>>> # diviseur de courant
>>> I3 = loi.DiviseurCourant(itotal=I1, r=R3,
r2=R2)
>>> I3
Intensité du courant : 0.00346154 A (3.461538 mA)
>>> I1*R2/(R2 +R3)
Intensité du courant : 0.00346154 A (3.461538 mA)
Puissances et loi de Joule
>>> P = E*I1 # puissance fournie par la source E
>>> P
Puissance : 0.0692308 W (69.230769 mW)
>>> P1 = loi.Joule(r=R1, i=I1)
>>> P1
Puissance : 0.033284 W (33.284024 mW)
>>> R1*I1*I1
Puissance : 0.033284 W (33.284024 mW)
>>> loi.Joule(r=R1, v=V1)
Puissance : 0.033284 W (33.284024 mW)
>>> V1*(V1/R1)
Puissance : 0.033284 W (33.284024 mW)
>>> P2 = loi.Joule(r=R2, i=I2)
>>> P2
Puissance : 0.0143787 W (14.378698 mW)
>>> P3 = loi.Joule(r=R3, i=I3)
Puissance : 0.021568 W (21.568047 mW)
>>> P1 +P2 +P3
Puissance : 0.0692308 W (69.230769 mW)
Exemple 2a
Le même circuit électrique mais avec une résistance R3 ajustable :
Etude de l'évolution de U2 en fonction de R3
R3 = ? 0
Propriétés de R3 :
Résistance : 0.000000 Ω
Propriétés de U2 :
Tension : 0.000000 V
R3 = ? 100
Propriétés de R3 :
Résistance : 100.000000 Ω
Propriétés de U2 :
Tension : 1.055375 V
R3 = ?
Télécharger les
scripts exemple2a_analyse_parametrique.py et exemple2a_analyse_para
metrique_bis.py
Exemple 2b
On utilise ici le module matplotlib pour faire de belles courbes :
Télécharger les
scripts exemple2b_analyse_parametrique.py et exemple2b_analyse_para
metrique_bis.py
Exemple 3
On cherche la valeur de R3 qui donne U2 = 6,00 V.
On utilise une méthode dichotomique :
Itération R3 (Ω) U2 (V)
1 5000.0
7.641509433962264
2 2500.0
6.7782426778242675
3 1250.0
5.5290102389078495
4 1875.0
6.303501945525291
5 1562.5
5.969049373618275
6 1718.75
6.146947223180407
7 1640.625
6.060929983965794
8 1601.5625
6.0157594420795215
9 1582.03125
5.992601726263872
10 1591.796875
6.004229291252643
11 1586.9140625
5.998427762523782
12 1589.35546875
6.001331580654524
13 1588.134765625
5.99988043623693
14 1588.7451171875
6.000606199456697
15 1588.43994140625
6.000243365618415
16 1588.287353515625
6.000061912872932
17 1588.2110595703125
5.99997117754154
Résultat : 1588.2110595703125 Ω
Télécharger les scripts exemple3_solution.py et exemple3_solution_bis.py
Avantages et limitations
Ce module gère les opérations arithmétiques de base (+, -, *, /) ainsi que
// qui désigne deux résistances en parallèle.
La cohérence des unités est contrôlée :
>>> V3 = V1 -V2 +I3
TypeError
>>> I = I1 +0.5
TypeError
>>> I2 = Courant(0.5)
>>> I = I1 + I2
>>> I = 5*I2 -V1/R1 + I3
Le résultat d'une opération doit donner une grandeur dont l'unité est en
volt, ampère, ohm, siemens, watt ou sans unité.
Autrement, vous aurez une erreur :
>>> R1/V1 # Ω/V -> Erreur
TypeError
>>> R2*(R3/(R2 +R3)) # Ω*(Ω/Ω) -> Ω*() -> Ω
>>> R2*R3/(R2 +R3) # Ω*Ω -> Erreur
TypeError
>>> P = V1*(V1/R1) # V*(V/Ω) -> V*A -> W
>>> P = V1*V1/R1 # V*V -> Erreur
TypeError
>>> V1()**2/R1()
Installation
pypi.org/project/dc-electricity
pip install dc-electricity
Documentation
Version française
English version
Exemple 1
On s'intéresse au circuit électrique suivant :
Données :
E = 12 V ; R1 = 1 kΩ ; R2 = 2,7 kΩ et R3 = 1,8 kΩ
Télécharger les scripts exemple1.py et exemple1_bis.py
Ce script calcule les courants I1, I2 et I3, les tensions U1 et U2 et fait un
bilan de puissances.
>>> from dcelectricity.dc_fr import *
>>> E = Tension(12)
>>> E
Tension : 12.000000 V
>>> R1 = Resistance(1, 'k')
>>> R1
Résistance : 1000 Ω (1.000000 kΩ)
>>> R2 = Resistance(2.7, 'k')
>>> R3 = Resistance(1.8, 'k')
>>> R23 = R2//R3 # résistances en parallèle
>>> R23
Résistance : 1080 Ω (1.080000 kΩ)
>>> Req = R1 +R23 # résistances en série
>>> Req
Résistance : 2080 Ω (2.080000 kΩ)
>>> I1 = E/Req # Loi d'Ohm
>>> I1
Intensité du courant : 0.00576923 A (5.769231 mA)
>>> V1 = R1*I1 # Loi d'Ohm
>>> V1
Tension : 5.769231 V
>>> V2 = E -V1 # Loi des branches
>>> V2
Tension : 6.230769 V
>>> I2 = V2/R2 # Loi d'Ohm
>>> I2
Intensité du courant : 0.00230769 A (2.307692 mA)
>>> I3 = I1 -I2 # Loi des nœuds
>>> I3
Intensité du courant : 0.00346154 A (3.461538 mA)
Une autre approche :
>>> loi = Loi()
>>> # diviseur de tension
>>> V2 = loi.DiviseurTension(vtotal=E, r=R2//R3,
r2=R1)
>>> V2
Tension : 6.230769 V
>>> # Théorème de Millman
>>> masse = Tension(0)
>>> V2 = loi.Millman(v_r=[(E, R1), (masse, R2),
(masse, R3)])
>>> V2
Tension : 6.230769 V
>>> (E/R1)/(1/R1 +1/R2 +1/R3)
Tension : 6.230769 V
>>> V2/E
0.5192307692307693
>>> # diviseur de courant
>>> I3 = loi.DiviseurCourant(itotal=I1, r=R3,
r2=R2)
>>> I3
Intensité du courant : 0.00346154 A (3.461538 mA)
>>> I1*R2/(R2 +R3)
Intensité du courant : 0.00346154 A (3.461538 mA)
Puissances et loi de Joule
>>> P = E*I1 # puissance fournie par la source E
>>> P
Puissance : 0.0692308 W (69.230769 mW)
>>> P1 = loi.Joule(r=R1, i=I1)
>>> P1
Puissance : 0.033284 W (33.284024 mW)
>>> R1*I1*I1
Puissance : 0.033284 W (33.284024 mW)
>>> loi.Joule(r=R1, v=V1)
Puissance : 0.033284 W (33.284024 mW)
>>> V1*(V1/R1)
Puissance : 0.033284 W (33.284024 mW)
>>> P2 = loi.Joule(r=R2, i=I2)
>>> P2
Puissance : 0.0143787 W (14.378698 mW)
>>> P3 = loi.Joule(r=R3, i=I3)
Puissance : 0.021568 W (21.568047 mW)
>>> P1 +P2 +P3
Puissance : 0.0692308 W (69.230769 mW)
Exemple 2a
Le même circuit électrique mais avec une résistance R3 ajustable :
Etude de l'évolution de U2 en fonction de R3
R3 = ? 0
Propriétés de R3 :
Résistance : 0.000000 Ω
Propriétés de U2 :
Tension : 0.000000 V
R3 = ? 100
Propriétés de R3 :
Résistance : 100.000000 Ω
Propriétés de U2 :
Tension : 1.055375 V
R3 = ?
Télécharger les
scripts exemple2a_analyse_parametrique.py et exemple2a_analyse_para
metrique_bis.py
Exemple 2b
On utilise ici le module matplotlib pour faire de belles courbes :
Télécharger les
scripts exemple2b_analyse_parametrique.py et exemple2b_analyse_para
metrique_bis.py
Exemple 3
On cherche la valeur de R3 qui donne U2 = 6,00 V.
On utilise une méthode dichotomique :
Itération R3 (Ω) U2 (V)
1 5000.0
7.641509433962264
2 2500.0
6.7782426778242675
3 1250.0
5.5290102389078495
4 1875.0
6.303501945525291
5 1562.5
5.969049373618275
6 1718.75
6.146947223180407
7 1640.625
6.060929983965794
8 1601.5625
6.0157594420795215
9 1582.03125
5.992601726263872
10 1591.796875
6.004229291252643
11 1586.9140625
5.998427762523782
12 1589.35546875
6.001331580654524
13 1588.134765625
5.99988043623693
14 1588.7451171875
6.000606199456697
15 1588.43994140625
6.000243365618415
16 1588.287353515625
6.000061912872932
17 1588.2110595703125
5.99997117754154
Résultat : 1588.2110595703125 Ω
Télécharger les scripts exemple3_solution.py et exemple3_solution_bis.py
Avantages et limitations
Ce module gère les opérations arithmétiques de base (+, -, *, /) ainsi que
// qui désigne deux résistances en parallèle.
La cohérence des unités est contrôlée :
>>> V3 = V1 -V2 +I3
TypeError
>>> I = I1 +0.5
TypeError
>>> I2 = Courant(0.5)
>>> I = I1 + I2
>>> I = 5*I2 -V1/R1 + I3
Le résultat d'une opération doit donner une grandeur dont l'unité est en
volt, ampère, ohm, siemens, watt ou sans unité.
Autrement, vous aurez une erreur :
>>> R1/V1 # Ω/V -> Erreur
TypeError
>>> R2*(R3/(R2 +R3)) # Ω*(Ω/Ω) -> Ω*() -> Ω
>>> R2*R3/(R2 +R3) # Ω*Ω -> Erreur
TypeError
>>> P = V1*(V1/R1) # V*(V/Ω) -> V*A -> W
>>> P = V1*V1/R1 # V*V -> Erreur
TypeError
>>> V1()**2/R1()