Algorithmique et Programmation - TP, Cheat Sheet of Computer science

Ceci est le premier travail que nous avons eu à faire sur la conception des classes en Python.

Typology: Cheat Sheet

2021/2022

Uploaded on 04/18/2023

kenny-boluka
kenny-boluka 🇨🇩

1 document

1 / 13

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Par
BOLUKA W’EKETE Kenny (2GEI)
MBANGU MANGUNGU Francis (2GEI)
TSHITOKO MINGA Manassé (2GC)
UNIVERSITE DE KINSHASA
FACULTE POLYTECHNIQUE
TRAVAIL PRATIQUE D’ALGORITHMIQUE
ET PROGRAMMATION
PROF. OLAMBA Paul
ANNEE ACADEMIQUE : 2021-2022
pf3
pf4
pf5
pf8
pf9
pfa
pfd

Partial preview of the text

Download Algorithmique et Programmation - TP and more Cheat Sheet Computer science in PDF only on Docsity!

Par

BOLUKA W’EKETE Kenny (2GEI)

MBANGU MANGUNGU Francis (2GEI)

TSHITOKO MINGA Manassé (2GC)

UNIVERSITE DE KINSHASA

FACULTE POLYTECHNIQUE

TRAVAIL PRATIQUE D’ALGORITHMIQUE

ET PROGRAMMATION

PROF. OLAMBA Paul

ANNEE ACADEMIQUE : 2021- 2022

  • Comme demandé par le travail, nous commençons par donner le diagramme UML

pour le projet :

Figure 1 : Diagramme UML avant la classe qui exploite les classes des formes géométriques

  • La classe de base est « FormeGeometrique », qui a deux méthodes abstraites

« perimetre() » et « surface() » pour le calcul du périmètre et de la surface d’une forme

géométrique. Les classes dérivées « Rectangle », « Cercle » et « Triangle » héritent de la

classe de base et implémentent ces méthodes en fonction de leur propre logique.

  • Pour ajouter les classes des carrés et des triangles rectangles, nous avons créé une

classe « Carre » qui hérite de la classe « Rectangle », et une classe

« TriangleRectangle » qui hérite de la classe « Triangle ». Ces deux nouvelles classes

peuvent utiliser les méthodes de calcul de périmètre et de surface déjà implémentées dans

les classes parentes.

Voici donc l’implémentation sur Python de la classe de base et de ses classes filles :

from math import pi, sqrt class FormeGeometrique: def perimetre(self): pass def surface(self): pass class Rectangle(FormeGeometrique): def init(self, longueur : float, largeur : float): self.longueur = longueur self.largeur = largeur def perimetre(self): return 2 * (self.longueur + self.largeur)

Figure 2 : Diagramme UML après la classe qui exploite la classe des formes géométriques

Voici l’implémentation de la classe « CalculateurFormeGéométrique » qui exploite les

classes des formes géométriques pour fournir le périmètre et la surface d’une forme

géométrique :

class CalculateurFormeGeometrique: def calculer_perimetre(self, forme : FormeGeometrique): return forme.perimetre() def calculer_surface(self, forme : FormeGeometrique): return forme.surface()

  • Le nombre des classes développées dans le cadre de ce projet est 7

( FormeGeometrique, Rectangle, Cercle, Triangle, Carre, TriangleRectangle,

CalculateurFormeGeometrique ). Oui c’est le minimum possible car chaque classe a sa

propre responsabilité et hérite de la classe appropriée pour réutiliser le code déjà

implémenté, ce qui évite la duplication de code inutile.

  • Pour organiser les classes en modules, nous avons créé un module appelé

« formes_geométriques » et nous y avons regroupé les classes développées.

Ce fichier n’est rien d’autre qu’une combinaison de nos deux premières implémentations, il

se présente comme suit :

