On souhaite dans cet exercice créer une classe Entier permettant de représenter des nombres entiers positifs ou nuls, de tester leur égalité, de les additionner et les soustraire.
On fournit donc une classe Entier dont l'interface est détaillée ci-dessous dans le cadre d'un exemple :
a=Entier() : crée un objet représentant l'entier \(0\) et l'affecte à la variable a ;
a.incremente() : augmente la valeur de l'entier représenté par a de une unité. a représente désormais l'entier \(1\) ;
a.est_nul() : renvoie le booléen indiquant si a représente l'entier nul. Dans le cas présent, cette expression est évaluée à False ;
b=a.copie() : crée un entier de même valeur que a et l'affecte à la variable b. Ces deux objets sont distincts : modifier l'un n'a pas d'incidence sur l'autre ;
b=b.decremente() : diminue la valeur de l'entier représenté par b de une unité. b représente désormais l'entier \(0\), a représente toujours \(1\).
La méthode decremente génère une ValueError si l'entier auquel on l'applique représente \(0\). Il est en effet impossible de représenter un entier inférieur à \(0\) dans le cadre des entiers positifs.
Il est aussi possible de tester l'égalité de deux entiers en faisant par exemple a==b qui, dans le cas présent, est évalué à False.
La classe Entier est fournie pour information ci-dessous.
Classe Entier
Les entiers sont représentés par des listes imbriquées. Ainsi :
\(0\) est représenté par la liste vide [],
\(1\) est représenté par la liste contenant une liste vide [[]],
\(2\) est représenté par la liste contenant une liste contenant une liste vide [[[]]],
etc...
Le code ci-dessous est fourni à titre indicatif. On doit résoudre l'exercice en n'utilisant que les méthodes est_nul, copie, incremente et decremente.
classEntier:def__init__(self):"Crée un entier égal à zéro"self.liste=[]defest_nul(self):"Indique si cet entier est nul ou non"returnself.liste==[]defincremente(self):"Augmente la valeur de cet entier de un"self.liste=[self.liste]defdecremente(self):"Diminue, si possible, la valeur de cet entier de un"ifself.est_nul():raiseValueError("L'entier est nul")else:self.liste=self.liste.pop()defcopie(self):"Renvoie un entier égal à cet entier"nouveau=Entier()whilenouveau.liste!=self.liste:nouveau.incremente()returnnouveaudef__eq__(self,autre):"Teste l'égalité de deux entiers"returnself.liste==autre.listedef__repr__(self):"Renvoie la représentation d'un objet de cet entier"returnf"'Entier' représenté par {self.liste}"
La méthode __eq__ a un statut particulier. Elle fait partie des méthodes spéciales de Python. Définir la méthode __eq__ dans une classe permet de tester l'égalité de deux instances de cette classe en faisant a == b. Dans ce cas, Python exécute l'action a.__eq__(b).
De la même façon, __repr__ est une méthode spéciale permettant de représenter un objet dans la console.
On souhaite mettre en place l'addition et la soustraction d'entiers. Pour cela on complète les méthodes spéciales __add__ et __sub__ qui sont appelées lorsque l'on exécute a + b et a - b. Ces méthodes créent chacune un nouvel entier représentant le nombre correspondant à l'opération demandée.
Attention, certaines soustractions sont impossibles dans le cadre des entiers positifs ou nuls. Dans ce cas la méthode __sub__ générera une erreur du type ArithmeticError.
Exemples
Ci-dessous, les objets zero, un, deux et trois sont des instances de la classe Entierreprésentant les nombres entiers correspondants.
Il est possible avec Python d'interrompre l'exécution du code en générant une erreur. Pour ce faire on utilise l'instruction raise<Erreur>. La méthode decremente génère ainsi une erreur : raiseValueError("L'entier est nul").
Dans le cas présent, si une soustraction impossible est effectuée, on saisira raiseArithmeticError("Opération impossible").
Python propose de plus un mécanisme permettant d'intercepter de telles erreurs sans interrompre l'exécution. Cette structure utilise les mots clés try et except et est utilisée dans les tests de cet exercice.
Contrainte
Dans tout l'exercice, il est interdit d'accéder aux attributs des objets de la classe Entier.
On n'utilisera que les méthodes incremente, decremente et copie.
###(Dés-)Active le code après la ligne # Tests (insensible à la casse) (Ctrl+I)
Entrer ou sortir du mode "deux colonnes" (Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran" (Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
# Tests(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)