Vous êtes sur la page 1sur 38

M.

AZILI POO

Implémenter la classe Rectangle avec 2 attributs : longueur & largeur

Ajouter les méthodes permettant de calculer le périmètre et la surface

class Rectangle:
    ''' Implémentation de la classe rectangle '''
    #constructeur
    def __init__(self,L,l):
        self.longueur=L
        self.largeur=l
    #calcul du périmetre
    def perimetre(self):
        ''' méthode permettant le calcul du périmetre du rectangle'''
        res=(self.longueur+ self.largeur)*2
        return res
    #calcul de la surface
    def surface(self):
       ''' méthode permettant le calcul de la surface du rectangle'''
       res=self.longueur*self.largeur
       return res

Effectuer un jeu d'essai

#Jeu d'essai
#création d'un objet rectangle (Instance d'objet)

R1=Rectangle(5,2)
print(R1) #Affiche adresse mémoire de l'objet
print("Longueur=",R1.longueur)
print("Largeur=",R1.largeur)
print("Perimetre=",R1.perimetre())
print("Surface=",R1.surface())

Ajouter une propriété / attribut de classe NbreRectangles qui donnent le nombre de rectangles crées

class Rectangle:
    nbreRectangles=0 #attribut de classe
    ''' Implémentation de la classe rectangle '''
    #constructeur
    def __init__(self,L,l):
        self.longueur=L
        self.largeur=l
        Rectangle.nbreRectangles=Rectangle.nbreRectangles+1

Faites un test

Réalisé par M.Elmostafa AZILI Page : 1/38


M.AZILI POO

R2=Rectangle(10,3)
print("Nombre de rectangles crées=",Rectangle.nbreRectangles)

Modifier le programme pour rendre la propriété /attribut la longueur private

 self.__longueur=L
en préfixant la propriété 2 underscores: __longueur

Tester :

Proposer une solution :

Écrire un getter et un setter pour la longueur

# getters & setters


    def getLongueur(self):
        return self.__longueur
    def setLongueur(self,valeur):
        self.__longueur=valeur

Test :

La classe complète
class Rectangle:
    nbreRectangles=0 #attribut de classe
    ''' Implémentation de la classe rectangle '''
    #constructeur
    def __init__(self,L,l):
        self.__longueur=L
        self.largeur=l
        Rectangle.nbreRectangles=Rectangle.nbreRectangles+1
   
    # getters & setters
    def getLongueur(self):
        return self.__longueur
    def setLongueur(self,valeur):
        self.__longueur=valeur
    #calcul du périmetre
    def perimetre(self):

Réalisé par M.Elmostafa AZILI Page : 2/38


M.AZILI POO

        ''' méthode permettant le calcul du périmetre du rectangle'''


        res=(self.__longueur+ self.largeur)*2
        return res
    #calcul de la surface
    def surface(self):
       ''' méthode permettant le calcul de la surface du rectangle'''
       res=self.__longueur*self.largeur
       return res

#Jeu d'essai
#création d'un objet rectangle (Instance d'objet)

R1=Rectangle(5,2)
print(R1) #Affiche adresse mémoire de l'objet
print("Longueur=",R1.getLongueur())
print("Largeur=",R1.largeur)
print("Perimetre=",R1.perimetre())
print("Surface=",R1.surface())
R2=Rectangle(10,3)
print("Nombre de rectangles crées=",Rectangle.nbreRectangles)

Ajouter une méthode nommée "Infos" qui affiche

******************

Ma longueur est : --

Ma largeur est : --

Ma surface est :---

*******************

#afficher les infos du rectangle


    def infos(self):
        print('***********************')
        print('* Ma longueur :',self.__longueur )
        print('* Ma largeur  :',self.largeur )
        print('* Ma surface  :',self.surface() )
        print('***********************')

Getter et Setter avec property()


Modifier le programme pour utiliser le setter et le getter de la longueur avec la fonction property()

# getter et setter de la longueur avec fonction property()


    longueur=property(getLongueur,setLongueur)

Réalisé par M.Elmostafa AZILI Page : 3/38


M.AZILI POO

Jeu d'essai

R1=Rectangle(5,2)

print("Longueur=",R1.longueur)
print("Largeur=",R1.largeur)
print("Perimetre=",R1.perimetre())
print("Surface=",R1.surface())
R1.longueur=55
print("Longueur=",R1.longueur)

Getter et Setter avec @property

class Rectangle:
 
    def __init__(self,Long,Larg):
        self.__longueur=Long
        self.largeur=Larg
       
    def perimetre(self):
        p=(self.__longueur+self.largeur)*2
        return p
    @property # implémenter le getter de la longueur
    def longueur(self):
        return self.__longueur
    @longueur.setter
    def longueur(self,valeur):
        self.__longueur=valeur

#essai
R1=Rectangle(5,2)
print(R1.longueur)
R1.longueur=99
print(R1.longueur)

Méthode de classe
1. Elle fonctionne à l'intérieur de la classe où elle a été créé et accessible soit via un objet
d'instance soit directement en utilisant le nom de la classe.
2. Une méthode de classe est décorée par @classmethod
3. Une méthode de classe possède un premier paramètre obligatoire nommé cls

Réalisé par M.Elmostafa AZILI Page : 4/38


M.AZILI POO

Pratique :

Créer une méthode de classe "nombreRectangles" qui permet d'afficher le nombre


d'objets rectangle crées

#@classmethod
    def nombreRectangles(cls):
        print("Nombre de rectangles crée :",Rectangle.NbreRectangles)
    #autre façon: déclaration de la méthode de classe
    #nombreRectangles= classmethod(nombreRectangles)

Destructeur

•Parmi les fonctions spéciales, il y a aussi le destructeur de la classe

•Il porte le nom suivant : __del__

•Cette procédure est appelée lorsque vous demander vous-même la destruction del R1 (par exple)
•automatiquement en sortant de la portée de l’objet
•Le destructeur est habituellement utilisé pour effectuer des actions avant la destruction de l’objet
(exple : écriture dans un fichier journal)
Pratique :