from math import pi, sqrt class FormeGeometrique: def perimetre(self): pass def surface(self): pass class Rectangle(FormeGeometrique): def init(self, longueur : float, largeur : float): self.longueur = longueur self.largeur = largeur def perimetre(self): return 2 * (self.longueur + self.largeur) def surface(self): return self.longueur * self.largeur class Cercle(FormeGeometrique): def init(self, rayon : float): self.rayon = rayon def perimetre(self): return 2 * pi * self.rayon def surface(self): return pi * self.rayon** 2 class Triangle(FormeGeometrique): def init(self, cote1 : float, cote2 : float, cote3 : float): self.cote1 = cote self.cote2 = cote self.cote3 = cote def perimetre(self): return self.cote1 + self.cote2 + self.cote def surface(self): p = (self.cote1 + self.cote2 + self.cote3)/ 2 return sqrt(p * (p - self.cote1) * (p - self.cote2) * (p - self.cote3)) class Carre(Rectangle): def init(self,cote : float): super().init(cote, cote)

class TriangleRectangle(Triangle):

rectangle = Rectangle( 4 , 6 ) cercle = Cercle( 5 ) triangle = Triangle( 3 , 5 , 6 ) carre = Carre( 5 ) triangle_rectangle = TriangleRectangle( 3 , 4 ) calculateur = CalculateurFormeGeometrique() self.assertEqual(calculateur.calculer_perimetre(rectangle), 20 ) self.assertEqual(calculateur.calculer_surface(rectangle), 24 ) self.assertAlmostEqual(calculateur.calculer_perimetre(cercle), 2 * pi * 5 ) self.assertAlmostEqual(calculateur.calculer_surface(cercle), pi * 5 ** 2 ) self.assertEqual(calculateur.calculer_perimetre(triangle), 14 ) self.assertEqual(calculateur.calculer_surface(triangle), 2 * sqrt( 14 )) self.assertEqual(calculateur.calculer_perimetre(carre), 20 ) self.assertEqual(calculateur.calculer_surface(carre), 25 ) self.assertEqual(calculateur.calculer_perimetre(triangle_rectangle), 12 ) self.assertEqual(calculateur.calculer_surface(triangle_rectangle), 6 ) if name == 'main': unittest.main()

Ce code définit une classe de tests « TestFormesGeometriques » qui hérite de

« unittest.Case » et contient plusieurs méthodes de test pour chaque classe du projet.

Nous y avons défini 6 tests, 5 pour chacune des 5 classes filles de la classe

« FormeGeometrique » et une pour la classe qui exploite les classes des formes

géométriques.

En lançant le programme, on obtient ceci :

Notre code tourne donc correctement.

  • Un autre concept de la technologie orientée objet que l’on pourrait utiliser pour

réaliser le projet est la composition, où une classe peut contenir des objets d’autres classes

comme attributs, plutôt que d’utiliser l’héritage pour créer une hiérarchie de classes.

En voici le diagramme des classes UML :

Dans cette approche, la classe « FormeGeometrique » est une classe de base qui définit

les méthodes « perimetre() » et « surface() » pour calculer le périmètre et la surface de

n’importe quelle figure géométrique.

Les classes « Rectangle », « Cercle », « Triangle », « Carre » et « TriangleRectangle »

sont des classes qui contiennent les informations spécifiques à chaque forme géométrique

(par exemple, les côtés d’un rectangle ou le rayon d’un cercle), et elles utilisent les méthodes

de la classe « FormeGeometrique » pour effectuer les calculs.

La classe « FormeComposee » est composée d’une liste d’objets de formes géométriques

(« Rectangle », « Triangle », etc.) et implémente les méthodes « perimetre() » et

« surface() » pour calculer respectivement le périmètre et la surface de toutes les formes

géométriques ajoutées à la liste. Elle est ici la classe qui exploite les classes de formes

géométriques.

Voici une implémentation du projet en utilisant la composition :

from math import pi, sqrt class FormeGeometrique: def perimetre(self): raise NotImplementedError("Méthode non implémentée") def surface(self):

