Ainsi que vous l'avez vérifié à la fin de la leçon précédente, Python ne sait pas comment additionner un entier à une Fraction. Nous pouvons corriger cela assez facilement en faisant ce qui suit :
La deuxième étape peut être accomplie avec une fonction ressemblant à ce qui suit :
def convertirEnFraction(objet):
'''Convertit "int" et "long" en Fractions''' if isinstance(objet, (int, long)):
return Fraction(objet)
else:
raise NotImplementedError
Nous commençons par vérifier si l'objet est un entier [int ou peut-être long] et, si c'est le cas, créons une nouvelle Fraction à partir de cet objet (l'entier sera le numérateur de la nouvelle Fraction). Puisque nous voulons que les fractions soient de la forme (entier/entier), nous ne permettrons aucun autre type d'objet ; en levant une exception, nous informons l'utilisateur qu'il a tenté une opération qui n'est pas permise.
La première étape sera une chose que nous ajouterons au début de chaque opération. Voici le nouveau code qui fait justement cela [Notez que nous avons inclu la conversion en Fractions comme une méthode de cette classe].
1 def gcd(a, b):
2 '''gcd retourne le plus grand commun diviseur (greatest common divisor)
3 de 2 entiers donnés.''' 4 while b:
5 a, b = b, a%b
6 return a
7 8 class Fraction(object):
9 def __init__(self, numerateur, denominateur=1):
10 num, denom = self.simplifier(numerateur, denominateur)
11 self.num = num
12 self.denom = denom
13
14 def __str__(self):
15 if self.denom == 1:
16 return "(%s)"%self.num
17 return "(%s/%s)"%(self.num, self.denom)
18 19 def __mul__(self, autre):
20 if not isinstance(autre, Fraction):
21 autre = self.convertirEnFraction(autre)
22 num = self.num * autre.num
23 denom = self.denom * autre.denom
24 return Fraction(num, denom)
25 26 def __div__(self, autre):
27 if not isinstance(autre, Fraction):
28 autre = self.convertirEnFraction(autre)
29 num = self.num * autre.denom
30 denom = self.denom * autre.num
31 return Fraction(num, denom)
32 33 def __add__(self, autre):
34 if not isinstance(autre, Fraction):
35 autre = self.convertirEnFraction(autre)
36 denom = self.denom * autre.denom
37 num = self.num*autre.denom + self.denom*autre.num
38 return Fraction(num, denom)
39 40 def __sub__(self, autre):
41 if not isinstance(autre, Fraction):
42 other = self.convertirEnFraction(autre)
43 denom = self.denom * autre.denom
44 num = self.num*autre.denom - self.denom*autre.num
45 return Fraction(num, denom)
46 47 def simplifier(self, a, b):
48 '''divise deux entiers par leur facteur commun.''' 49 facteur_commun = gcd(a, b)
50 a /= facteur_commun
51 b /= facteur_commun
52 return a, b
53 54 def convertirEnFraction(self, objet):
55 '''Convertit "int" et "long" en Fractions''' 56 if isinstance(objet, (int, long)):
57 return Fraction(objet)
58 else:
59 raise NotImplementedError
60 61 #== zone de test ci-dessous ===
62 63 if __name__ == "__main__":
64 a = Fraction(1, 2)
65 b = Fraction(3, 1)
66 assert str(a) == "(1/2)" 67 assert str(b) == "(3)" 68 assert str(a*b) == "(3/2)" 69 c = Fraction(1, 3)
70 assert str(b*c) == "(1)" 71 d = Fraction(5, 10)
72 assert str(d) == "(1/2)" 73 assert str(a/b) == "(1/6)" 74 assert str(a/a) == "(1)" 75 assert str(a+a) == "(1)" 76 assert str(b+b) == "(6)" 77 assert str(a+b) == "(7/2)" 78 assert str(c+c) == "(2/3)" 79 assert str(a-a) == "(0)" 80 assert str(a-b) == "(-5/2)" 81 assert str(a-c) == "(1/6)" 82 assert str(a+1) == "(3/2)" 83 assert str(a*2) == "(1)" 84 assert str(b-1) == "(2)" 85 assert str(b/3) == "(1)"
Si vous pensez que nous avons fini, essayez ce qui suit :
un = Fraction(1)
print 1 + un
Pouvez-vous réfléchir à ce qui fait que cela ne va pas ?