22.02.2014 Views

Types de données en Python - LMPT

Types de données en Python - LMPT

Types de données en Python - LMPT

SHOW MORE
SHOW LESS

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.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!