#redéfinition destructeur
    def __del__(self):
        f=open('d:/rectangleSupp.txt','a')
        chaine=str(self.__longueur)+";"+date.today().strftime("%d/%m/%Y")
        f.write(chaine)
        f.close()

Représentation d’un objet

•La fonction membre spéciale __repr__ retourne la chaîne de caractère qu’il faut afficher lorsque
l’on tape directement le nom de l’objet (plutôt pour le debug)

 La fonction membre spéciale __str__ retourne la chaîne de caractère qu’il faut afficher lorsque
l’on appelle la fonction print sur l’objet

Pratique :

Print(r1) == affiche rectangle de surface …

#Redéfinition de __str__
    def __str__(self):
        chaine='Rectangle de surface :'+ str(self.surface())

Réalisé par M.Elmostafa AZILI Page : 5/38


M.AZILI POO

        return chaine
    def __repr__(self):
        chaine='Rectangle de surface :'+ str(self.surface())
        return chaine

Héritage Simple
Implémentation du diagramme de classe suivant :

Pratique :

from datetime import date


# création de la classe Personne
class Personne:
   
    def __init__(self,Nom,pr=None,ad=None):
        self.__nom=Nom
        self.__prenom=pr
        self.__adresse=ad
    #getters & setters
    @property
    def nom(self):
        return self.__nom
    @nom.setter

Réalisé par M.Elmostafa AZILI Page : 6/38


M.AZILI POO

    def nom(self, value):


        self.__nom=value

    @property
    def prenom(self):
        return self.__prenom
    @prenom.setter
    def prenom(self, value):
        self.__prenom=value

    @property
    def adresse(self):
        return self.__adresse
    @adresse.setter
    def adresse(self, value):
        self.__adresse=value
   
    #redéfinition de __str__
    def __str__(self):
        #res="je suis la personne nommée :"+self.__nom+" "+self.__prenom
        res="personne !!!!!!!!!!!"
        return res
    #redefinition de del
    def __del__(self):
        f=open('d:/ObjSupp.txt','a')
        f.write(self.nom+";"+date.today().strftime("%d/%m/%Y"))
        f.close()

class Stagiaire(Personne): #la classe stagiaire hérite de la super classe


Personne
    #constructeur
    def __init__(self, Nom,NumIns, pr=None, ad=None,dIns=None):
        Personne.__init__(self,Nom,pr,ad)
        self.numeroInscr=NumIns
        self.dateInscr=dIns
       
    #affichage de stagiaire
    def __str__(self):
        #res=super().__str__()+" mais un stagiaire dont le num Ins
est :"+str(self.dateInscr)
        res="Stagiaire !!!!!"
        return res
   

#jeu d'essai
#p=Personne('azili','most')
#print(p)
d=date.today().strftime("%d/%m/%Y")
'''

Réalisé par M.Elmostafa AZILI Page : 7/38


M.AZILI POO

p=Personne("aa","aa","casa")
s=Stagiaire("hichy","A200",pr="Moha",ad=None,dIns=d)
print('--------------------')
print(p)
print(s)
print('----------------')
print("Nom stagiaire",s.nom)
print("PreNom stagiaire",s.prenom)
print("adresse stagiaire",s.adresse)
print("Num stagiaire",s.numeroInscr)
print("__________")
print(s)
'''
s=Stagiaire("hichy","A200",pr="Moha",ad=None,dIns=d)
del s
print('Fin')

Héritage Multiple

Implémentation :

class Personne:
    def __init__(self,nom,prenom,dateN=None):
        self.__Nom = nom
        self.__Prenom = prenom
        self.__DateNaissance = dateN

Réalisé par M.Elmostafa AZILI Page : 8/38


