1.5. Programmation orientée objet (TD)#
1.5.1. Pour commencer#
Écrire une classe
Eleve
qui contiendra les attributsnom
,classe
etnote
.Instancier trois élèves de cette classe.
Écrire une fonction
compare(eleve1, eleve2)
qui renvoie le nom de l’élève ayant la meilleur note.Écrire la méthode
__eq__
qui renvoieTrue
si les élèves ont la même note etFalse
sinon.
Écrire une classe Player qui :
ne prendra aucun argument lors de son instanciation.
affectera à chaque objet créé un attribut energie valant 3 par défaut.
affectera à chaque objet créé un attribut alive valant True par défaut.
fournira à chaque objet une méthode blessure() qui diminue l’attribut energie de 1.
fournira à chaque objet une méthode soin() qui augmente l’attribut energie de 1.
si l’attribut energie passe à 0, l’attribut alive doit passer à False et ne doit plus pouvoir évoluer.
1.5.2. TD sur les fractions#
Le but de ce Travail Dirigé est de prendre en main la réalisation d’une classe et l’utiliser en tant qu’objet. Le T.D. se focalise donc sur cet aspect, même si d’autres aspects peuvent être travaillés.
Le travail doit être déposé avant demain dans le dépot suivant
Avertissement
Attention, une fois passé la date de demain soir, ce dépot ne sera plus accessible.
Votre fichier doit être au format Notebook (*.ipynb)
, nommé suivant le schéma : <date (format aaad-mm-jj)> <nom> <prenom> <titre du TP>
Rédiger une classe Fraction
permettant de
créer un objet Fraction à partir de son numérateur et dénominateur ;
tester si deux fractions sont égales avec
f = Fraction(2,3) g = Fraction(4,6) assert f.egal(g) == True
additionner deux fractions
f = Fraction(2,3) g = Fraction(4,5) h = f.somme(g) assert h.egal(Fraction(22,15)) == True
soustraire deux fractions
multiplier deux fractions
prendre l’inverse d’une fraction
diviser deux fractions
donner le numérateur et le dénominateur
simplier une fraction (peut être une fonction en dehors de la classe)
On veillera à commenter ses fonctions, à donner des indications de types et à tester les entrées sorties sur des exemples simples.
def somme(a: float, b:float) -> float
"""Renvoie la somme de deux float
Une bête addition.
Args:
a (float): Le premier opérande
b (float): Le deuxième opérande
Returns:
float: la somme
Exemples:
>>> somme(2.2, 5.3)
7.5
"""
return a+b
assert somme(2.2, 5.3) == 7.5
Astuce
Note
Si la docstring
contient >>> fonction(args)
suivi du résultat attendu, on peut placer
%%doctest
from doctest import testmod
testmod(verbose=True)
dans le Notebook Jupyter pour tester la fonction.
Show code cell content
from IPython.display import Code
Show code cell content
Code(filename='fraction.py',language='python3')
"""
fraction.py
une classe (incomplète) Fraction
une fonction egyptian donnant la decomposition égyptienne d'une fraction
Auteur : S. Hoarau
Date : 2021-09-19
Licence : CC BY-NC-SA 4.0 http://creativecommons.org/licenses/by-nc-sa/4.0/
"""
import math
class Fraction:
PRECISION = 0.0000001
def __init__(self, num, den):
if den:
self.__den = den
else:
raise ZeroDivisionError("denominator can't be zero")
self.__num = num
@property
def num(self):
return self.__num
@num.setter
def num(self, num):
self.__num = num
@property
def den(self):
return self.__den
@den.setter
def den(self, den):
if den:
self.__den = den
else:
raise ZeroDivisionError("denominator can't be zero")
@staticmethod
def reduce(a, b):
pgcd = math.gcd(a, b)
return a//pgcd, b//pgcd
@classmethod
def float(cls, f):
if isinstance(f, float):
den = 1
while abs(int(f) - f) > Fraction.PRECISION:
den *= 10
f *= 10
return Fraction(*Fraction.reduce(int(f), den))
else:
raise TypeError(f"{repr(f)} must be a float")
def __str__(self):
if self.den == 1:
return str(self.num)
else:
return f'{self.num}/{self.den}'
def __repr__(self):
return f'Fraction({self.num}, {self.den})'
def __eq__(self, f):
if isinstance(f, int) or isinstance(f, float):
return self.num % self.den == 0 and self.num // self.den == f
elif isinstance(f, Fraction):
return self.num * f.den == f.num * self.den
return False
def __lt__(self, f):
if isinstance(f, int) or isinstance(f, float):
return self.num / self.den < f
elif isinstance(f, Fraction):
return self.num * f.den < f.num * self.den
else:
raise NotImplemented(f"can't compare {repr(self)} and {repr(f)}")
def __gt__(self, f):
if isinstance(f, int) or isinstance(f, float):
return self.num / self.den > f
elif isinstance(f, Fraction):
return self.num * f.den > f.num * self.den
else:
raise NotImplemented(f"can't compare {repr(self)} and {repr(f)}")
def __add__(self, f):
if isinstance(f, Fraction):
num, den = Fraction.reduce(self.num * f.den + f.num * self.den, self.den * f.den)
return Fraction(num, den)
elif isinstance(f, int):
num, den = Fraction.reduce(self.num + self.den * f, self.den)
return Fraction(num, den)
elif isinstance(f, float):
return self.__add__(Fraction.float(f))
def __sub__(self, f):
if isinstance(f, Fraction):
num, den = Fraction.reduce(self.num * f.den - f.num * self.den, self.den * f.den)
return Fraction(num, den)
elif isinstance(f, int):
num, den = Fraction.reduce(self.num - self.den * f, self.den)
return Fraction(num, den)
elif isinstance(f, float):
return self.__sub__(Fraction.float(f))
def __mul__(self, f):
if isinstance(f, Fraction):
num, den = Fraction.reduce(self.num * f.num, self.den * f.den)
return Fraction(num, den)
elif isinstance(f, int):
num, den = Fraction.reduce(self.num * f, self.den)
return Fraction(num, den)
elif isinstance(f, float):
return self.__mul__(Fraction.float(f))
def simplify(self):
num, den = Fraction.reduce(self.num, self.den)
return Fraction(num, den)
def auto_simplify(self):
self.num, self.den = Fraction.reduce(self.num, self.den)
def egyptian(f):
if isinstance(f, Fraction):
if f < 1:
reste = f.simplify()
decompo = []
n = 2
while reste != 0:
unit_frac = Fraction(1, n)
while reste < unit_frac:
n += 1
unit_frac = Fraction(1, n)
decompo.append(unit_frac)
reste -= unit_frac
return decompo
else:
raise ValueError(f"{f} is greater than 1 and has no egyptian decomposition")
else:
raise TypeError('Only Fraction smaller than 1 has egyptian decomposition')