self.base = base self.hauteur = hauteur def perimetre(self): return self.base + self.hauteur + (sqrt(self.base** 2 + self.hauteur** 2 )) def surface(self): return self.base * self.hauteur/ 2 class FormeComposee: def init(self): self.formes = [] def ajouter_forme(self, forme): self.formes.append(forme) def perimetre(self): perimetre_total = [] for forme in self.formes: perimetre_total.append(forme.perimetre()) return perimetre_total def surface(self): surface_totale = [] for forme in self.formes: surface_totale.append(forme.surface()) return surface_totale

Comme fait pour la précédente implémentation, nous allons générer une batterie de test

pour notre implémentation en organisant les classes développées en module.

Nous nommons notre module « formes_geometriques_composition ».et le fichier test

« tests_formes_geometriques_composition » dont voici l’implémentation :

import unittest from math import pi, sqrt from formes_geometriques_composition import FormeGeometrique, Rectangle, Cercle, Triangle, TriangleRectangle, Carre, FormeComposee class TestFormesGeometriquesComposition(unittest.TestCase): def test_rectangle(self): rectangle = Rectangle( 4 , 6 ) self.assertEqual(rectangle.perimetre(), 20 ) self.assertEqual(rectangle.surface(), 24 ) def test_cercle(self): cercle = Cercle( 5 ) self.assertAlmostEqual(cercle.perimetre(), 2 * pi * 5 ) self.assertAlmostEqual(cercle.surface(), pi * 5 ** 2 )

def test_triangle(self): triangle = Triangle( 3 , 5 , 6 ) self.assertEqual(triangle.perimetre(), 14 ) self.assertEqual(triangle.surface(), 2 * sqrt( 14 )) def test_carre(self): carre = Carre( 5 ) self.assertEqual(carre.perimetre(), 20 ) self.assertEqual(carre.surface(), 25 ) def test_triangle_rectangle(self): triangle_rectangle = TriangleRectangle( 3 , 4 ) self.assertEqual(triangle_rectangle.perimetre(), 12 ) self.assertEqual(triangle_rectangle.surface(), 6 ) def test_forme_composee(self): formes = FormeComposee() rectangle = Rectangle( 4 , 6 ) cercle = Cercle( 5 ) triangle = Triangle( 3 , 5 , 6 ) carre = Carre( 5 ) triangle_rectangle = TriangleRectangle( 3 , 4 ) formes.ajouter_forme(rectangle) formes.ajouter_forme(cercle) formes.ajouter_forme(triangle) formes.ajouter_forme(carre) formes.ajouter_forme(triangle_rectangle) self.assertEqual(formes.perimetre(), [ 20 , 2 * pi * 5 , 14 , 20 , 12 ]) self.assertEqual(formes.surface(), [ 24 , pi * 5 ** 2 , 2 * sqrt( 14 ), 25 , 6 ]) if name == 'main': unittest.main()

Nous avons une fois de plus utiliser le module « unittest » de Python pour tester nos

différentes classes et voici le résultat :

Notre deuxième implémentation fonctionne donc correctement et les résultats trouvés sont

conformes à ceux de la première implémentation.

  • Pour évaluer le temps d’exécution des méthodes dans les deux cas (héritage vs

composition), il faudrait prendre en compte la complexité algorithmique de chaque méthode.

En général, la complexité algorithmique de chaque méthode dépendra de la façon dont les

calculs sont effectués. Par exemple, les méthodes « perimetre() » et « surface() » des

classes « Rectangle » et « Cercle » ont une complexité constante O(1) , car les calculs sont

permettant ainsi une plus grande flexibilité dans la création et la configuration de formes

complexes.

Notre projet ne nous en demandant pas tant, il est évident que notre choix devrait donc se

porter sur l’approche de « l’héritage » car le rectangle, le cercle, le triangle, le carré ainsi

que le triangle rectangle sont tous des types de figure géométrique.