Méthodes spéciales
Les méthodes spéciales
, aussi appelées méthodes magiques ou méthodes du double underscore (dunder), sont des méthodes prédéfinies en Python qui permettent de surcharger le comportement des opérateurs et des fonctions intégrées. Ces méthodes sont appelées automatiquement par l’interpréteur Python en fonction de l’opération effectuée.
Exercice 1 : traîneau de la Mère Noël
La Mère Noël souhaite optimiser la distribution des cadeaux en traîneau. Pour cela, elle a besoin de calculer la capacité de son traîneau en fonction de la taille des cadeaux.
La Mère Noël veut également calculer le temps de chargement des cadeaux dans le traineau. Pour cela, cela elle vous demande de créer un décorateur @timer
qui permet de mesurer le temps d’exécution d’une méthode.
classDiagram
class Gift {
+ size : string
+ __init__(size: string)
+ compute_weight() float
+ compute_time() float
+ wrap_gift() void
}
class Sleigh {
+ capacity : float
+ current_capacity : float
+ gifts : list
+ __init__(capacity: float)
+ add_gift(gift: Gift) void
+ remove_gift(gift: Gift) void
+ compute_free_capacity() float
+ __len__() int
+ __eq__(other: Sleigh) bool
+ __lt__(other: Sleigh) bool
+ __gt__(other: Sleigh) bool
}
Gift --> Sleigh : "contained in"
Définissez une classe Gift
qui permet de représenter un cadeau, caractérisé par sa taille. Les cadeaux sont classés en trois catégories : Small, Medium et Large qui ont les caractéristiques suivantes :
Taille | Poids | Temps d’emballage |
---|---|---|
Small | 1 kg | 1 seconde |
Medium | 2 kg | 3 secondes |
Large | 5 kg | 10 secondes |
La classe Gift
aura les méthodes suivantes :
-
__init__(size: str)
: constructeur d’un cadeau à partir de sa taille. -
compute_weight()
: méthode décorée par@timer
qui renvoie le poids du cadeau. -
compute_time()
: méthode décorée par@timer
qui renvoie le temps d’emballage du cadeau. -
wrap_gift()
: méthode décorée par@timer
qui attend le temps d’emballage du cadeau (i.e.time.sleep()
)
Définissez une classe Sleigh
qui permet de calculer la capacité du traîneau en fonction de la taille des cadeaux. La classe Sleigh
comportera au moins les méthodes suivantes :
-
__init__(capacity: float)
: constructeur d’un traîneau à partir de sa capacité. -
compute_free_capacity()
: renvoie la capacité restante du traîneau. -
add_gift(gift: Gift)
: ajoute un cadeau au traîneau (seulement si la capacité du traîneau est suffisante). -
remove_gift(gift: Gift)
: retire un cadeau du traîneau. -
__len__()
: renvoie la capacité du traîneau. -
__eq__(other: Sleigh)
: compare si les traîneaux ont la même capacité. -
__lt__(other: Sleigh)
: compare si la capacité du traîneau est inférieure à celle d’un autre traîneau. -
__gt__(other: Sleigh)
: compare si la capacité du traîneau est supérieure à celle d’un autre traîneau.
Créer une classe main qui permet de tester les classes Gift
et Sleigh
.
Exercice 2 : points du plan
Définissez une classe Point
pour représenter les points du plan rapporté à une origine fixée. Les coordonnées d’un point sont ici deux nombres flottants x
, y
, qui sont deux attributs privés.
classDiagram
class Point {
# x: float
# y: float
+ x() float
+ y() float
+ r() float
+ t() float
+ __str__() string
+ __eq__(other: Point) bool
+ __add__(other: Point) Point
+ __sub__(other: Point) Point
+ homothety(k: float) void
+ translation(dx: float, dy: float) void
+ rotation(a: float) void
}
La classe Point
comportera au moins les méthodes suivantes :
-
__init__(x, y)
: constructeur d’un point à partir de ses coordonnées cartésiennes. - Les méthodes
x()
ety()
retournent les coordonnées cartésiennes du point. Les méthodesr()
ett()
retournent les coordonnées polaires du point (voir ci-dessous). Ces 4 méthodes sont définies comme des propriétés. -
__str__()
: renvoie les coordonnées du point sous format texte. Par exemple, si on crée un point d’abscisse 2 et d’ordonnée 3 (i.e.Point(x=2, y=3)
), la fonction retournera \((2.0, 3.0)\). -
__eq__(other)
: compare si les points sont identiques (i.e. ont les mêmes coordonnées). -
__add__(other)
: additionne les coordonnées de deux points pour obtenir un nouveau point. -
__sub__(other)
: soustrait les coordonnées de deux points pour obtenir un nouveau point. -
homothety(k)
: applique au point une homothétie de centre \((0, 0)\) et de rapport \(k\) (k est un flottant). Pour cela, on multiplie les coordonnées \((x, y)\) par \(k\) pour obtenir \((kx, ky)\). -
translation(dx, dy)
: applique au point une translation de vecteur \((dx, dy)\). Cela consiste à remplacer \((x, y)\) par \((x + dx, y + dy)\). -
rotation(a)
: applique au point une rotation de centre \((0, 0)\) et d’angle \(a\). Une manière – qui n’est pas la plus efficace – de faire cela consiste à calculer les coordonnées polaires \((r, t)\) correspondant à \((x, y)\) puis les coordonnées cartésiennes \((x′, y′)\) correspondant à \((r, t + a)\).
Rappel des formules
- Coordonnées cartésiennes à partir des coordonnées polaires : \(x = r cos(t)\) et \(y = r sin(t)\)
- Coordonnées polaires à partir des coordonnées cartésiennes : \(r = \sqrt{x^2 + y^2}\) et \(t = atan2(y, x)\)