Types de données en Python - LMPT
Types de données en Python - LMPT
Types de données en Python - LMPT
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Types</strong> <strong>de</strong> données <strong>en</strong> <strong>Python</strong><br />
– Integer : n=10<br />
– Float : x=0.27; y=3e-28; z=3/5+x*y<br />
– String : msg=’blabla’; rep=’re-’ ; chaine=msg+rep; chaine=2*msg; print(l<strong>en</strong>(msg));<br />
print(msg[2])<br />
– List : liste=[’lundi’, ’mardi’, ’mercredi’]<br />
Utilisation <strong>de</strong>s listes : print(liste[2]); <strong>de</strong>l(liste[0]); liste.app<strong>en</strong>d(’jeudi’); print(l<strong>en</strong>(liste))<br />
liste1+liste2; liste[3]=liste[3]+liste[4]+’hello’.<br />
Interaction avec l’utilisateur : rep=input("Entrez un répertoire:") qui r<strong>en</strong>voit une chaîne<br />
<strong>de</strong> caractères (convertir si besoin <strong>en</strong> <strong>en</strong>tier, float etc...)<br />
Exercices :<br />
1. Ecrivez un programme qui convertit les <strong>de</strong>grés Celsius <strong>en</strong> <strong>de</strong>gré Far<strong>en</strong>heit (T F = 9 5 T C + 32).<br />
2. Ecrivez un programme qui calcule les intérêts cumulés p<strong>en</strong>dant n années d’un capital <strong>de</strong><br />
départ C placé au taux d’intérêt r<br />
3. Ecrivez un programme qui détermine le nombre <strong>de</strong> caractères a dans une chaîne <strong>en</strong>treé par<br />
l’utilisateur.<br />
4. Ecrivez un programme qui détermine si une chaîne est un palindrome.<br />
5. A partir <strong>de</strong> <strong>de</strong>ux listes L1 et L2 <strong>de</strong> même taille, écrivez un programme qui crée une liste L3<br />
alternant les élém<strong>en</strong>ts <strong>de</strong> L1 et L2.<br />
6. Ecrivez un programme qui recherche le plus grand élém<strong>en</strong>t d’une liste donnée.
Fonctions et modules<br />
Fonction : retourne une donnée (quelque soit le type)<br />
Procédure : ne retourne ri<strong>en</strong> mais fait quelque chose<br />
– Définition :<br />
<strong>de</strong>f ma_fonction ():<br />
···<br />
···<br />
<strong>de</strong>f autre_fonction ():<br />
– Def avec paramètres : <strong>de</strong>f ma_fonction (hauteur, nom, co<strong>de</strong>)<br />
– Initialisation : <strong>de</strong>f ma_fonction (hauteur=3, nom=’echelle’, co<strong>de</strong>=[])<br />
– Appel : ma_fonction (3,’corbeau’)<br />
– Appel avec étiquettes : ma_fonction (nom=’corbeau’, co<strong>de</strong>=[2,3], hauteur=3)<br />
– Pour une fonction : return, utilisation : a=ma_fonction(2,”,[3,5])<br />
Par défaut les variables sont locales, sinon utiliser global.<br />
Module : regroupem<strong>en</strong>t <strong>de</strong> fonctions (équival<strong>en</strong>t d’une librairie) voire plus (POO), mon_module.py<br />
(ne pas repr<strong>en</strong>dre un nom déjà existant).<br />
Importer un module : import mon_module<br />
Att<strong>en</strong>tion, les définitions <strong>de</strong> fonction doiv<strong>en</strong>t précé<strong>de</strong>r le corps du programme, <strong>de</strong> même qu’une<br />
fonction servant à une autre.<br />
Exercices :<br />
1. Ecrire une fonction qui compte le nombre <strong>de</strong> mots dans une phrase<br />
2. Ecrire une fonction changeCar(ch, ca1, ca2, <strong>de</strong>but, fin) qui remplace dans la chaîne<br />
ch tous les caractères ca1 par les caractères ca2 à partir <strong>de</strong> l’indice <strong>de</strong>but, jusqu’à l’indice fin.<br />
Si début et fin sont omis, le traitem<strong>en</strong>t concerne toute la chaine.<br />
3. Ecrire une fonction chercheMax(liste, <strong>de</strong>but, fin) qui cherche dans la liste liste,<br />
l’élém<strong>en</strong>t maximum (au s<strong>en</strong>s mathématique). La recherche doit s’effectuer <strong>en</strong>tre les rangs d’indice<br />
<strong>de</strong>but et fin. Si début et fin sont omis, le traitem<strong>en</strong>t concerne toute la liste.<br />
4. Ecrire une fonction erathost<strong>en</strong>e(n) qui r<strong>en</strong>voit tous les nombres premiers compris <strong>en</strong>tre<br />
1 et n <strong>en</strong> utilisant le crible d’Erathostène.<br />
5. Ecrire une fonction mobius(n) qui calcule la fonction <strong>de</strong> mobius <strong>de</strong> n.<br />
6. Mettre toutes ces fonctions dans un module appelé essai_module.py et l’importer pour<br />
faire un programme <strong>de</strong>mandant à un utilisateur d’<strong>en</strong>trer un <strong>en</strong>tier, donant <strong>en</strong> retour la fonction<br />
<strong>de</strong> mobius et les nombres premiers <strong>en</strong>tre 1 et l’<strong>en</strong>tier.
Chaines, Listes, Tuples, Dictionnaires<br />
1. Chaines <strong>de</strong> Caractères<br />
– ch[1:3] donne ’lab’<br />
– ch[-4] donne ’a’<br />
– comparaison : ch1, ch2 = ’bla’ , ’<strong>de</strong>f’<br />
alors on peut tester if ch1 < ch2 :<br />
– parcourir une chaine : for i in ch :<br />
– test d’appart<strong>en</strong>ance : if i in ch :<br />
– split(car) : chaine vers liste <strong>en</strong> découpant au caractère car<br />
– join(liste) : liste vers chaine "–-".join(liste)<br />
– replace(c1,c2) : remplace le caractère c1 par c2<br />
– in<strong>de</strong>x(car) : revoit la première occur<strong>en</strong>ce <strong>de</strong> car<br />
– format(tuple) : formate la chaine <strong>en</strong> remplaçant les {}<br />
2. Listes<br />
– test d’appart<strong>en</strong>ance : if i in liste :<br />
– parcourrir la liste : for i in liste :<br />
– Att<strong>en</strong>tion : liste2=liste fait un nouveau pointeur vers la même liste<br />
– Slicing : liste[2:2]=["blabla", "re-blabla"], liste[2:5]=[]<br />
3. Tuples<br />
Entre chaine <strong>de</strong> caractère et liste : ordonné mais pas modifiable (moins gourmand).<br />
tup=’a’,’b’,’c’,’4’<br />
print(tup)<br />
(’a’,’b’,’c’,’4’)<br />
4. Dictionnaires<br />
Type composite non ordonné contrairem<strong>en</strong>t aux autres. Donc on utilise une clef et le dictionnaire<br />
est constitué <strong>de</strong> paires (clef,valeur).<br />
– initialisation : dico={}<br />
– dico[’pommes’]=’3’<br />
– la clef peut être plus générale, par exemple <strong>de</strong>s coordonnées <strong>de</strong> point sous forme <strong>de</strong> tuple :<br />
dico(3,4)=’touché’<br />
– si la clef n’est pas définie, l’appel r<strong>en</strong>voit une erreur. On a donc la métho<strong>de</strong> suivante : dico.get(clef,<br />
’pas définini’).<br />
– print(dico.keys())<br />
– print(dico.values())<br />
– print(dico.items())<br />
– <strong>de</strong>l(clef) supprime l’<strong>en</strong>trée associée<br />
– parcourrir le dictionnaire : for clef in dico :<br />
– test d’appart<strong>en</strong>ance : if clef in dico :<br />
On peut controller le flux à l’ai<strong>de</strong> d’un dictionnaire (très utile) :<br />
possibilites = {’a’:fonction_A , ’b’:fonction_B, ’c’:fonction_C}<br />
possibilites(choix)()
-> exécute la fonction correspondant au choix, c’est l’équival<strong>en</strong>t <strong>de</strong> case/switch.<br />
Mieux :<br />
possibilites.get(choix, fonction_par_<strong>de</strong>faut)()<br />
Exercice :<br />
Créer un script qui créée un mini-système <strong>de</strong> base <strong>de</strong> données fonctionnant à l’ai<strong>de</strong> d’un dictionnaire<br />
dans lequel on mémorise les noms d’une série <strong>de</strong> copains, leur age et leur taille. Le<br />
script doit comporter <strong>de</strong>ux fonctions : la première pour le remplissage du dictionnaire et la<br />
secon<strong>de</strong> pour sa consultation. Dans la fonction <strong>de</strong> remplissage, on utilisera une boucle pour<br />
accepter les données <strong>en</strong>trées par l’utilisateur.<br />
Dans le dictionnaire, le nom <strong>de</strong> l’utilisateur servira <strong>de</strong> clef, et les valeurs seront constituées <strong>de</strong><br />
tuple <strong>de</strong> la forme (age,taille) où l’age est un <strong>en</strong>tier <strong>en</strong> années et la taille un réel <strong>en</strong> mètres.<br />
La fonction <strong>de</strong> consultation comportera elle aussi une boucle, dans laquelle l’utilisateur pourra<br />
fournir un nom quelconque pour obt<strong>en</strong>ir <strong>en</strong> retour le couple (age,taille) correspondant. Le<br />
résultat <strong>de</strong> la requête <strong>de</strong>vra être une ligne <strong>de</strong> texte bi<strong>en</strong> formatée, par exemple :<br />
«Nom : Jean Dupont - âge : 15 ans - taille : 1.74 m »
Travailler avec <strong>de</strong>s fichiers<br />
1. Se placer dans le bon répertoire :<br />
from os import chdir, getcwd<br />
print(getcwd())<br />
chdir("/home/toto/mon_rep")<br />
print(getcwd())<br />
2. Ecrire dans un fichier séqu<strong>en</strong>tiellem<strong>en</strong>t :<br />
obFichier = op<strong>en</strong>(’mon_fichier’, ’a’)<br />
obFichier.write(’Hello you !’)<br />
obFichier.write(’How are you ?’)<br />
obFichier.close()<br />
3. Lire un un fichier séqu<strong>en</strong>tiellem<strong>en</strong>t :<br />
obFichier = op<strong>en</strong>(’mon_fichier’, ’r’)<br />
t=obFichier.read()<br />
print(t)<br />
obFichier.close()<br />
’a’ :app<strong>en</strong>d ; ’w’ :write ; ’r’ :read<br />
read(nb) -> nb <strong>en</strong>tier donne le nombre <strong>de</strong> caractères à lire.<br />
4. Lire ligne à ligne avec une boucle infinie :<br />
fs = op<strong>en</strong>(’source.txt’, ’r’)<br />
fd = op<strong>en</strong>(’<strong>de</strong>stination.txt’, ’w’)<br />
While 1:<br />
ligne=fs.readline()<br />
if ligne=="":<br />
break<br />
if ligne[0]!=’#’:<br />
fd.write(ligne)<br />
fs.close()<br />
fd.close()<br />
Att<strong>en</strong>tion à écrire <strong>de</strong>s chaines <strong>de</strong> caractères (convertir si besoin <strong>en</strong> str). Sinon, pour conserver<br />
le type, utiliser le module pickle.<br />
5. gestion <strong>de</strong>s erreurs au cas où il ne soit pas possible d’ouvrir le fichier :<br />
fichier=input(’Entrez un nom <strong>de</strong> fichier’)<br />
try:<br />
f = op<strong>en</strong>(fichier, ’r’)<br />
f.close()<br />
except:<br />
print(’fichier introuvable’)<br />
Exercice : repr<strong>en</strong>dre <strong>de</strong>s co<strong>de</strong>s <strong>en</strong> C sur les fichiers et les transcrires <strong>en</strong> python
La programmation ori<strong>en</strong>tée objet<br />
Il s’agit d’un paradigme <strong>de</strong> programmation, non obligatoire <strong>en</strong> python, mais très utile pour<br />
faire du co<strong>de</strong> à la fois sûr et bi<strong>en</strong> conçu.<br />
1. Une classe va regrouper <strong>de</strong>s objets possédant <strong>de</strong>s caractéristiques souv<strong>en</strong>t similaires. Par<br />
exemple, la classe <strong>de</strong>s moy<strong>en</strong>s <strong>de</strong> locomotions.<br />
L’emploi <strong>de</strong> classes va permettre d’<strong>en</strong>capsuler un certain nombre <strong>de</strong> variables et <strong>de</strong> métho<strong>de</strong>s,<br />
ce qui donnera une programmation mieux structurée et plus sécurisée (on risque moins <strong>de</strong><br />
modifier <strong>de</strong>s données qui ne <strong>de</strong>vrai<strong>en</strong>t pas l’être).<br />
Au sein d’une classe, certaines variables et métho<strong>de</strong>s peuv<strong>en</strong>t être publiques (accessibles <strong>de</strong><br />
l’extéreur) et d’autres privées (accessibles seulem<strong>en</strong>t <strong>de</strong> façon interne, dans la classe).<br />
2. L’héritage permet <strong>de</strong> construire <strong>de</strong>s sous-classes ou classes-<strong>en</strong>fant possédant les fonctionalités<br />
<strong>de</strong> la classe par<strong>en</strong>t, mais <strong>en</strong> définissant aussi ses propres fonctionalités. Par exemple, on<br />
peut construire la classe-<strong>en</strong>fant "voitures" à partir <strong>de</strong> la classe-par<strong>en</strong>te "moy<strong>en</strong>s <strong>de</strong> locomotions".<br />
Un autre mécanisme existe : le polymorphisme qui permet <strong>de</strong> modifier les comportem<strong>en</strong>t <strong>de</strong>s<br />
objets d’une classe selon le contexte.<br />
3. Les objets sont <strong>de</strong>s membres d’une classe. Un objet regroupe <strong>de</strong>ux choses : <strong>de</strong>s attributs et<br />
<strong>de</strong>s métho<strong>de</strong>s. Lorsqu’on créé un représ<strong>en</strong>tant d’une classe, on dit qu’on instancie un objet.<br />
Pour cela, on utilise une métho<strong>de</strong> spécifique <strong>de</strong> la classe, appelée métho<strong>de</strong> constructeur.<br />
4. Les attributs sont <strong>de</strong>s données associées à un objet. Par exemple : si on considère un objet<br />
<strong>de</strong> la classe "voiture", la couleur est un attribut <strong>de</strong> cet objet. Une métho<strong>de</strong> est une fonction ou<br />
procédure, agissant sur les attributs <strong>de</strong> l’objet. Métho<strong>de</strong>s et attributs sont eux-mêmes <strong>en</strong>capsulés<br />
dans l’objet.
En pratique :<br />
class Voiture(object):<br />
# <strong>de</strong>finition <strong>de</strong>s attributs et métho<strong>de</strong>s à v<strong>en</strong>ir<br />
utilisation :<br />
simca = voiture() # instanciation d’un objet<br />
simca.couleur = rouge # attribut couleur<br />
Exemple d’une fonction qui instancie un objet voiture et lui affecte une couleur :<br />
<strong>de</strong>f voiture_coloree(couleur):<br />
v = Voiture()<br />
v.couleur = couleur<br />
return v<br />
simca = voiture(’rouge’)<br />
peugeot = voiture(’verte’)<br />
print(simca.couleur, peugeot.couleur)<br />
On pourrait co<strong>de</strong>r une couleur par défaut dans la classe, c’est ce que nous ferons plus tard,<br />
ainsi que définir <strong>de</strong>s métho<strong>de</strong>s. Affecter une couleur comme nous l’avons fait n’est pas la<br />
meilleure façon <strong>de</strong> faire mais c’est suffisant pour le mom<strong>en</strong>t.<br />
Les objets peuv<strong>en</strong>t eux-même comporter <strong>de</strong>s objets <strong>en</strong> tant qu’attributs. Par exemple, l’objet<br />
"voiture" peut comporter l’objet "siège" qui aura lui même <strong>de</strong>s attributs <strong>de</strong> largeur, longeur,<br />
matière etc...<br />
simca.siege.largeur = 70<br />
Cette notation à l’ai<strong>de</strong> <strong>de</strong> point (.) est fondam<strong>en</strong>tale, on l’appelle qualification <strong>de</strong> nom hierarchisée,<br />
du plus gros cont<strong>en</strong>ant vers le plus petit, et <strong>en</strong>fin les attributs finaux (ou les métho<strong>de</strong>s).<br />
Définition d’une métho<strong>de</strong> constructeur et d’une métho<strong>de</strong> quelconque dans une classe (self<br />
représ<strong>en</strong>te l’objet instancié) :
class Time(object):<br />
# classe d’objets temporels<br />
<strong>de</strong>f __init__(self): # métho<strong>de</strong> constructeur<br />
self.heure = 12<br />
self.minute = 0<br />
self.secon<strong>de</strong> = 0<br />
<strong>de</strong>f affiche_heure(t): # une métho<strong>de</strong><br />
print("{}:{}:{}".format(t.heure, t.minute, t.secon<strong>de</strong>))<br />
Utilisation : objet.métho<strong>de</strong>()<br />
temp_start = Time()<br />
temp_start.affiche_heure()<br />
Instanciation avec paramètres :<br />
<strong>de</strong>f __init__(self, hh = 12, mm = 0, ss = 0):<br />
self.heure = hh<br />
self.minute = mm<br />
self.secon<strong>de</strong> = ss<br />
pause = Time(hh = 10)<br />
pause.affiche_heure()<br />
# métho<strong>de</strong> constructeur<br />
Exercices :<br />
1. Définir une classe CompteBancaire() qui permet d’instancier <strong>de</strong>s objets tels que compte1,<br />
compte2, ... Le constructeur initialisera <strong>de</strong>ux attributs d’instance nom et sol<strong>de</strong> avec les valeurs<br />
par défaut ’duschmol’ et 1000. Trois métho<strong>de</strong>s doiv<strong>en</strong>t être aussi définies : <strong>de</strong>pot(somme)<br />
qui permet d’ajouter <strong>de</strong> l’arg<strong>en</strong>t au compte ; retrait(somme) qui permet <strong>de</strong> retirer <strong>de</strong> l’arg<strong>en</strong>t<br />
(pas <strong>de</strong> découvert autorisé !) ; et affiche() qui r<strong>en</strong>voit le sol<strong>de</strong> du compte.<br />
2. Définir une classe Satellite() qui permet d’instancier <strong>de</strong>s objets représ<strong>en</strong>tant <strong>de</strong>s satellites<br />
lancés autour <strong>de</strong> la terre. Le constructeur initialise <strong>de</strong>ux attributs d’instance par défaut<br />
comme suit : masse=100, vitesse=0. Lorsqu’on instancie un satellite, on peut choisir son<br />
nom, sa masse et sa vitesse. Définir <strong>en</strong>suite une métho<strong>de</strong> impulsion(force, duree) qui permet<br />
<strong>de</strong> faire varier la vitesse du satellite (variation <strong>de</strong> vitesse = force * temps / masse) ; une métho<strong>de</strong><br />
affiche_vitesse() qui affiche le nom du satellite et sa vitesse courante ; une métho<strong>de</strong><br />
<strong>en</strong>ergie() qui r<strong>en</strong>voit l’énergie cinétique courante du satellite.
Un zeste <strong>de</strong> cryptographie<br />
1. Le chiffre <strong>de</strong> Caesar<br />
Ce chiffrem<strong>en</strong>t consiste à décaler les lettres d’un pas constant. Par exemple, si on choisit un<br />
décalage <strong>de</strong> 4, on va alors substituer la lettre A par E, B par F , C par G etc... (et on boucle, par<br />
exemple Z est remplacé par D).<br />
Ce chiffrem<strong>en</strong>t est un chiffrem<strong>en</strong>t monoalphabétique par subsitution.<br />
2. Cryptanalyse du chiffre <strong>de</strong> Caesar<br />
Le chiffre <strong>de</strong> Caesar est suceptible d’être cassé par l’analyse <strong>de</strong> fréqu<strong>en</strong>ce, comme tout chiffrem<strong>en</strong>t<br />
monoalphabétique : dans la langue française, la lettre E est la plus fréqu<strong>en</strong>te, puis vi<strong>en</strong>t<br />
la lettre A etc... donc <strong>en</strong> repérant les occur<strong>en</strong>ces, on peut <strong>en</strong> déduire quelle est le substitut pour<br />
E, A ... Evi<strong>de</strong>mm<strong>en</strong>t, plus le texte chiffré est long, plus fiable est la cryptanalyse.<br />
3. Chiffre <strong>de</strong> Vig<strong>en</strong>ère<br />
Il s’agit d’un chiffrem<strong>en</strong>t polyalphabétique : le chiffrem<strong>en</strong>t change à chaque nouvelle lettre,<br />
selon une clef définie et qui doit être connue <strong>de</strong> l’éméteur et du récépteur pour déchiffrer le<br />
message. Si par exemple la clef est "perman<strong>en</strong>t", alors les décalages successifs sont les suivant :<br />
16,5,18,13,1,14,5,14,19 puis on repr<strong>en</strong>d le décalage à 16,5 etc...<br />
Ce chiffrem<strong>en</strong>t est beaucoup plus difficile à analyser. Il faut d’abord t<strong>en</strong>ter <strong>de</strong> repérer la longueur<br />
l <strong>de</strong> la clef <strong>de</strong> chiffrem<strong>en</strong>t <strong>en</strong> repérant <strong>de</strong>s occur<strong>en</strong>ces, puis travailler comme pour le<br />
chiffrem<strong>en</strong>t <strong>de</strong> Caesar sur chaque morceau <strong>de</strong> longueur l.<br />
Exercices – faire <strong>de</strong>s scripts python qui effectu<strong>en</strong>t le chiffrem<strong>en</strong>t et déchiffrem<strong>en</strong>t <strong>de</strong> Caesar<br />
et <strong>de</strong> Vig<strong>en</strong>ère (<strong>en</strong> fournissant la clef à chaque fois) ; puis un script faisant la cryptanalyse du<br />
chiffrem<strong>en</strong>t <strong>de</strong> Caesar par analyse <strong>de</strong> fréqu<strong>en</strong>ces.
Programmation réseau <strong>en</strong> python<br />
On est sur le principe cli<strong>en</strong>t /serveur : le cli<strong>en</strong>t se connecte sur un serveur déterminé par son<br />
nom ou son adresse IP, sur un port précisé. L’objet fondam<strong>en</strong>tal est un socket, qui est une<br />
brique logicielle se mettant <strong>en</strong> écoute <strong>de</strong>rrière un port, et pouvant égalem<strong>en</strong>t transmettre <strong>de</strong>s<br />
données sur ce port.<br />
Coté cli<strong>en</strong>t :<br />
On débute par instancier un objet <strong>de</strong> type socket et le connecter sur le serveur :<br />
# cli<strong>en</strong>t basique<br />
import socket<br />
HOST = ’10.68.5.171’<br />
PORT = 5000<br />
cli<strong>en</strong>tsock = socket.socket(socket.AF_ INET, socket.SOCK_ STREAM)<br />
cli<strong>en</strong>tsock.connect((HOST,PORT))<br />
A partir <strong>de</strong> là, le cli<strong>en</strong>t peut soit recevoir, soit émettre <strong>de</strong>s données à travers le socket cli<strong>en</strong>tsock.<br />
Mais pour cela, il faut avant avoir mis, coté serveur, un soscket <strong>en</strong> écoute, sur le port adapté et<br />
on accepte les connexions <strong>en</strong>trantes.<br />
Coté serveur :<br />
# serveur basique<br />
import socket<br />
HOST = ”<br />
PORT = 5000<br />
serversock = socket.socket(socket.AF_ INET, socket.SOCK_ STREAM)<br />
serversock.bind((HOST,PORT))<br />
serversock.list<strong>en</strong>(1)<br />
(cli<strong>en</strong>tsock, address) = serversock.accept()<br />
Le tuple (cli<strong>en</strong>tsock, address) conti<strong>en</strong>t d’une part un objet servant <strong>de</strong> référ<strong>en</strong>ce vers le socket<br />
cli<strong>en</strong>t qui s’est connecté au serveur, et d’autre part un tableau adress cont<strong>en</strong>ant l’adresse<br />
IP et le port utilisé par le cli<strong>en</strong>t pour se connecter.<br />
Coté serveur aussi, on peut <strong>en</strong>voyer ou récupérer <strong>de</strong>s données transitant par le socket serversock.<br />
Une fois la tranmission faite, il ne faut pas oublier <strong>de</strong> fermer les sockets, sans quoi le port utilisé<br />
ne sera plus disponible. On réalise cela à l’ai<strong>de</strong> <strong>de</strong> la métho<strong>de</strong> close() :<br />
# cote cli<strong>en</strong>t :<br />
cli<strong>en</strong>tsock.close()<br />
# cote serveur :<br />
serversock.close()
Si le programme s’est interrompu <strong>de</strong> façon subite avant d’avoir correctem<strong>en</strong>t fermé le socket,<br />
on peut supprimer l’application <strong>en</strong> écoute sur le port concerné grace à la comman<strong>de</strong> shell<br />
lsof -i qui donne le PID du processus actif sur le port.<br />
Envoi et Réception <strong>de</strong> données<br />
On utilise <strong>de</strong>ux métho<strong>de</strong>s assez simples à compr<strong>en</strong>dre : s<strong>en</strong>d(), recv() mais il faut p<strong>en</strong>ser<br />
à <strong>en</strong>co<strong>de</strong>r et déco<strong>de</strong>r <strong>en</strong> mo<strong>de</strong> UTF-8 (par exemple) dans le cas d’un <strong>en</strong>voi <strong>de</strong> texte, car la<br />
transmission <strong>de</strong> données se fait <strong>en</strong> type byte par défaut.<br />
Coté cli<strong>en</strong>t, on peut donc compléter le co<strong>de</strong> par exemple par :<br />
text = input(’S<strong>en</strong>d a text : ’)<br />
cli<strong>en</strong>tsock.s<strong>en</strong>d(text.<strong>en</strong>co<strong>de</strong>(’utf-8’))<br />
cli<strong>en</strong>tsock.close()<br />
et coté serveur :<br />
print(cli<strong>en</strong>tsock.recv(1024).<strong>de</strong>co<strong>de</strong>(’utf-8’))<br />
serversock.close()<br />
Exercice 1 : Mettre <strong>en</strong> place un protocole <strong>de</strong> sécurisation <strong>de</strong> la connexion <strong>en</strong> <strong>de</strong>mandant au<br />
cli<strong>en</strong>t <strong>de</strong> s’auth<strong>en</strong>tifier lorsqu’il se connecte sur le serveur.<br />
Exercice 2 : Mettre <strong>en</strong> place un système <strong>de</strong> messagerie <strong>en</strong>tre un cli<strong>en</strong>t et un serveur sur la même<br />
machine (on utilisera <strong>de</strong>ux f<strong>en</strong>êtres), puis <strong>en</strong>tre <strong>de</strong>ux machines différ<strong>en</strong>tes.
Controle Continu n o 2<br />
Le principe du co<strong>de</strong> Morse est <strong>de</strong> substituer chaque lettre par une suite <strong>de</strong> signaux courts<br />
(représ<strong>en</strong>tés par un point « . ») ou longs (représ<strong>en</strong>tés par un trait « _ ») selon le modèle suivant :<br />
On ne ti<strong>en</strong>t pas compte ici ni <strong>de</strong> la ponctuation ni <strong>de</strong>s chiffres (qui ont une codification Morse<br />
égalem<strong>en</strong>t). Un trait équivaut <strong>en</strong> longueur à trois points ; <strong>en</strong>tre <strong>de</strong>ux lettres, on laisse l’équival<strong>en</strong>t<br />
<strong>de</strong> trois points blancs ; <strong>en</strong>tre <strong>de</strong>ux mots on laisse l’équival<strong>en</strong>t <strong>de</strong> sept points blancs.<br />
Ainsi, la phrase « le petit chat » se traduira <strong>en</strong> Morse :<br />
L E P E T I T ···<br />
. _ . . (3B) . (7B) ._ _ . (3B) . (3B) _ (3B) . . (3B) _<br />
où (3B) représ<strong>en</strong>te une série <strong>de</strong> trois blancs et (7B) une série <strong>de</strong> sept blancs. On choisit donc<br />
ici <strong>de</strong> représ<strong>en</strong>ter ce co<strong>de</strong> sous forme d’une liste consituée <strong>de</strong> chaines <strong>de</strong> caractères ainsi :<br />
[ ._.. ,(3B), . ,(7B), .__. ,(3B), . ,(3B), _ ,(3B), .. ,(3B), _ ]
Vous <strong>de</strong>vez réaliser un module morse.py implém<strong>en</strong>tant les fonctions suivantes :<br />
a) string_to_morse(chaine) : pr<strong>en</strong>d <strong>en</strong> <strong>en</strong>trée une chaine <strong>de</strong> type string et r<strong>en</strong>voit une<br />
liste constituée du co<strong>de</strong> morse correspondant.<br />
b) morse_to_string(liste) : qui fait l’inverse, pr<strong>en</strong>ant <strong>en</strong> <strong>en</strong>trée une liste et donnant <strong>en</strong><br />
retour une chaine <strong>de</strong> caractères.<br />
c) kbd_to_morse() : une procédure qui se met <strong>en</strong> écoute au clavier et transcris à l’écran directem<strong>en</strong>t<br />
<strong>en</strong> morse les caractères <strong>en</strong>trés au clavier (bi<strong>en</strong> <strong>en</strong>t<strong>en</strong>du on ne ti<strong>en</strong>t pas compte<br />
<strong>de</strong>s acc<strong>en</strong>ts, majuscules, chiffres et ponctuation, sauf les espaces <strong>en</strong>tre les mots). La procédure<br />
comportera une boucle qui se terminera si l’utilisateur <strong>en</strong>tre le caractère «*».<br />
Indication : pour la procédure c), voici un bout <strong>de</strong> co<strong>de</strong> à examiner et utiliser :<br />
import curses # import <strong>de</strong> la librairie curses<br />
stdscr = curses.initscr() # initialisation du terminal curses<br />
curses.cbreak() # mo<strong>de</strong> où l’<strong>en</strong>trée <strong>de</strong>s caractères ne nécessite pas <strong>de</strong> CR<br />
curses.noecho() # n’<strong>en</strong>voit pas les charactères à l’écran lors d’une saisie<br />
while 1:<br />
c = chr(stdscr.getch()) # récupère un caractère <strong>en</strong>tré au clavier<br />
stdscr.addstr(c+’|’) # <strong>en</strong>voit le caractère <strong>en</strong> console suivi <strong>de</strong> ’|’<br />
stdscr.refresh() # raffraichit l’affichage<br />
curses.<strong>en</strong>dwin()<br />
# ferme le terminal curses
Utilisation du module tk<br />
Classes :<br />
Tk, Label, Button, Entry, Canevas, Frame etc...<br />
Métho<strong>de</strong>s :<br />
pack(), mainloop(), quit(), <strong>de</strong>stroy(), bind()<br />
Premier exemple : calculatrice graphique<br />
from tkinter import *<br />
<strong>de</strong>f evaluer(ev<strong>en</strong>t):<br />
chaine.configure(text = "Résultat = " + str(eval(<strong>en</strong>tree.get())))<br />
f<strong>en</strong>etre = Tk()<br />
<strong>en</strong>tree = Entry(f<strong>en</strong>etre)<br />
<strong>en</strong>tree.bind("", evaluer)<br />
chaine = Label(f<strong>en</strong>etre)<br />
<strong>en</strong>tree.pack()<br />
chaine.pack()<br />
f<strong>en</strong>etre.mainloop()
Deuxième exemple :<br />
from tkinter import *<br />
<strong>de</strong>f avance(gd,hb):<br />
global x1,y1<br />
x1, y1 = x1 + gd, y1 + hb<br />
can1.coords(oval1, x1, y1, x1+30, y1+30)<br />
<strong>de</strong>f <strong>de</strong>pl_gauche():<br />
avance(-10,0)<br />
<strong>de</strong>f <strong>de</strong>pl_droite():<br />
avance(10,0)<br />
<strong>de</strong>f <strong>de</strong>pl_haut():<br />
avance(0,10)<br />
<strong>de</strong>f <strong>de</strong>pl_bas():<br />
avance(0,-10)<br />
#––––- main –––––<br />
x1, y1 = 10, 10<br />
f<strong>en</strong>1 = Tk()<br />
f<strong>en</strong>1.title("Exercice d’animation")<br />
can1 = Canvas(f<strong>en</strong>1, bg = ’dark grey’, height = 300, width = 300)<br />
oval1 = can1.create_oval(x1,y1,x1+30,y1+30,width=2,fill=’red’)<br />
can1.pack(si<strong>de</strong>=LEFT)<br />
Button(f<strong>en</strong>1, text=’Quitter’, command=f<strong>en</strong>1.quit).pack(si<strong>de</strong>=BOTTOM)<br />
Button(f<strong>en</strong>1, text=’Gauche’, command=<strong>de</strong>pl_gauche).pack()<br />
Button(f<strong>en</strong>1, text=’Droite’, command=<strong>de</strong>pl_droite).pack()<br />
Button(f<strong>en</strong>1, text=’Haut’, command=<strong>de</strong>pl_haut).pack()<br />
Button(f<strong>en</strong>1, text=’Bas’, command=<strong>de</strong>pl_bas).pack()<br />
f<strong>en</strong>1.mainloop()
Troisième exemple<br />
from tkinter import *<br />
<strong>de</strong>f cercle(can, x, y, r):<br />
can.create_oval(x-r,y-r,x+r,y+r)<br />
class Application(Tk):<br />
<strong>de</strong>f __init__(self):<br />
Tk.__init__(self)<br />
self.can=Canvas(self, width=475, height=130, bg=’white’)<br />
self.can.pack(si<strong>de</strong>=TOP, padx=5, pady=5)<br />
Button(self, text="Train", command=self.<strong>de</strong>ssine).pack(si<strong>de</strong>=LEFT)<br />
Button(self, text="Hello", command=self.coucou).pack(si<strong>de</strong>=LEFT)<br />
<strong>de</strong>f <strong>de</strong>ssine(self):<br />
self.w1=Wagon(self.can, 10, 30)<br />
self.w2=Wagon(self.can, 130, 30)<br />
self.w3=Wagon(self.can, 250, 30)<br />
self.w4=Wagon(self.can, 370, 30)<br />
<strong>de</strong>f coucou(self):<br />
self.w1.perso(3)<br />
self.w1.perso(1)<br />
self.w1.perso(2)<br />
self.w1.perso(1)<br />
class Wagon(object):<br />
<strong>de</strong>f __init__(self, canev, x,y):<br />
self.canev, self.x, self.y = canev, x, y<br />
canev.create_rectangle(x,y,x+95,y+60)<br />
for xf in range(x+5,x+90,30):<br />
canev.create_rectangle(xf,y+5,xf+25,y+40)<br />
cercle(canev, x+18, y+73, 12)<br />
cercle(canev, x+77, y+73, 12)<br />
<strong>de</strong>f perso(self, f<strong>en</strong>):<br />
xf = self.x + f<strong>en</strong>*30 - 12<br />
yf = self.y + 25<br />
cercle(self.canev, xf, yf, 10)<br />
cercle(self.canev, xf-5, yf-3, 2)<br />
cercle(self.canev, xf+5, yf-3, 2)<br />
cercle(self.canev, xf, yf+5, 3)<br />
app = Application()<br />
app.mainloop()
Utilisation <strong>de</strong> threads <strong>en</strong> python<br />
On utilise le module threading qui permet <strong>de</strong> générer <strong>de</strong>s threads différ<strong>en</strong>ts, ce qui permet <strong>de</strong><br />
faire <strong>de</strong>s programmes multi-tâche. Voici un exemple basique d’utilisation :<br />
import threading<br />
<strong>de</strong>f affiche(nb, nom = ”):<br />
for i in range(nb): print nom, i<br />
a = threading.Thread(None, affiche, None, (200,), {’nom’:’thread a’})<br />
b = threading.Thread(None, affiche, None, (200,), {’nom’:’thread b’})<br />
a.start() b.start()<br />
L’objet Thread est généré sous la façon suivante : Thread(None, fonction, nom, args,<br />
dico). Ici, fonction représ<strong>en</strong>te l’appel à une fonction précé<strong>de</strong>m<strong>en</strong>t définie et on lui passe<br />
les argum<strong>en</strong>ts args (sous forme <strong>de</strong> liste) et dico (dictionnaire associant paramètre/valeur).<br />
On invoque <strong>en</strong>suite la métho<strong>de</strong> start() qui lance le thread <strong>en</strong> lui-même. En réalité cette métho<strong>de</strong><br />
invoque elle-même la métho<strong>de</strong> run, mais dans un thread lui-même différ<strong>en</strong>t du cours<br />
d’exécution actuel. La métho<strong>de</strong> run peut être surchargée, lorsqu’on crée une sous-classe <strong>de</strong><br />
Thread().<br />
Autre exemple où l’on voit les <strong>de</strong>ux threads <strong>en</strong> exécution :<br />
import threading, time<br />
<strong>de</strong>f timer():<br />
global tps<br />
while 1:<br />
time.sleep(1)<br />
tps=tps+1<br />
print(tps)<br />
<strong>de</strong>f inp():<br />
while 1:<br />
ch=input(’Entrez un mot’)<br />
print(’le mot est: ’+ch)<br />
tps = 0<br />
a = threading.Thread(None, timer, None, (), )<br />
b = threading.Thread(None, inp, None, (), )<br />
a.start()<br />
b.start()
Controle Continu n o 3<br />
Le but du projet est <strong>de</strong> créer un « pipotron », un générateur d’excuses aléatoires. Pour cela, une<br />
excuse est une phrase constituée <strong>de</strong> sujet + verbe + autre chose.<br />
Par exemple : « ma grand-mère était mala<strong>de</strong> », « le bus avait du retard », « le réveil n’a pas<br />
sonné » etc...<br />
Vous <strong>de</strong>vez :<br />
– construire une interface graphique cont<strong>en</strong>ant : trois zones <strong>de</strong> texte avec un bouton <strong>en</strong> <strong>de</strong>ssous<br />
<strong>de</strong> chaque zone : "sujet", "verbe", "complém<strong>en</strong>t" ; et <strong>de</strong>ux boutons supplém<strong>en</strong>taires à<br />
part : "pipotron" et quitter". Le bouton "quitter" sert bi<strong>en</strong> à quoi l’on p<strong>en</strong>se.<br />
– un click sur le bouton "sujet" choisit un sujet au hasard dans une liste <strong>de</strong> sujets, un click sur<br />
le bouton "verbe" choisit un verbe au hasard dans la liste <strong>de</strong>s verbes et <strong>en</strong>fin un click sur<br />
"complém<strong>en</strong>t" choisit un complém<strong>en</strong>t <strong>de</strong> phrase au hasard dans la liste correspondante.<br />
– lors <strong>de</strong> chaque click, la zone <strong>de</strong> texte correspondante est raffraichie, faisant apparaitre une<br />
nouvelle excuse. 1<br />
– un click sur "pipotron" ajoute la phrase complète obt<strong>en</strong>ue à un fichier sur le disque « pipotron.txt<br />
», constituant ainsi une base d’excuses.<br />
– dans l’idéal, la liste <strong>de</strong>s sujets, <strong>de</strong>s verbes et <strong>de</strong>s complém<strong>en</strong>ts <strong>de</strong>vrait être constituée <strong>de</strong> trois<br />
fichiers mais on se cont<strong>en</strong>tera <strong>de</strong> listes crées dans le script lui-même.<br />
1. la phrase obt<strong>en</strong>ue n’a pas forcém<strong>en</strong>t un s<strong>en</strong>s : « ma grand-mère n’a pas sonné » :)
Utilisation <strong>de</strong> threads <strong>en</strong> python — suite<br />
On utilise l’héritage pour re<strong>de</strong>finir <strong>de</strong>s threads. Le script précé<strong>de</strong>nt peut être donc réécrit ainsi :<br />
import threading, time<br />
class ThreadTimer(threading.Thread):<br />
<strong>de</strong>f __init__(self, <strong>de</strong>part):<br />
threading.Thread.__init__(self)<br />
self.tps = <strong>de</strong>part<br />
<strong>de</strong>f run(self):<br />
while 1:<br />
time.sleep(1)<br />
self.tps += 1<br />
print(self.tps)<br />
class ThreadInput(threading.Thread):<br />
<strong>de</strong>f __init__(self):<br />
threading.Thread.__init__(self)<br />
<strong>de</strong>f run(self):<br />
while 1:<br />
ch=input(’Entrez un mot ("fin" pour terminer)’)<br />
print(’le mot est: ’+ch)<br />
if ch == ’fin’:<br />
Th_Timer._stop()<br />
break<br />
Th_Timer = ThreadTimer(3) Th_Input = ThreadInput()<br />
Th_Timer.start()<br />
Th_Input.start()<br />
Exercices :<br />
1. Ecrire un système cli<strong>en</strong>t <strong>de</strong> messagerie <strong>en</strong> utilisant <strong>de</strong>ux threads : un pour l’émission et<br />
un pour la récéption <strong>de</strong> sorte à pouvoir faire les <strong>de</strong>ux <strong>de</strong> façon simultanée.<br />
2. Ecrire un serveur <strong>en</strong> utilisant là aussi plusieurs threads : chaque nouvelle connection<br />
d’un cli<strong>en</strong>t <strong>de</strong>vra générer un thread. Le serveur <strong>en</strong> tant que tel ne fait que retransmettre<br />
aux cli<strong>en</strong>ts ce qu’ils échang<strong>en</strong>t <strong>en</strong>tre eux.<br />
3. améliorer le serveur pour qu’il écrive qui est <strong>en</strong> train <strong>de</strong> parler ; améliorer le cli<strong>en</strong>t pour<br />
créer une interface graphique et év<strong>en</strong>tuellem<strong>en</strong>t, gérer les smileys.