POO

Opérateurs : exercices

Une classe Rationnel

Définir une classe Rationnel. Un objet rationnel présentera deux attributs entiers : numerateur et denominateur.

On devra pouvoir additionner, soustraire, multiplier, diviser deux rationnels.

  • un code possible

from math import gcd

class Rationnel:
	
	def __init__(self, numerateur, denominateur = 1):
		self.numerateur = numerateur
		self.denominateur = denominateur

	def __add__(self, f):
		num = self.numerateur * f.denominateur + f.numerateur * self.denominateur
		den = self.denominateur * f.denominateur
		num, den = num//gcd(num, den), den//gcd(num, den)
		return Rationnel(num, den)
		
	def __sub__(self, f):
		num = self.numerateur * f.denominateur - f.numerateur * self.denominateur
		den = self.denominateur * f.denominateur
		num, den = num//gcd(num, den), den//gcd(num, den)
		return Rationnel(num, den)
		
	def __mul__(self, f):
		num = self.numerateur * f.numerateur  
		den = self.denominateur * f.denominateur
		num, den = num//gcd(num, den), den//gcd(num, den)
		return Rationnel(num, den)
		
	def __floordiv__(self, f):
		num = self.numerateur * f.denominateur
		den = self.denominateur * f.numerateur
		num, den = num//gcd(num, den), den//gcd(num, den)
		return Rationnel(num, den)
		
	def __neg__(self):
		return Rationnel(-self.numerateur, self.denominateur)
		
	def __str__(self):
		if self.numerateur == 0: 
			return str(self.numerateur)
		else:
			return str(self.numerateur) + '/' + str(self.denominateur)
		
		
		
p = Rationnel(2)
q = Rationnel(3,4)
print(p+q)
print(p-q)
print(q-p)
print(p*q)
print(p//q)

print( -Rationnel(2,3))
print( -Rationnel(-2,3))
print( -Rationnel(2,-3))
print( -Rationnel(2,3) + Rationnel(2,3) )

Une classe Parcours

Définir une classe Parcours. Un objet de type Parcours présentera deux attributs : distance et vitesse. L'attribut distance est la longueur en km d'un parcours et l'attribut vitesse est la vitesse moyenne, en km/h, qui a été réalisée pour parcourir la distance.

On devra pouvoir additionner deux parcours : la distance de la somme des parcours sera la somme des distances, la vitesse devra correspondre à la vitesse moyenne sur l'ensemble.

  • un code possible

On rappelle que la vitesse moyenne sur les deux parcours cumulés n'est pas dans ce cas la moyenne arithmétique des vitesses.


class Parcours:
	
	def __init__(self, distance, vitesse):
		self.vitesse = vitesse
		self.distance = distance
		
	def __add__(self, p):
		d = self.distance + p.distance
		v = d/(self.distance/self.vitesse + p.distance/p.vitesse)
		return Parcours(d, v)
		
	def __str__(self):
		return "Distance : {}, Vitesse moyenne : {}.".format(self.distance, self.vitesse)
		
		
p1 = Parcours(1, 50)
p2 = Parcours(3, 100)
print(p1+p2)

Résistance équivalente

Définir une classe Resistor devant modéliser une résistance électrique. Un objet Resistor présentera un attribut resistance et définir les opérateurs // (__floordiv__) et - (__sub__) correspondant respectivement à l'association en parallèle ou en série de deux résistors.

On rappelle que la résistance équivalente à l'association en série de deux composants de résistances $R_1$ et $R_2$ est $ R_1+R_2$, et que s'il sont associés en parallèle c'est $\left(\frac{1}{R_1}+\frac{1}{R_2}\right)^{-1}.$

Pour afficher la résistance d'un objet Resistor dans la console, on définira la méthode __repr__(self). Elle est aussi utilisée par la str() quand __str__(self) n'est pas définie.

  • un code possible
  • un autre code


    
class Resistor:
    def __init__(self, resistance):
        self.resistance = resistance

    def __sub__(self, b):
        return Resistor(self.resistance+b.resistance)

    def __floordiv__(self, b):
        return Resistor(1/(1/self.resistance+1/b.resistance))

    def __repr__(self):
        return str(self.resistance)

Python permet de manipuler $+\infty$ dans les calculs algébriques. On en tire parti pour gérer les courts-circuits (résistance nulle) ou les circuits ouverts (résistance infinie) dans les calculs de résistance équivalente.


 
class Resistor:
    def __init__(self, resistance):
        self.resistance = resistance

    def __sub__(self, b):
        return Resistor(self.resistance+b.resistance)

    def __floordiv__(self, b):
        if self.resistance == 0 or b.resistance == 0:
            return Resistor(0)
        elif self.resistance == float('inf') and b.resistance == float('inf'):
            return Resistor(float('inf'))
        else:
            return Resistor(1/(1/self.resistance+1/b.resistance))

    def __repr__(self):
        return str(self.resistance)

circuit_ouvert = Resistor(float('inf'))
court_circuit  = Resistor(0)

A = Resistor(2)

# résistance de valeur 2 en parallèle avec un court-circuit
print(A//court_circuit)

# résistance de valeur 2 en série avec un circuit ouvert
print(A-circuit_ouvert)