Q1. Définir une classe Satellite qui permette d'instancier des objets simulant des satellites artificiels lancés dans l'espace, autour de la terre. Le constructeur de cette classe initialisera les attributs d'instance ci-dessous :
L'attribut nom de type str, représentant le nom du satellite
L'attribut masse de type int ou float, représentant la masse du satellite en $kg$, ayant pour valeur par défaut 250
L'attribut vitesse de type int ou float, représentant la vitesse du satellite en $m.s^{-1}$, ayant pour valeur par défaut 0
Q2. Instancier les trois satellites suivants puis vérifier en console les valeurs de leurs attributs :
Satellite s1 portant le nom de "Sirius"
Satellite s2 ayant pour nom "Arcturus" et pour masse 100 $kg$
Satellite s3 ayant pour nom "Procyon", pour masse 150 $kg$ et pour vitesse 20 $m.s^{-1}$
Q3. Créer les trois méthodes infos, __repr__ et __str__ pour qu'elles produisent les affichages donnés en exemple.
Exemple :
>>>s3.infos()'Le satellite Procyon (masse : 150 kg) a une vitesse de 20 m/s'>>>s3Nom:ProcyonMasse:150kgVitesse:20m/s>>>print(s3)SatelliteProcyon:|Masse->150kg|Vitesse->20m/s
Q4. Tester les deux dernières instructions de la question 3 :
En commentant la méthode spéciale __repr__
En commentant la méthode spéciale __str__
On expliquera dans chaque cas les affichages obtenus.
Q5. On rappelle que l'énergie cinétique se calcule à l'aide de la formule : $E_{c} = \frac{1}{2} m v^{2}$
Définir une méthode energie qui renvoie la valeur de l'énergie cinétique de l'instance.
Q6. On rappelle que la variation $\Delta v$ subie par un objet de masse $m$ soumis à l'action d'une force $F$ pendant un temps $t$ vaut : $\Delta v = \frac{F \times t}{m}$. Par exemple, un satellite de 300 $kg$ qui subit une force de 600 $N$ pendant 10 secondes voit sa vitesse augmenter (ou diminuer) de 20 $m.s^{-1}$.
Définir une méthode impulsion qui :
Prend en paramètre la valeur de la force, force, en $N$ et la durée d'application de cette force, duree, en $s$
Modifie la vitesse du satellite en conséquence
In [ ]:
classSatellite:def__init__(self,nom,masse:int=250,vitesse:int=0):self.nom=nomself.masse=masseself.vitesse=vitessedefinfos(self)->str:returnf'Le satellite {self.nom} (masse : {self.masse} kg) a une vitesse de {self.vitesse} m/s'def__repr__(self)->str:returnf'Nom : {self.nom}\nMasse : {self.masse} kg\nVitesse : {self.vitesse} m/s'def__str__(self)->str:returnf'Satellite {self.nom} : | Masse -> {self.masse} kg | Vitesse -> {self.vitesse} m/s'defenergie(self)->int:returnint((self.masse*self.vitesse**2)/2)defimpulsion(self,force:int,duree:int):self.vitesse+=int((force*duree)/self.masse)
Q1. Définir une classe CompteBancaire permettant d'instancier des objets représentant des comptes.
Le constructeur de cette classe initialisera deux attributs :
L'attribut numero, de type str, représentant le numéro de compte
L'attribut solde, de type float
Q2. Créer les méthodes credit et debit permettant respectivement d'ajouter et de retirer une certaine somme. Ces méthodes possèderont deux paramètres :
Le paramètre montant, de type float, correspondant à la somme à ajouter ou à débiter
Le paramètre description, de type str, qui précise le type d'opération.
Ce paramètre sera initialisé par défaut à "Type de crédit/débit non précisé"
Q3. Créer la méthode info_solde qui renvoie la chaîne de caractères suivante :
'Le solde du compte n°{numéro du compte} est de {valeur du solde} €.'
Q4. Dans cette question, on souhaite générer un fichier au format csv représentant un relevé du compte.
Ce fichier devra posséder les quatre champs suivants : "Description", "Crédit", "Débit" et "Solde".
Créer un nouvel attribut d'instance histo et l'initialiser à la valeur 'Solde initial,,,{valeur du solde}\n'.
Compléter les méthodes credit et debit pour ajouter l'enregistrement correspondant à chaque opération.
Créer la méthode d'instance genere_historique qui crée le fichier releve_{noméro du compte}.csv comme indiqué dans l'exemple ci-dessous.
classCompteBancaire:def__init__(self,numero:int,solde:float):self.numero=numeroself.solde=soldeself.histo=f'Solde initial,,,{self.solde:.2f}\n'defcredit(self,montant:float,description:str='Type de crédit non précisé'):self.solde+=montantself.histo+=f'{description},{montant:.2f},,\n'defdebit(self,montant:float,description:str='Type de débit non précisé'):self.solde-=montantself.histo+=f'{description},,{montant:.2f},\n'definfo_solde(self)->str:returnf'Le solde du compte n°{self.numero} est de {self.solde:.2f} €.'defgenere_historique(self):withopen('releve_'+self.numero+'.csv','w',encoding='utf-8')asf:contenu='Description,Crédit,Débit,Solde\n'contenu+=self.histocontenu+=f'Nouveau solde,,,{self.solde:.2f}\n'f.write(contenu)
Exercice 3 : Tableau périodique des éléments - Dictionnaires et classes¶
Dans cet exercice, nous allons utiliser les classes pour représenter les éléments du tableau de Mendeleiev et le tableau périodique lui-même.
On placera le fichier tableau_mendeleiev.csv dans le répertoire courant.
Q2. Créer la classe Element permettant d'instancier un élément du tableau périodique.
Le constructeur de cette classe initialisera les attributs d'instances suivants à partir d'un enregistrement de la liste table :
L'attribut nom, de type str, qui prendra la valeur du champ Nom
L'attribut symbole, de type str, qui prendra la valeur du champ Symbole
L'attribut numero_atomique, de type int, qui prendra la valeur du champ Numéro atomique
L'attribut t_fusion, de type float, qui prendra la valeur du champ Température de fusion (en K) Si la température de fusion n'est pas renseignée, t_fusion prendra la valeur None
L'attribut t_ebullition, de type float, qui prendra la valeur du champ Température d'ébullition (en K) Si la température d'ébullition n'est pas renseignée, t_ebullition prendra la valeur None
Q3. Définir la méthode spéciale __repr__ pour qu'elle renvoie la chaîne de caractères ci-dessous :
Symbole : {symbole}
Nom : {nom}
Numéro atomique : {numéro atomique}
Masse atomique : {masse atomique} u
Température de fusion : {température fusion} K
Température d'ébullition : {température ébullition} K
Q4 Définir la méthode d'instance nb_neutrons pour qu'elle renvoie le nombre de neutrons de l'élément.
Le nombre de neutrons se calcule en soustrayant le numéro atomique à la masse atomique arrondie à l'unité.
Q5. Définir les méthodes d'instances t_fusion_degre et t_ebullition_degre qui renvoient respectivement les températures de fusion et d'ébullition d'un élément en degré Celsius, arrondies à deux décimales. On rappelle que $T_{°C} = T_{K} - 273.15$.
Si la température en $K$ n'est pas renseignée, ces méthodes devront renvoyer None.
Exemple d'utilisation :
>>>e1=Element(table[0])>>>e2=Element(table[16])>>>print(e1)Symbole:HNom:HydrogèneNuméroatomique:1Masseatomique:1.00794uTempératuredefusion:NoneKTempératured'ébullition : None K>>>print(e2)Symbole:ClNom:ChloreNuméroatomique:17Masseatomique:35.453uTempératuredefusion:171.65KTempératured'ébullition : 239.11 K>>>print(f'Nombre de neutrons de {e1.symbole} : {e1.nb_neutrons()}')NombredeneutronsdeH:0>>>print(f'Nombre de neutrons de {e2.symbole} : {e2.nb_neutrons()}')NombredeneutronsdeCl:18>>>print(f'Température de fusion de {e1.symbole} : {e1.t_fusion_degre()}')TempératuredefusiondeH:None>>>print(f'Température de ébullition de {e2.symbole} : {e2.t_ebullition_degre()}')TempératuredeébullitiondeCl:-34.04
In [ ]:
classElement:def__init__(self,e:dict):self.nom=e['Nom']self.symbole=e['Symbole']self.numero_atomique=int(e['Numéro atomique'])self.masse_atomique=float(e['Masse atomique (en u)'])ife['Température de fusion (en K)']!='':self.t_fusion=float(e['Température de fusion (en K)'])else:self.t_fusion=Noneife['Température d\'ébullition (en K)']!='':self.t_ebullition=float(e['Température d\'ébullition (en K)'])else:self.t_ebullition=Nonedef__repr__(self):returnf'Symbole : {self.symbole}\n\Nom : {self.nom}\n\Numéro atomique : {self.numero_atomique}\n\Masse atomique : {self.masse_atomique} u\n\Température de fusion : {self.t_fusion} K\n\Température d\'ébullition : {self.t_ebullition} K\n'defnb_neutrons(self):returnround(float(self.masse_atomique))-int(self.numero_atomique)deft_fusion_degre(self)->float:ifself.t_fusionisNone:returnNonereturnround(self.t_fusion-273.15,2)deft_ebullition_degre(self)->float:ifself.t_ebullitionisNone:returnNonereturnround(self.t_ebullition-273.15,2)
In [ ]:
e1=Element(table[0])e2=Element(table[16])print(e1)print(e2)print(f'Nombre de neutrons de {e1.symbole} : {e1.nb_neutrons()}')print(f'Nombre de neutrons de {e2.symbole} : {e2.nb_neutrons()}')print(f'Température de fusion de {e1.symbole} : {e1.t_fusion_degre()}')print(f'Température de ébullition de {e2.symbole} : {e2.t_ebullition_degre()}')
Q1. Créer la classe TableauPeriodique et définir les méthodes spéciales __init__ et __repr__ de la manière suivante :
Le constructeur initialise une variable d'instance elements, de type list d'Element, à partir de la liste d'enregistrements table passée en paramètre.
On utilisera la méthode par compréhension pour créer cet attribut d'instance.
La méthode spéciale __repr__ doit renvoyer la chaîne de caractères ci-dessous :
>>>t_mendeleiev=Tableau(table)>>>t_mendeleievSymbole:HNom:HydrogèneNuméroatomique:1Masseatomique:1.00794uTempératuredefusion:NoneKTempératured'ébullition : None KSymbole:HeNom:HéliumNuméroatomique:2Masseatomique:4.002602uTempératuredefusion:NoneKTempératured'ébullition : 4.22 K...Symbole:UuoNom:UnunoctiumNuméroatomique:118Masseatomique:294.0uTempératuredefusion:NoneKTempératured'ébullition : None K
Q2. Définir la méthode d'instance affiche_element qui :
Prend en paramètre le symbole d'un élément
Renvoie la chaîne de caractères correspondante si le symbole existe et None sinon
Q3. On souhaite effectuer des opérations de sélection à l'aide d'une méthode select.
Cette méthode prend en argument :
Une liste de conditions conditions initialisée par défaut à la liste vide, de type list de str
Un dictionnaire attributs où :
La clé est le nom du champ à utiliser dans l'écriture de la condition
La valeur est l'attribut d'instance correspondant de la classe Element
Elle renvoie la liste des éléments répondant aux critères si la liste conditions est non vide et la liste de tous les éléments sinon.
On considère le code incomplet ci-dessous :
defselect(self,conditions:list=[],attributs={'nom':'e.nom','sym':'e.symbole','Z':'e.numero_atomique','A':'e.masse_atomique','Tf':'e.t_fusion','Te':'e.t_ebullition'})->list:# Création par compréhension la liste des conditions en utilisant les attributs d'instance de la classe Element# On pourra utiliser la méthode replace des chaînes de caractèresconditions_modifiees=...# Création de la chaîne de caractères correspondant à la liste de ces conditions# On pourra utiliser la méthode join des chaînes de caractèreschaine_conditions=...# print(chaine_conditions)ifchaine_conditions=='':returnself.elementselse:# Création de la liste des éléments qui répondent aux critères spécifiés# On pourra utiliser la fonction evalres=...returnres
Compléter les instructions d'affectation des variables conditions_modifiees, chaine_conditions et res en respectant les consignes données en commentaires. Si conditions = ['1 < Z < 5', '"H" in nom'], alors :
conditions_modifiees = ['1 < e.numero_atomique < 5', '"H" in e.nom']
chaine_conditions = '1 < e.numero_atomique < 5' and '"H" in e.nom'
res contient uniquement l'élément "Hélium"
Exemple :
>>>t_mendeleiev=TableauPeriodique(table)>>>print(t_mendeleiev.select(['Z <= 5','Tf is not None','Tf > 1000']))[Symbole:BeNom:BérylliumNuméroatomique:4Masseatomique:9.012182uTempératuredefusion:1560.15KTempératured'ébullition : 2744.15 K,Symbole:BNom:BoreNuméroatomique:5Masseatomique:10.811uTempératuredefusion:2348.15KTempératured'ébullition : 4273.15 K]>>>print(t_mendeleiev.select(['1 <= Z <= 10','"H" in nom']))[Symbole:HNom:HydrogèneNuméroatomique:1Masseatomique:1.00794uTempératuredefusion:NoneKTempératured'ébullition : None K,Symbole:HeNom:HéliumNuméroatomique:2Masseatomique:4.002602uTempératuredefusion:NoneKTempératured'ébullition : 4.22 K]
In [ ]:
classTableauPeriodique:def__init__(self,table:list):self.elements=[Element(e)foreintable]def__repr__(self):res=''foreinself.elements:res+=f'{e.__repr__()}\n'returnresdefaffiche_element(self,symbole:str)->str:foreinself.elements:ife.symbole==symbole:returnf'{e.__repr__()}'returnNonedefselect(self,conditions:list=[],attributs={'nom':'e.nom','sym':'e.symbole','Z':'e.numero_atomique','A':'e.masse_atomique','Tf':'e.t_fusion','Te':'e.t_ebullition'})->list:conditions_modifiees=[c.replace(cle,attributs[cle])forcinconditionsforcleinattributsifcleinc]chaine_conditions=' and '.join(conditions_modifiees)#print(chaine_conditions)ifchaine_conditions=='':returnself.elementselse:res=[eforeinself.elementsifeval(chaine_conditions)]returnres
In [ ]:
t_mendeleiev=TableauPeriodique(table)#print(t_mendeleiev)#print(t_mendeleiev.affiche_element('Ag'))#print(t_mendeleiev.affiche_element('Lg'))print(t_mendeleiev.select(['Z <= 5','Tf is not None','Tf > 1000']))print(t_mendeleiev.select(['1 <= Z <= 10','"H" in nom']))
Q1. Créer une classe Texte et son constructeur. Celui-ci devra initialiser un attribut d'instance chaine à la valeur d'une chaîne de caractères passée en argument.
Créer ensuite une instance mon_texte de cette classe avec la chaine suivante :
blablabla bla blabla bli blo blabla blabla blabla blo bli
Q2. Créer une méthode nb_caracteres renvoyant le nombre de caractères de l'attribut chaine.
Exemple :
>>>mon_texte.nb_caracteres()57
Q3. Créer la méthode ajout_prefixe qui modifie la valeur de l'attribut chaine en lui ajoutant un texte passé en paramètre en début de chaîne.
Exemple :
>>>mon_texte.ajout_prefixe('blibli ')>>>mon_texte.chaine'blibli blablabla bla blabla bli blo blabla blabla blabla blo bli'
Q4. Créer la méthode trouve_lettre qui :
Prend en paramètre une lettre
Renvoie la position de la première occurrence de cette lettre si elle est présente et -1 sinon
Q5. Créer la méthode occurrences_lettre qui prend en paramètre une lettre et renvoie le nombre d'occurrences de celle-ci dans la chaîne, puis la tester.
Q6. On considère ici qu'un mot est un groupe de lettres ne contenant pas d'espace.
Créer la méthode nombre_mots qui renvoie le nombre de mots contenus dans chaine.
Q7. Créer la méthode dico_mots qui renvoie le dictionnaire des mots présents dans chaine où :
Les clés sont les mots
Les valeurs sont les nombres d'occurrences de chaque mot
Q9. Créer un attribut de classenb_instances qui dénombre le nombre d'instances de la classe Texte créées.
Compléter le programme en ajoutant une méthode de classe nombre_textes_crees renvoyant le nombre d'instances créées, puis la tester.
Q10. Définir la méthode spéciale repr pour qu'elle produise l'affichage donné en exemple.
>>>mon_texte=Texte('blibli blablabla bla blabla bli blo blabla blabla blabla blo bli')>>>mon_texteNombretotaldecaractères:64Nombretotaldemots:11Motsutilisés:Lemot"blibli"apparaît1foisLemot"blablabla"apparaît1foisLemot"bla"apparaît1foisLemot"blabla"apparaît4foisLemot"bli"apparaît2foisLemot"blo"apparaît2foisLettresutilisées:Lalettre"b"apparaît18foisauxpositions[0,3,7,10,13,17,21,24,28,32,36,39,43,46,50,53,57,61]Lalettre"l"apparaît18foisauxpositions[1,4,8,11,14,18,22,25,29,33,37,40,44,47,51,54,58,62]Lalettre"i"apparaît4foisauxpositions[2,5,30,63]Lalettre" "apparaît10foisauxpositions[6,16,20,27,31,35,42,49,56,60]Lalettre"a"apparaît12foisauxpositions[9,12,15,19,23,26,38,41,45,48,52,55]Lalettre"o"apparaît2foisauxpositions[34,59]
In [ ]:
classTexte:nb_instances=0def__init__(self,une_chaine:str):self.chaine=une_chaineTexte.nb_instances+=1defnb_caracteres(self)->int:returnlen(self.chaine)defajout_prefixe(self,une_chaine:str):self.chaine=une_chaine+self.chainedeftrouve_lettre(self,lettre:str)->int:foriinrange(len(self.chaine)):ifself.chaine[i]==lettre:returnireturn-1defoccurrences_lettre(self,lettre:str)->int:res=0forcarinself.chaine:ifcar==lettre:res+=1returnresdefdico_mots(self)->dict:res={}formotinself.chaine.split():ifmotinres:res[mot]+=1else:res[mot]=1returnresdefnombre_mots(self)->int:returnlen(self.chaine.split())defdico_lettres(self)->dict:res={}foriinrange(len(self.chaine)):lettre=self.chaine[i]iflettreinres:nb,pos=res[lettre]pos.append(i)res[lettre]=(nb+1,pos)else:res[lettre]=(1,[i])returnresdef__repr__(self)->str:res=f'Nombre total de caractères : {self.nb_caracteres()}\n'+\
f'Nombre total de mots : {self.nombre_mots()}\n\n'+\
'Mots utilisés :\n'formot,nbinself.dico_mots().items():res+=f'Le mot "{mot}" apparaît {nb} fois\n'res+='\nLettres utilisées :\n'forlettre,(nb,pos)inself.dico_lettres().items():res+=f'La lettre "{lettre}" apparaît {nb} fois aux positions {pos}\n'returnres@classmethoddefnombre_textes_crees(cls)->int:returncls.nb_instancesmon_texte=Texte('blablabla bla blabla bli blo blabla blabla blabla blo bli')print(mon_texte.nb_caracteres())mon_texte.ajout_prefixe('blibli ')print(mon_texte.chaine)print(mon_texte.trouve_lettre('a'))print(mon_texte.trouve_lettre('u'))print(mon_texte.occurrences_lettre('a'))print(mon_texte.occurrences_lettre('u'))print(mon_texte.occurrences_lettre('i'))print(mon_texte.dico_mots())print(mon_texte.nombre_mots())print(mon_texte.dico_lettres())print(mon_texte)print(Texte.nombre_textes_crees())autre_texte=Texte('blu')print(Texte.nombre_textes_crees())
Exercice 5 : Jeu de cartes "La Bataille" - Utilisation de classes par une autre classe¶
Dans cet exercice, on considère un jeu de 52 cartes.
Q1. Définir une classe JeuDeCartes permettant d'instancier des objets dont le comportement soit similaire à celui d'un vrai jeu de 52 cartes en respectant les contraintes ci-dessous :
Cette classe doit contenir les deux attributs de classe suivants :
L'attribut de classe figures contenant le dictionnaire {11: 'Valet', 12: 'Dame', 13: 'Roi', 14: 'As'}
L'attribut de classe couleurs contenant la liste des couleurs "Coeur", "Carreau", "Pique" et "Trèfle"
Le constructeur se chargera de créer l'attribut d'instance cartes qui contiendra une liste de 52 éléments, qui sont eux-mêmes des tuples de la forme (int, str). Cette liste de tuples contiendra les caractéristiques de chacune des 52 cartes. En effet, une carte peut être représentée par sa valeur et sa couleur. Par exemple la carte "As de Pique" sera représentée par le tuple (14, 'Pique'), la carte "Sept de Coeur" par le tuple (7, 'Coeur'), ...
Q2. Définir une méthode est_vide qui renvoie True si le jeu de cartes est vide et False sinon.
Exemple :
Q3. Définir une méthode battre qui permet de mélanger le jeu de cartes, uniquement si la liste cartes est non-vide.
On pourra utiliser la fonction shuffle du module random, en l'important au préalable, sur l'attribut cartes.
Q4. Définir une méthode tirer : Lorsque cette méthode est appelée, une carte est retirée du jeu et le tuple contenant sa valeur et sa couleur est renvoyé. On retire toujours la dernière carte de la liste.
Si cette méthode est invoquée alors qu'il ne reste plus aucune carte dans la liste, la méthode renverra None.
Exemple :
Q5. Définir une méthode nom_carte qui prend en paramètre un tuple représentant une carte et renvoyant la chaîne de caractères désignant la carte comme indiqué dans l'exemple. La méthode renverra None si la carte
Exemple :
>>>j=JeuDeCartes()>>>j.nom_carte((14,'Pique'))'As de Pique'>>>j.nom_carte((7,'Coeur'))'7 de Coeur'>>>j.nom_carte(None)None
Q6. Implémenter la suite d'instructions suivantes en Python puis tester pour n = 3, n = 5 et n = 60:
Affecter à n l'entier 3 (n représente le nombre de cartes à tirer)
Créer une instance j de JeuDeCartes
Battre le jeu de cartes
Afficher le jeu de cartes mélangés
Tirer et afficher le nom des n dernières cartes
In [ ]:
fromrandomimportshuffleclassJeuDeCartes():figures={11:'Valet',12:'Dame',13:'Roi',14:'As'}couleurs=['Coeur','Carreau','Pique','Trèfle']def__init__(self):self.cartes=[]forcouleurinJeuDeCartes.couleurs:foriinrange(2,15):self.cartes.append((i,couleur))defest_vide(self)->bool:returnlen(self.cartes)==0defbattre(self):ifnot(self.est_vide()):shuffle(self.cartes)deftirer(self)->tuple:ifself.est_vide():returnNonereturnself.cartes.pop()defnom_carte(self,carte:tuple)->str:ifcarteisnotNone:valeur,couleur=carteifvaleur>10:valeur=JeuDeCartes.figures[valeur]returnf'{valeur} de {couleur}'returnNone
Ce jeu se joue à deux joueurs. Chacun possède un jeu de 52 cartes mélangés. Chaque joueur tire la carte située en haut du tas (retourné). Le joueur qui a la carte avec la plus grande valeur remporte le point. Si les deux valeurs sont égales, on passe au tirage suivant. On procède ainsi avec les 52 cartes des tas. Le gagnant est celui qui totalise le plus de points.
Q1. Définir une classe Joueur contenant les méthodes suivantes :
Un constructeur qui :
Initialise une variable d'instance nom, de type str, avec le nom du joueur passé en paramètre.
Initialise une variable d'instance score, de type int, avec la valeur passée en paramètre.
Ce paramètre prendra pour valeur par défaut 0.
Initialise une variable d'instance tas de type JeuDeCartes.
Une méthode gagne qui permet d'augementer le score du joueur de 1 point
Une méthode info_score qui renvoie la chaîne de caractères suivante : Score du joueur {nom} : {score} point(s).
In [ ]:
classJoueur:def__init__(self,nom:str,score:int=0):self.nom=nomself.tas=JeuDeCartes()self.score=scoredefgagne(self):self.score+=1definfo_score(self)->str:returnf'Score du joueur {self.nom} : {self.score} point(s)'
Q2. Définir une classe Match contenant les méthodes suivantes :
Un constructeur qui :
Initialise une variable d'instance joueur_A de type Joueur
Initialise une variable d'instance joueur_B de type Joueur
Initialise une variable d'instance vainqueur à None
Une méthode play qui simule une partie entre les deux joueurs.
Le jeu commence par le mélange des tas de cartes de chacun des joueurs.
Exemple de partie au cours de laquelle le joueur B gagne :
classMatch:classJoueur:def__init__(self,nom:str,score:int=0):self.nom=nomself.tas=JeuDeCartes()self.score=scoredefgagne(self):self.score+=1definfo_score(self)->str:returnf'Score du joueur {self.nom} : {self.score} point(s)'def__init__(self,joueur_A:joueur,joueur_B:joueur):self.joueur_A=joueur_Aself.joueur_B=joueur_Bself.vainqueur=Nonedefplay(self):self.joueur_A.tas.battre()self.joueur_B.tas.battre()foriinrange(52):ca=self.joueur_A.tas.tirer()cb=self.joueur_B.tas.tirer()ifca[0]>cb[0]:self.joueur_A.gagne()print(f'A : {self.joueur_A.tas.nom_carte(ca)} | B : {self.joueur_B.tas.nom_carte(cb)} -> A gagne')elifca[0]<cb[0]:self.joueur_B.gagne()print(f'A : {self.joueur_A.tas.nom_carte(ca)} | B : {self.joueur_B.tas.nom_carte(cb)} -> B gagne')else:print(f'A : {self.joueur_A.tas.nom_carte(ca)} | B : {self.joueur_B.tas.nom_carte(cb)} -> ex aequo')print('\n'+self.joueur_A.info_score())print(self.joueur_B.info_score())score_a,score_b=self.joueur_A.score,self.joueur_B.scoreifscore_a==score_b:print(f'Match nul. Les deux joueurs ont un score égal à {score_a}.')else:ifscore_a>score_b:self.vainqueur=self.joueur_Aelse:self.vainqueur=self.joueur_Bprint(f'Le vainqueur est {self.vainqueur.nom} avec un score de {self.vainqueur.score} points.')
Q1. Définir une classe Point implémentant l'interface InterfacePoint puis compléter le corps des méthodes spéciales __init__ et __repr__ de la manière suivante :
Le constructeur __init__ doit initialiser :
L'attribut d'instance nom de type str qui prendra pour valeur le nom du point
L'attribut d'instance x de type int représentant l'abscisse du point
L'attribut d'instance y de type int représentant l'ordonnée du point
La méthode spéciale __repr__ doit renvoyer la chaîne {nom du point}({valeur de x}, {valeur de y})
Q2. Compléter le corps de la méthode de classedistance qui prend en paramètres deux instances a et b de Point et renvoie la valeur de la distance entre ces deux points.
Q1. Définir une classe Polygone implémentant l'interface InterfacePolygone puis compléter le corps des méthodes spéciales __init__ et __repr__ de la manière suivante :
Le constructeur __init__ doit initialiser l'attribut d'instance points, de type list de Point, correspondant à la liste des sommets du polygone. Lors de l'initialisation de cet attribut, on veillera à bien créer une nouvelle liste d'instances de la classe Point à partir de la liste points passée en paramètre, en utilisant la méthode par compréhension.
La méthode spéciale __repr__ doit renvoyer la chaîne suivante :
Q2. Compléter le corps de la méthode de d'instance perimetre qui renvoie la valeur du périmètre du polygone.
Q3. Compléter le corps de la méthode d'instance dessine ci-dessous permettant de dessiner le polygone dans une nouvelle fenêtre à l'aide du module turtle.
On pensera à importer ce module au préalable à l'aide de l'instruction import turtle.
defdessine(self):turtle.reset()turtle.setup()turtle.title(f'Représentation du polygone {self.__repr__()}')# Partie à compléter...turtle.exitonclick()
importturtleclassPolygone(implements(InterfacePolygone)):def__init__(self,points:list):assert(len(points)>=3),'Un polygone doit avoir au minimum 3 sommets.'self.points=[pointforpointinpoints]def__repr__(self):nom,coords='',''forpinself.points:nom+=p.nomcoords+=f'({p.x}, {p.y}), 'returnf'Polygone {nom} : [{coords[:-2]}]'defperimetre(self)->float:res=Point.distance(self.points[0],self.points[-1])foriinrange(len(self.points)-1):res+=Point.distance(self.points[i],self.points[i+1])returnresdefdessine(self):turtle.reset()turtle.setup()turtle.title(f'Représentation du polygone {self.__repr__()}')turtle.up()turtle.goto(self.points[0].x,self.points[0].y)turtle.write(self.points[0].nom)turtle.down()foriinrange(1,len(self.points)):turtle.goto(self.points[i].x,self.points[i].y)turtle.write(self.points[i].nom,align="left")turtle.goto(self.points[0].x,self.points[0].y)turtle.exitonclick()
Exercice 7 : Vecteurs 2D à coordonnées entières - Interface¶
Dans cet exercice, nous allons implémenter une classe permettant de créer et de manipuler des vecteurs 2D, à coordonnées entières, à partir de l'interface donnée ci-dessous :
Q1. Définir une classe Vecteur2D implémentant l'interface InterfaceVecteur2D puis compléter le corps des méthodes spéciales __init__ et __repr__ de la manière suivante :
Le constructeur __init__ doit initialiser :
L'attribut d'instance x de type int représentant l'abscisse du vecteur
L'attribut d'instance y de type int représentant l'ordonnée du vecteur
La méthode spéciale __repr__ doit renvoyer la chaîne ({valeur de x}, {valeur de y})
Q2. Compléter le corps de la méthode multiplication_ext qui prend en argument un entier k et renvoie une instance de Vecteur2D représentant le vecteur $k \vec{u}$.
Si une des coordonnées du vecteur $\vec{u}$ n'est pas définie, la méthode renverra None.
Q3. Compléter le corps de la méthode representant qui prend en argument un tuplepoint (initialisé par défaut au couple (0, 0)) représentant l'origine du vecteur et renvoie un tuple constitués des couples représentant respectivement l'origine du vecteur et son extrémité.
Si une des coordonnées du vecteur $\vec{u}$ n'est pas définie, la méthode renverra None.
Q4. Compléter le corps de la méthode norme qui renvoie la norme du vecteur $\vec{u}$.
Si une des coordonnées du vecteur $\vec{u}$ n'est pas définie, la méthode renverra None.