====== Module de géométrie avec les classes ====== On reprend la définition de la classe ''Triangle'' définie [[classe_python|ici]]. # module triangle.py class Triangle: """ Commentaires utiles pour la lisibilité et la documentation """ def __init__(self, x1, y1, x2, y2, x3, y3): """ Constructeur - Gère l'initialisation de l'objet x1, y1: coordonnées du premier point x2, y2: coordonnées du deuxième point x3, y3: coordonnées du troisième point """ self.x1 = x1 self.y1 = y1 self.x2 = x2 self.y2 = y2 self.x3 = x3 self.y3 = y3 def aire(self): """ Renvoie l'aire du triangle """ # formule de maths... return abs((self.x2 - self.x1)*(self.y3 - self.y1) - (self.y2 - self.y1)*(self.x3 - self.x1))/2 ===== Exercice 1 : méthodes supplémentaires ===== Ajoutez une méthode ''%%périmetre%%'' et une méthode ''%%centre_de_gravite%%'' à la classe ''Triangle''. ===== Exercice 2 : classe Parallélogramme ===== Dans un module ''parallelogramme.py'' créez une classe ''Parallelogramme'' en reprenant le modèle de la classe ''Triangle''. Pensez à vérifier que les coordonnées fournies sont bien celles d'un parallélogramme. == public / privé == Supposez que l'on crée ''%%p = Parallelogramme(0,0,1,0,2,1,1,1)%%''. C'est bien un parallélogramme, c'est vérifié dans la méthode ''%%__init__%%''. Mais que se passe-t-il si on écrit plus tard ''%%p.x1 = 12%%'' ? Avec cette modification, ''p'' n'est plus un parallélogramme. Il faudrait empêcher que l'on puisse changer ainsi les coordonnées. Ceci peut être contrôlé, c'est le rôle d'élément comme la visibilité public / privé. ===== Exercice 3 : classe Point ===== * Dans un module ''point.py'', définir une classe ''Point'' ayant les attributs ''x'', ''y''. * Ajouter la méthode ''distance(self, autrePoint)'' de sorte que pour les ''Point'' ''A'' et ''B'', l'expression ''A.distance(B)'' donne la distance AB. * Modifier les classes ''Triangle'' et ''Parallelogramme'' pour qu'elles utilisent la classe ''Point'' au lieu des paires de coordonnées ''x'' et ''y''. ===== Exercice 4 : problème de dépendance ===== Supposons que l'on veuille ajouter une fonction qui détermine si un point est contenu dans un triangle. Selon vous, quel est le meilleur choix ? * dans la classe ''Point'', définir la méthode ''est_dans_triangle(self, triangle)'' * dans la classe ''Triangle'', définir la méthode ''contient_point(self, point)'' * en dehors des deux classes, définir une fonction ''triangle_contient_point(triangle, point)'' Argumentez. ===== Exercice 5 : méthodes magiques ===== [[nsi:langages:python:methodes_magiques|Plus d'infos ici]]. Quand on définit ''x = 5'' et ''y = 12'', on peut faire avec ''x'' et ''y'' un certain nombre d'opérations qui seront comprises automatiquement par le langage. * On peut additionner ''x + y'' * On peut comparer ''%%x <= y%%'' * On peut afficher ''print(x)'', ce qui provoque le **transtypage** de ''x'', ''int'' -> ''str'' Si on souhaite pouvoir faire ce genre d'opérations avec notre objet, c'est possible ! === Transtypage str === La méthode magique ''%%__str(self)__%%'' permet de définir comment convertir un objet en ''str'' ce qui permet d'utiliser ''print''. Dotez la classe ''Point'' de la méthode ''%%__str__%%'' pour que le point de coordonnées (6 ; 28), transtypé en ''str'' produise le texte ''%%"(6 ; 28)"%%''. === Console === Quand on fait un calcul en console, la console affiche le résultat. La méthode utilisée pour produire l'affichage du résultat n'est pas ''%%__str__%%'' mais ''%%__repr__%%''. On aimerait que pour le point de coordonnées (6 ; 28) l'affichage soit de la forme ''%%Point (6 ; 28)%%''. La fonction ''%%__repr__%%'' doit donc renvoyer dans ce cas le texte ''%%"Point (6 ; 28)"%%''. === Comparaison === Supposons que l'on veuille permettre la comparaison entre deux objets ''Point''. On voudrait pouvoir écrire : p1 = Point(45,12) p2 = Point(17, 4) if p1 > p2: "p1 est supérieur" else: "p1 est inférieur ou égal" On voudrait donc que ''p1 < p2'' ait un sens. Il faut donc : * que nous définissions ce que cela pourrait vouloir dire, * que nous indiquions à Python notre critère de comparaison Nous pouvons par exemple décider que ''p1 > p2'' quand ''p1'' est plus éloigné de l'origine du repère que ''p2''. Il faudrait calculer ''d1'', distance entre ''p1'' et l'origine, ''d2'', distance entre ''p2'' et l'origine, et on déciderait que ''p1 > p2'' équivalent à ''d1 > d2''. Voilà nous avons un critère clair. Maintenant comment l'indiquer à Python ? # à l'intérieur de la classe Point def __gt__(p1, p2): # gt = greater than """ Renvoie True si p1 > p2 False sinon """ # vous n'avez plus qu'à compléter ici ! === Soustraction === Quand on calcule les coordonnées d'un vecteur $\overrightarrow{AB}$ on calcul $x_B - x_A$ et $y_B - y_A$. On a souvent très envie d'écrire quelque chose comme $B - A$. Ne dites pas cela à votre prof de maths :-x ! On peut le faire en Python en expliquant à la classe ''Point'' comment elle doit réaliser cette soustraction. # à l'intérieur de la classe Point def __sub__(p1, p2): # sub = soustraction """ Renvoie un objet Point avec les coordonnées x = p1.x - p2.x, y = p1.y - p2.y """ # vous n'avez plus qu'à compléter ici !