M.AZILI POO

        ###getter/setter nom
    @property
    def Nom(self):
        return self.__Nom
    @Nom.setter
    def nomsetter(self,valeur):
        self.__Nom = valeur  
        ####getter/setter prenom
    @property
    def Prenom(self):
        return self.__Prenom
    @Prenom.setter
    def Prenom(self,prenom):
        self.__prenom = prenom
        ####getter/setter datenaissance
    @property
    def DateNaissance(self):
        return self.__dateNaissance
    @DateNaissance.setter
    def DateNaissance(self,valeur):
        self.__DateNaissance = valeur
    ###method affiche
    def AfficheInfos(self):
        print("____________________")
        print("***** PRESONNE ****")
        print("____________________")
        print(f"le nom est : {self.nom}\nle prenom est : {self.prenom}\ndate
de naissance est : {self.DateNaissance}")

class Employe:
    def __init__(self,CodeEmploye,dateRecrutement=None,Salair=None):
        self.CodeEmploye = CodeEmploye
        self.DateRecrutement = dateRecrutement
        self.Salaire = Salair
    #method affiche
    def AfficheInfos(self):
        print("____________________")
        print("***** EMPLOYE ****")
        print("____________________")
        print(f"le code de l'employe est : {self.CodeEmploye}\nsont date de
recrutement est : {self.DateRecrutement}\nsont salair est : {self.Salaire}")

class Professeur(Personne,Employe):
    def __init__(self, Nom,
sp,CodeEmploye,Pren=None,DateRecrutement=None,Salair=None, dateN=None):
        Personne.__init__(self,Nom, Pren, dateN)
        Employe.__init__(self,CodeEmploye,DateRecrutement,Salair)
        self.Specialite = sp
   

Réalisé par M.Elmostafa AZILI Page : 9/38


M.AZILI POO

    def AfficheInfos(self):
        print("Professeur nommé:"+self.Nom+" son code:",self.CodeEmploye,"\n
Spécialité:",self.Specialite)
______________________________
print("je suis dans professeur")
        Personne.AfficherInfos(self)
        Employe.AfficherInfos(self)

# jeu essai
p = Professeur("azili","maths","C123")
print(p.Nom)
print(p.CodeEmploye)
p.AfficheInfos()

Surcharge des opérateurs


Une classe fraction
Python possède un module fractions dont les objets sont des nombres rationnels.
Exemple :
>>>from fractions import *
>>>q1=Fraction(1,2) # q1=1/2
>>> q1
Fraction(1, 2)
>>>q2=Fraction(3,2) # q2=3/2
>>> q2
Fraction(3, 2)
>>>q3=q1+q2
>>>q3
Fraction(2, 1)
Question. Définir une classe Rationnel qui représente les mêmes fonctionnalités que la classe
fractions

Travail Pratique :

class Rationnel:
    def __init__(self,bast,ma9am):    
        self.Bast=bast
        self.Ma9am=ma9am
        if self.Ma9am==0:
            raise ValueError("Ma9am doit etre different de zero")
           
    def __str__(self):
        value = str(self.Bast)+"/"+str(self.Ma9am)
        return value

Réalisé par M.Elmostafa AZILI Page : 10/38


M.AZILI POO

    #surcharge de l'operateur +
    def __add__(self,r):
        denominateur=self.Ma9am*r.Ma9am
        numerateur=self.Bast*r.Ma9am+self.Ma9am*r.Bast
        Res=Rationnel(numerateur,denominateur)
        return Res
    #Redifinir le produit *
    def __mul__(self,r):
        denominateur=self.Ma9am*r.Ma9am
        numerateur=self.Bast*r.Bast
        Resultat=Rationnel(numerateur,denominateur)
        return Resultat
   
    #Programme de Reduction    x=pgdc(numerateur,denominateur)
#jeu d'essai
a=Rationnel(6,5)
b=Rationnel(3,2)
print(a+b)
print(a*b)
print((a+b)*(a+b))

Travail personnel :

- Écrire fonction qui détermine le PGDC de 2 entiers


- Écrire fonction qui réduit une fraction

Surcharge des Méthodes (même nom de méthode mais signatures différentes

Réalisé par M.Elmostafa AZILI Page : 11/38


M.AZILI POO

Implémentation en Python (spécial)

Exemple :

calculSalaire=NbreHeures * 10 par defaut ======= calculSalaire()


calculSalaire= NbreHeures * TauxHoraire ======= calculSalaire(taux)
calculSalaire= NbreHeures * TauxHoraire + commission ========== calculSalaire(taux, comm)

Pratique :

class Employe:
    def __init__(self,mle,nom,nbrH):
        self.Matricule=mle
        self.Nom=nom
        self.NbreHeures=nbrH
        self.__salaire=None
    #surcharge de Méthode
    def calculSalaire(self,taux=None,comm=None):
        if (taux is None) and (comm is None):
            self.__salaire= self.NbreHeures*10
        elif (taux is not None) and (comm is None):
            self.__salaire= self.NbreHeures*taux
        elif (taux is not None) and (comm is not None):
            self.__salaire= self.NbreHeures*taux+comm
    # getters & setter du salaire
    def getSalaire(self):
        return self.__salaire
    def setSalaire(self,valeur):
        self.__salaire=valeur
    salaire=property(getSalaire,setSalaire)
   
#Jeu essai
e=Employe('M123','azili',100)
e.calculSalaire()
print(e.salaire)
e.calculSalaire(12)
print(e.salaire)
e.calculSalaire(12,800)
print(e.salaire)

Réalisé par M.Elmostafa AZILI Page : 12/38


M.AZILI POO

La comparaison entre objets


Comparer 2 employés pour pouvoir faire du tri dans une liste d'employés par exemple

class Employe:
    def __init__(self,mle,nom,nbrH):
        self.Matricule=mle
        self.Nom=nom
        self.NbreHeures=nbrH
        self.__salaire=None
    #surcharge de Méthode
    def calculSalaire(self,taux=None,comm=None):
        if (taux is None) and (comm is None):
            self.__salaire= self.NbreHeures*10
        elif (taux is not None) and (comm is None):
            self.__salaire= self.NbreHeures*taux
        elif (taux is not None) and (comm is not None):
            self.__salaire= self.NbreHeures*taux+comm
    # getters & setter du salaire
    def getSalaire(self):
        return self.__salaire
    def setSalaire(self,valeur):
        self.__salaire=valeur
    salaire=property(getSalaire,setSalaire)
    #surcharge de __eq__
    def __eq__(self, other):
        if isinstance(other, Employe):
            return (self.Matricule == other.Matricule) and
(self.Nom==other.Nom)
        else:
            return False
       
    def __gt__(self, other):
      # return comparison
      if isinstance(other, Employe):
            return self.Matricule>other.Matricule
   
    def __repr__(self):
        return self.Matricule
   
#Jeu essai
e1=Employe('M123','azili',100)
'''
e.calculSalaire()
print(e.salaire)
e.calculSalaire(12)
print(e.salaire)
e.calculSalaire(12,800)
print(e.salaire)

Réalisé par M.Elmostafa AZILI Page : 13/38


M.AZILI POO

'''
e2=Employe('M200','azili',100)
e3=Employe('M123','azil',100)
e4=Employe('M223','azil',100)
e5=Employe('M125','azil',100)
e6=Employe('M123','azil',100)
print(e1<e2)
print(e1==e3)
L=[e1,e2,e3,e4,e5]
print(L)
L.sort()
print(L)

Les méthodes magiques de comparaison :

Les classes abstraites en Python


Caractéristiques :

- Sont des classes qui ne peuvent pas être instanciées.


- Elles contiennent une ou plusieurs méthodes abstraites.
- C’est un modèle pour d’autres classes qui héritent un ensemble de méthodes et de
propriétés.
- N’a pas d’implémentation. Mais, une classe abstraite nécessite des sous-classes qui
fournissent des implémentations pour les méthodes abstraites.

Intérêt :

Réalisé par M.Elmostafa AZILI Page : 14/38


M.AZILI POO

- L'abstraction est l’un des concepts clés dans les langages de programmation orientée
objet
- Rendre le code compréhensible, structuré et propre

En Python, le module abc fournit les fonctionnalités pour définir et utiliser des classes abstraites.

Exemple Pratique :

Créer une super-classe appelée « Forme » et deux sous-classes – « Rectangle » et « Cercle ».


Les deux sous-classes ont des propriétés communes à partager, comme la couleur.
Il existe une différence majeure entre le rectangle et le cercle à savoir : la surface, la largeur, la
taille et le rayon …

Implémentation Pratique

from abc import ABC, abstractmethod


class Forme(ABC):
    #Attention!!! pas de constructeur, on l'instancie pas
    #proriété couleur
    @property
    @abstractmethod
    def Couleur(self):
        pass
   
    @abstractmethod
    def Surface(self):
        pass
    def __str__(self):
        return "C'est une forme "
#Implémentation de la classe Rectangle
class Rectangle(Forme):
    def __init__(self,L,l):

Réalisé par M.Elmostafa AZILI Page : 15/38


M.AZILI POO

        self.__longueur=L
        self.__largeur=l
        #self.Couleur=''
       
    #Implémentation de Couleur obligatoire
    @property                
    def Couleur(self):    
        return self.__couleur
    @Couleur.setter
    def Couleur(self,valeur):
        self.__couleur=valeur
   
    #Implémentation de surface est obligatoire, sinon error
    def Surface(self):
        return self.__longueur* self.__largeur
   
    def __str__(self):
        return super().__str__() +" Rectangle"
#Implémentation de la classe Cercle
class Cercle(Forme):
    def __init__(self,ray):
        self.__rayon=ray
    #Implémentation de surface est obligatoire, sinon error
    def Surface(self):
        return self.__rayon**2
    #Implémentation de Couleur obligatoire
    @property                
    def Couleur(self):    
        return self.__couleur
    @Couleur.setter
    def Couleur(self,valeur):
        self.__couleur=valeur

    def __str__(self):
        return super().__str__()+" Cercle"
       

#jeu d'essai
r=Rectangle(7,2)
print(r)
print(r.Surface())
r.Couleur="noire"
print(r.Couleur)

c=Cercle(5)
print(c)
print(c.Surface())
c.Couleur='Jaune'
print(c.Couleur)

Réalisé par M.Elmostafa AZILI Page : 16/38


M.AZILI POO

TP RECAPITULATIF

Énoncé :

M.AZILI TP P.O.O DEV 1A

TRAVAIL PRATIQUE RECAPITULATIF


Créer la classe Contrat :
Contrat
Numero
dateContrat
Montant payé

• Toutes les propriétés sont privées


• L’attribut paye a la valeur par défaut « False »
1. Écrire le constructeur dont les données obligatoires (Numero, Montant)
(dateContrat est par défaut la date du système s’elle est non fournie)
2. Écrire les getters (toutes les ptés)
3. Écrire les setters (pour ptés : dateContrat )
4. Redéfinir la méthode __str__ :
Contrat N° : …….
Date Contrat : …..
Montant : …..

5. Redéfinir la méthode __repr__ Pour gérer le tri des contrats :


Critères de comparaison :
2 contrats sont comparés selon leur montants
6. Ajouter une méthode
Negocier(dateNegoce, newMontant, avis) qui permet de renégocier le contrat en modifiant sa
date et son montant si l’avis est « OK »
7. Écrire une méthode dont l’entête reglement ( effectue)
8. Ajouter les attributs de classe NbreContrats et CA (total de tous les montants de tous les
contrats)
9. Ajouter une méthode de classe CARealise() qui retourne le total de tous les montants de tous
les contrats
10. Jeu d’essai :
Afficher un menu

Réalisé par M.Elmostafa AZILI Page : 17/38


M.AZILI POO

1 : Nouveau contrat (crée un contrat et l’ajoute dans une liste)


2 : Liste des contrats
3 : Liste des contrats triés par ordre décroissant
4 : Liste des contrats non encore réglés (Écrire une fonction pour cette option)
5 : Négocier un contrat
6 : Enregistrer Liste Contrats
(dans un fichier texte sur une ligne. Les attributs doivent être séparés par le
caractère /) 7 : Quitter

Surcharger l’opérateur + afin de réaliser l’opération addition de 2 contrats selon la règle


suivante :
Contrat1 + contrat2= contrat résultat avec un numéro (numero Contrat1 + numero
Contrat2) Et Montant Contrat Résultat= montant contrat 1+ montant contrat 2)

M.Elmostafa AZILI Page 1/1

Réalisation Type :

from datetime import *


import os
import csv #pour manipulation des fichiers CSV
#affichage du Menu
def Menu():
    print('***************************************')
    print('* 1- Nouveau Contrat                  *')
    print('* 2- Liste Contrats                   *')
    print('* 3- Liste Contrats triés             *')
    print('* 4- Liste Contrats Non Réglés        *')
    print('* 5- Négocier Contrat                 *')
    print('* 6- régler Contrat                   *')
    print('* 7- Enregistrer Contrat              *')
    print('* 8- Quitter                          *')
    print('* Votre Choix :                       *')
    #print('***************************************\n')
class Contrat:
    #Ptés de Classe
    nombreContrats=0
    chiffreAffaire=0
    L=[] #liste des contrats
    def __init__(self,num,Mt,p=False,DateContrat=date.strftime(date.today(),'%d/
%m/%y')):
        self.__numero=num
        self.__dateContrat=DateContrat
        self.__montant=Mt
        self.__paye=p
        Contrat.nombreContrats +=1

Réalisé par M.Elmostafa AZILI Page : 18/38


M.AZILI POO

        Contrat.L.append(self)
        Contrat.chiffreAffaire +=float(self.__montant)
    #les getters de toutes les ptés
    @property
    def numero(self):
        return self.__numero
    @property
    def dateContrat(self):
        return self.__dateContrat
    @property
    def montant(self):
        return self.__montant
    @property
    def paye(self):
        return self.__paye
    #setter de la date contrat
    @dateContrat.setter
    def dateContrat(self,valeur):
        self.__dateContrat=valeur
    #redéfinition de __str__
    def __str__(self):
        chaine='*-------------------------* \n'+\
            '* Contrat N°: '+str(self.__numero)+'\n' +\
            '* Date Contrat :'+ str(self.__dateContrat) +'\n'+\
            '* Montant : '+str(self.__montant)+'\n'+\
            '*-----------------------------*'
        return chaine
    def __repr__(self):
        chaine="("+str(self.__numero)+","+str(self.montant)+")"
        return chaine
    #redéfinir __gt__
    def __gt__(self,autre):
        if isinstance(autre,Contrat):
            return float(self.__montant)>float(autre.__montant)
    def __eq__(self,autre):
        if isinstance(autre,Contrat):
            return float(self.__montant)==float(autre.__montant)
    #Méthode Négocier
    def Negocier(self,dateNegoce, newMontant, avis):
        if str(avis).upper()=='OK':
            self.__montant=newMontant
            self.__dateContrat=dateNegoce
    def reglement ( self,effectue):
        if effectue in (True,False):
            self.__paye=effectue
    #Méthode de classe
    @classmethod
    def CaRealise(cls):
        s=0

Réalisé par M.Elmostafa AZILI Page : 19/38


M.AZILI POO

        for elt in Contrat.L:


            if isinstance(elt,Contrat):
                s=s+float(elt.__montant)
        return s
    @classmethod
    def ContratNonRegles(cls):
        ''' récupere les contarts non payés dans une liste'''
        LnonPayes=[]
        for elt in Contrat.L:
            if isinstance(elt,Contrat):
                if elt.__paye==False:
                    LnonPayes.append(elt)
        return LnonPayes
    @classmethod
    def rechercher(cls,Numc):
        '''
        retourne un contrat dont on connait le numero.
        si introuvable retourne None
        '''
        res=None
        for elt in Contrat.L:
            if  isinstance(elt,Contrat):
                if elt.__numero==Numc:
                    res= elt
                    break
        return res
               
    @classmethod
    def enregistrer(cls,chemin):
        '''
        enregistre la liste des contrats(num,montant,date) dans un fichier
        '''
        f=open(chemin,'a')
        writer=csv.writer(f,delimiter='/')
        for elt in Contrat.L:
            if isinstance(elt,Contrat):
                writer.writerow([elt.__numero,elt.__montant])
        f.close()

#jeu d'essai1

while(True):
    os.system("cls")
    Menu()
    choix=int(input())
    if choix==1:
        #nouveau contrat
        Numero=input('Numero du Contrat :')
        Mt=input('Montant :')

Réalisé par M.Elmostafa AZILI Page : 20/38


M.AZILI POO

        c=Contrat(Numero,Mt)
    elif choix==2:
        print(Contrat.L)
        input('Tappez Entrer pour Continuer')
    elif choix==3:
        x=sorted(Contrat.L,reverse=True)
        print(x)
        input('Tappez Entrer pour Continuer')
    elif choix==4:
        print(Contrat.ContratNonRegles())
        input('Tappez Entrer pour Continuer')
    elif choix==5:
        N=input('N° Contrat Négocier ?')
        cRech=Contrat.rechercher(N)
        if cRech is not None:
            D=input('Date de contrat:')
            M=float(input('Montant du contrat:'))
            A=input('Votre Avis:')
            cRech.Negocier(D,M,A)
        else:
            print('Contrat introuvable')
        input('Tappez Entrer pour Continuer')
    elif choix==6:
        N=input('N° Contrat à régler ?')
        cRech=Contrat.rechercher(N)
        if cRech is not None:
            cRech.reglement(True)
        else:
            print('Contrat introuvable')
        input('Tappez Entrer pour Continuer')
    elif choix==7:
        Contrat.enregistrer('contrats.txt')
        input('Enregistrement terminé! Tappez Entrer pour Continuer')
    elif choix==8:
        break

Les Interfaces : Concept O.O


Introduction
De manière similaire aux classes abstraites ou concrètes (les classes non abstraites), une interface
décrit des objets mais uniquement en termes de méthodes abstraites. Une interface ne peut
contenir ni attribut, ni méthode implémentée. Le terme d’héritage n’est pas utilisé entre classes et
interfaces : on dit qu’une classe implémente une interface. Lorsqu’une classe implémente une
interface, elle doit redéfinir toutes ses méthodes abstraites ou bien être abstraite. Une interface peut
hériter d’une autre interface.

Réalisé par M.Elmostafa AZILI Page : 21/38


M.AZILI POO

L’interface est la vue externe d’un objet, elle définit les services accessibles (attributs et méthodes)
aux utilisateurs de l’objet

Intérêt 
Tirer profit du polymorphisme avec des instances dont les classes ne font pas partie de la même
hiérarchie d’héritage
À retenir :
 Toutes les méthodes d’une interface sont abstraites.
 Les interfaces ne sont pas instanciables

Cas PYTHON :

L'approche de Python en matière de conception d'interface est quelque peu différente par rapport
à des langages tels que  Java  , Go et  C++  .  Ces langages ont tous un  interface mot-clé,
contrairement à Python.  Python s'écarte encore des autres langages sur un autre aspect. 

Il n'est pas nécessaire que la classe qui implémente l'interface définisse toutes les méthodes
abstraites de l'interface.

Exemple Pratique :

On souhaite caractériser la fonctionnalité de comparaison qui est commune à tous les objets qui
ont une relation d’ordre ( < , = , >), on peut définir l’interface Comparable.

#création de l'interface IComparable


from abc import *
class IComparable:
    @abstractmethod
    def CompareTo(self, objOther):
        pass
    @abstractmethod
    def xx(self):
        pass
# création de la classe Personne qui implémente l'interface IComparable
class Personne(IComparable):
    def __init__(self,nom,age) :
        self.Nom=nom
        self.Age=age

Réalisé par M.Elmostafa AZILI Page : 22/38


M.AZILI POO

    #implémentation de la méthode compareTo


    def CompareTo(self, objOther):
        return self.Age==objOther.Age
# création de la classe Outil qui implémente l'interface IComparable
class Outil(IComparable):
    def __init__(self,long) :
        self.Longueur=long
       
    #implémentation de la méthode compareTo
    def CompareTo(self, objOther):
        return self.Longueur==objOther.Longueur

#jeu d'essai
p1=Personne('aa',60)
p2=Personne('aa',50)
if p1.CompareTo(p2):
    print('personnes ave mm age')
else:
    print('personnes ave différents ages')

o1=Outil(60)
o2=Outil(60)
if o1.CompareTo(o2):
    print('Outils ave mm longueur')
else:
    print('Outils ave différents longueurs')

La Gestion des Erreurs


Types d’erreurs :

 Erreur de syntaxe
 Exception 

x=int(input('x ='))
y=int(input('y ='))
q=x/y
print('x/y=',q)

Réalisé par M.Elmostafa AZILI Page : 23/38


M.AZILI POO

Gestion des Erreurs

try:
    x=int(input('nbre:'))
    print('x=',x)
    print('x/0:',x/0)
 
except ValueError:
        print('il faut tapper un entier')
except ZeroDivisionError:
        print('Division par 0 impossible')

print('Suite du programme !!!')


               
   

bloc finally
try:
    x=int(input('nbre:'))
    print('x=',x)
    print('x/0:',x/0)
 
except ValueError:
        print('il faut tapper un entier')
except ZeroDivisionError:
        print('Division par 0 impossible')

print('Suite du programme !!!')


               
   

try:
    x=int(input('Tappez entier :'))
    y=1/x
    print('x=',x)
except Exception as ex:
    print(ex)

Réalisé par M.Elmostafa AZILI Page : 24/38


M.AZILI POO

Exceptions & Objets

Exemple Pratique :

class Stagiaire :
    def __init__(self,n,mat,moy):
        #Controler le nom chaine de caracteres
        assert isinstance(n,str),"Error Type Du Nom"
        #Controler la moyenne

Réalisé par M.Elmostafa AZILI Page : 25/38


M.AZILI POO

        assert isinstance(float(moy),float) and moy in range(21),"Error


Moyenne"

        self.Nom = n
        self.Moyenne = moy
        self.Matricule = mat
   
    def __str__(self) :
        res = "Nom : " + str(self.Nom) + "\nMatricule : " +
str(self.Matricule) + "\nMoyenne : " + str(self.Moyenne)
        return res

#Jeu d'essai
try :
    S = Stagiaire(54, "M100",25)
    print(S)
except AssertionError as e :
    print(e)

Collections – namedtuple

Les namedtuple attribuent une signification à chaque position dans un tuple et permettent un
code plus lisible et auto-documenté. 

Nous les utiliserons pour créer des tuples avec des champs nommés

Ils peuvent être utilisés partout où des tuples réguliers sont utilisés, et ils ajoutent la possibilité
d'accéder aux champs par nom au lieu de l'index de position.

collections. namedtuple ( typename , field_names , * , rename = 
False , defaults = None , module = None ) 
Les noms_champs sont une séquence de chaînes telles que :
Alternativement, field_names peut être une seule chaîne avec chaque nom de champ séparé
par des espaces et/ou des virgules, par exemple  'x y' or 'x, y'.

Les tuples sont utilisés pour représenter des données en colonnes. Exemple :

('A123','azili','Mostafa')

Réalisé par M.Elmostafa AZILI Page : 26/38


M.AZILI POO

Ce tuple n’indique pas clairement ce que représente chacun de ses champs. En réalité,
l’élément 0 est un matricule, l’élément 1 est un nom, et l’élément 2 est le prénom d'une personne.

Donc on utilisera namedtuple du module collections pour générer une classe qui nomme
clairement chaque élément du tuple de personne :

from collections import namedtuple


Personne = namedtuple("Stagiaire", ["matricule", "nom", "prenom"])

Stagiaire est le nom de la nouvelle classe


La fonction namedtuple( ) renvoie une classe

Utilisons la classe Personne pour représenter le tuple de


Stagiaire ('A123','azili','Mostafa')

Exemple Pratique :

Collections - deque
La classe deque du module collections est un objet de type liste qui permet d'insérer des éléments au
début ou a la fin d'une séquence avec une performance a temps constant (O(1)) même si cette liste a
des milliers ou des millions d'éléments.
Exemple Pratique :

from collections import deque


queu=deque(['aa','x',5,'z'])
queu.append('azili')
queu.appendleft('azili')
print(queu)

Travail Personnel :

Tester les méthodes : pop(), popleft() et clear()

Collections – counter
Sous classe de dict qui permet de compter des objets hachables.

En fait c’est un dictionnaire avec comme clef les éléments et comme valeurs leur nombre.
class collections.Counter([iterable-or-mapping]) ceci retourne un Counter. L’argument permet de
spécifier ce que l’on veut mettre dedans et qui doit être compte.
Exemple Pratique :
from collections import Counter #Retourne un dico
c=Counter() #compteur vide
print('conteur vide :',c)
c=Counter('omo matio')  
print(c)
monCompteur=Counter([1,'a','b',1,5,1,5,5,'a'])

Réalisé par M.Elmostafa AZILI Page : 27/38


M.AZILI POO

print('Le compteur:',monCompteur)
print('le nombre de a:',monCompteur['a'])
print('le nombre de 5:',monCompteur[5])
# Parcours des clefs du dico retourné par le Counter et affichage
personnalisé
for k in monCompteur.keys():
    print(k,'----',monCompteur[k])
#les items renvoyés par le Counter()
for elt in monCompteur.items():
    print(elt)

#addition de Counters
print('---- addition de counters ----')
c1=Counter({'A':2,'B':5})
c2=Counter({'A':2,'C':5,'D':9})
c3=c1+c2
print(c3)

Travail personnel :
Vérifier la différence, l’Intersection et l’Union de 2 Counter

Collections - ChainMap
Python contient un conteneur appelé « ChainMap » qui encapsule de nombreux dictionnaires dans
une seule unité. ChainMap est membre du module « collections ».

Exemples Pratiques :
from collections import ChainMap
# programme démostration de ChainMap
# ChainMap retourne une nouvelle ChainMap.
d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'd': 4}
d3 = {'e': 5, 'f': 6}
   
# Defining the chainmap
z = ChainMap(d1, d2, d3)
print('type de c:',type(z))
print(z)
for k, v in z.items(): #parcourir les éléments de z
    print(k, v)

# ------diverses opérations sur ChainMap -----


# printing chainMap using maps
print ("All the ChainMap contents are : ")
print (z.maps)
print('------------')  
# printing keys using keys()
print ("All keys of ChainMap are : ")
print (list(z.keys()))

Réalisé par M.Elmostafa AZILI Page : 28/38


M.AZILI POO

print('------------')  
# printing values using values()
print ("All values of ChainMap are : ")
print (list(z.values()))
print('------------')  
# ajoute un nouveau dictionnaire au début de la ChainMap.
dicNew = { 'xx' : 5 }
z=z.new_child(dicNew)
 
# printing chainMap using map
print ("Displaying new ChainMap z: ")
print (z.maps)
print('------------')  
# inverser l'ordre relatif des dictionnaires dans le ChainMap.
z.maps=reversed(z.maps)
print (list(z.maps))

LES FICHIERS JSON

Java Script Object Notation


JSON est une syntaxe pour stocker et échanger les données.

- Syntaxe :
Les données JSON est écrit sous forme de paires nom / valeur.

Une paire nom / valeur est constituée d'un nom de champ (entre
guillemets), suivi de deux points, suivi d'une valeur :

Exemples :

"nom":"Houssam"

"age": 22

Le format JSON est presque identique à des objets JavaScript.

Réalisé par M.Elmostafa AZILI Page : 29/38


M.AZILI POO

Exemples :

{"nom":"Houssam"}

– Type de valeurs :
En JSON, les valeurs doivent être l’un des types de données suivants :

• String
• Number
• Objet (objet JSON)
• Array
• Boolean
• Null
String { "nom":"Houssam" }
Number { "age":22 }
Object { "employee":{
"nom":"Houssam",
"age":30,
"ville":"Media"
}
}
Array { "employees":[ "Houssam", "Mostafa", "Mehdi" ] }
Boolean { "vendu":false }
Null { "alias":null }

Lire un fichier JSON : Utiliser la fonction json.loads(….)


import json
#ouvrir le fichier exemple.json en lecture
f = open ('exemple.json', "r" )
#décoder le texte et le transformer en dictionnaire.
d=json.loads(f.read())
print(d)
f.close()

le fichier exemple.Json :
[
{
"prenom": "Mostafa",

Réalisé par M.Elmostafa AZILI Page : 30/38


M.AZILI POO

"nom": "AZILI",
"fils": [
{
"nomFils": "Othmane",
"age": "16"
},
{
"nomFils": "Youssef",
"age": "13"
}
]
},
{
"prenom": "ALI",
"nom": "MESSI",
"fils": [
{
"nomFils": "ahmed",
"age": "1"
}
]
}

Écrire dans un fichier JSON : Utiliser la fonction json.dumps(…)


#Ecriture d'un dict ou list dans un fichier monFichier.json en lecture
monDico={"Ref":"P123","Nom":"Tablette","Pu":"2000"}
l=[1,2,5,2]
f = open ('articleJson.json', "w" )
f.write(json.dumps(monDico))
f.write('\n')
f.write(json.dumps(l))
f.close()
print('fichier Json crée!!!!')

Travail Pratique :
Créer la classe stagiaire (nom ,age)

Écrire une fonction LireJson(chemin) : qui permet de lire un fichier représentant des stagiaires sous
format Json et afficher la liste de leurs noms

Réalisé par M.Elmostafa AZILI Page : 31/38


M.AZILI POO

Écrire une fonction EcrireJson(chemin,dictionnary) qui écrit une liste de stagiaires dans un fichier
Json.

Solution Proposée :

import json
class Stagiaire:
    def __init__(self,n,a):
        self.nom=n
        self.age=a
   
def LireJson(chemin):
    ''' lit un fichier Json et le place ds un dict qu'elle retourne'''
    #overture du fichier
    f=open(chemin,'r')
    #lecture du fichier Json et son chargement ds un dict
    dictStagiaire=json.loads(f.read())
    f.close()
    return dictStagiaire
def EcrireJson(chemin,dictionnary):
    #overture du fichier
    f=open(chemin,'a')
    #Ecriture dans fichier Json
    f.write(json.dumps(dictionnary))
    f.close()
#prgm ppl ****
'''
d=LireJson('Stagiaires.json')
print(d)
#affichage de la liste des noms de stagiaires
print('---- Liste des stagiaires -----')
for elt in d:
   print('\t',elt["nom"])
'''
objS1=Stagiaire('Reda',20)
objS2=Stagiaire('Med',30)
objS3=Stagiaire('Said',16)
d=[{"nom":objS1.nom,"age":objS1.age},
    {"nom":objS2.nom,"age":objS2.age},
        {"nom":objS3.nom,"age":objS3.age}]
EcrireJson('gpeDev103.json',d)
print('Enregistrement effectué !!')

Réalisé par M.Elmostafa AZILI Page : 32/38


M.AZILI POO

Les Expression Régulières


Permettent de respecter des formats de chaines bien particulières telle qu’une adresse mail

Les Règles :

On utilise des symboles qui ont une signification:


.^$*+?{}[]\|()
. Le point correspond à n'importe quel caractère.
^ Indique un commencement de segment mais signifie aussi "contraire de"
$ Fin de segment
[xy] Une liste de segment possibble. Exemple [abc] équivaut à : a, b ou c
(x|y) Indique un choix multiple type (ps|ump) équivaut à "ps" OU "UMP"
\d le segment est composé uniquement de chiffre, ce qui équivaut à [0-9].
\D le segment n'est pas composé de chiffre, ce qui équivaut à [^0-9].
\s Un espace, ce qui équivaut à [ \t\n\r\f\v].
\S Pas d'espace, ce qui équivaut à [^ \t\n\r\f\v].
\w Présence alphanumérique, ce qui équivaut à [a-zA-Z0-9_].
\W Pas de présence alphanumérique [^a-zA-Z0-9_].
\ Est un caractère d'échappement
Il est possible de d'imposer le nombre d'occurrences avec la syntaxe suivante:
A{2} : on attend à ce que la lettre A (en majuscule) se répète 2 fois consécutives.
BA{1,9} : on attend à ce que le segment BA se répète de 1 à 9 fois consécutives.
BRA{,10} : on attend à ce que le segment BRA ne soit pas présent du tout ou présent jusqu'à 10
fois consécutives.
VO{1,} : on attend à ce que le segment VO soit présent au mois une fois.
Symbole Nb Caractères attendus Exemple Cas possibles
? 0 ou 1 GR (.)? S GRS, GR O S, GR I S, GR A S
+ 1 ou plus GR (.)+ S GR O S, GR I S, GR A S
* 0, 1 ou plus GR (.)* S GRS,GRO O ,GR III S,GR Olivier S

Exemple Pratique (Application des règles des expressions régulières en Python):

import re #regular expression


#code qui est composé de 4 chiffres

formatCode=r'^[0-9]{4}$'
x='1247'

if re.match(formatCode,x):

Réalisé par M.Elmostafa AZILI Page : 33/38


M.AZILI POO

    print('format correct')
else:
   print('format incorrect')

#code composé de 2 Lettres suivi par 3 Chiffres

formatCode=r'^[a-zA-Z]{1,2}[0-9]{3}$'
x='1aX23'

if re.match(formatCode,x):
    print('format correct')
else:
   print('format incorrect')

#format de numero tel : (06) 11.11.11.11


formatCode=r'^\(06\) [0-9]{2}\.[0-9]{2}\.[0-9]{2}\.[0-9]{2}$'
x='(06) 11.11.11.11'

if re.match(formatCode,x):
    print('format correct')
else:
   print('format incorrect')

#xx=tuple(re.findall(r'\d{4}$|\d{3}','0123456789'))
#print(xx)
#xx=re.search(r'(ab)','01ab3456ab9')
#print(xx)

#format d'une adresse mail : chaine qui commence par une lettre
# @chaine qui commence par une lettre.2 à 4 char. exple: xx_x11x@xaa1.ma

emailPattern= r'^[a-zA-Z]\w*@[a-zA-Z]\w*\.[a-zA-Z]{2,4}$'
x='a_azili@mail.ma'

if re.match(emailPattern,x):
    print('format correct')
else:
   print('format incorrect')

#format du code d'une facture client:


#commence par le mot 'Fact'suivi d'un numero de 4 à 5 chiffres et un _ suivi de
'casa'ou 'Hcasa'
#exp: Fact1234_casa
facturePattern=r"^Fact\d{4,5}_(casa|Hcasa)$"
x='Fact1345_Hcasa'

if re.match(facturePattern,x):

Réalisé par M.Elmostafa AZILI Page : 34/38


M.AZILI POO

    print('format correct')
else:
   print('format incorrect')

Correction Examen Passage 2019


Enoncé
Proposition de solution
import re
import csv
class Stagiaire:
    def __init__(self, ni=None,Nom=None):
        #controler avec assert la variable ni
        assert re.match(r"^[0-9]{12}$",str(ni)),"Numero Inscription doit
etre composé de 12 chiffres"
        self.numeroIns=ni
        self.nom=Nom
    def __eq__(self,otherObj):
        if isinstance(otherObj,Stagiaire):
            return self.numeroIns==otherObj.numeroIns
    def __str__(self):
        chaine="Stagiaire "+str(self.numeroIns)+":"+str(self.nom)
        return chaine
    # redéfinition du __repr__ pour le print(de la liste des stagiaire)  
    def __repr__(self):
        return str(self.numeroIns)
#Implémentation de la classe Club
class Club:
    def __init__(self):
        self.membres=[]
        self.NombreMembres=0

    def indiceDe(self,objStagiaire):
        if isinstance(objStagiaire,Stagiaire):
            indice=-1
            for i in range(len(self.membres)):
                if objStagiaire==self.membres[i]:
                    indice=i
                    break
        return indice
    def ajouter(self,membre):
        if isinstance(membre,Stagiaire):
            res=False
            if membre not in self.membres:
                self.membres.append(membre)
                self.NombreMembres+=1

Réalisé par M.Elmostafa AZILI Page : 35/38


M.AZILI POO

                res=True
        return res
    # attention!!! Implémentation de la surcharge de méthodes en python
    #Polymorphisme
    def supprimer(self, numI=None,membre=None):
        if numI!=None and membre is None:
            trouve=False
            for m in self.membres:
                if m.numeroIns==numI:
                    self.membres.remove(m)
                    self.NombreMembres-=1
                    trouve=True
                    print('Suppression effectuée')
                    break
            if trouve==False:
                raise TypeError('Element_Introuvable')
       
        elif numI is None and membre!=None:
            if isinstance(membre,Stagiaire):
                if membre in self.membres:
                    self.membres.remove(membre)
                    self.NombreMembres-=1
                    print('Suppression effectuée')
                else:
                    raise TypeError('Element_Introuvable')
        else:
            raise TypeError('un paramètre requis')
    # redéfinition du __str__ pour le print(club)
    def __str__(self):
        chaine="CLub de Lecture \n" +\
        "Membres ("+str(self.NombreMembres)+") \n"
        chaineStagiaires=''
        for elt in self.membres:
            chaineStagiaires=chaineStagiaires+elt.__str__()    
        return chaine+"\n"+chaineStagiaires
    def enregistrer(self, chemin):
        f=open(chemin,'w')
        leWriter=csv.writer(f,delimiter=";")
        for elt in self.membres:
            leWriter.writerow([elt.__str__()])
        f.close()

#jeu essai
#créer 3 stagiaires
s1=Stagiaire(111111111111,'hichy')
s2=Stagiaire(111111111119,'anis')
s3=Stagiaire(111111111111,'said')
#affichage d'un stagiaire
print(s1)

Réalisé par M.Elmostafa AZILI Page : 36/38


M.AZILI POO

# création d'un club


c=Club()
# ajouter les 3 stagiaires au club
if c.ajouter(s1):
    print('ajout effectué')
else:
    print('Stagiaire existe déja')

if c.ajouter(s2):
    print('ajout effectué')
else:
    print('Stagiaire existe déja')

if c.ajouter(s3):
    print('ajout effectué')
else:
    print('Stagiaire existe déja')
# afficher la liste des membres du club

print(c.membres)
c.enregistrer('d:/club.txt')
c.supprimer(membre=c.membres[0])
print(c.membres)
   

Réalisé par M.Elmostafa AZILI Page : 37/38


M.AZILI POO

Réalisé par M.Elmostafa AZILI Page : 38/38

Vous aimerez peut-être aussi