Implémenter les objets permettant de faire de la géométrie affine:
from typing import Any, Union
from fractions import Fraction
Fraction(1, 2)
Fraction(1, 2)
print(Fraction(1, 2))
1/2
Nombre = Union[int, Fraction]
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
v = Vecteur()
v
<__main__.Vecteur at 0x7f8fc435cf70>
v.x
0
v.y
0
Vecteur(x=1, y=2)
<__main__.Vecteur at 0x7f8fc435cfa0>
repr(v)
'<__main__.Vecteur object at 0x7f8fc435cf70>'
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self):
return f"Vecteur(x={self.x}, y={self.y})"
Vecteur(x=1, y=2)
Vecteur(x=1, y=2)
Vecteur()
Vecteur(x=0, y=0)
print(Vecteur())
Vecteur(x=0, y=0)
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self):
return f"Vecteur(x={self.x}, y={self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
Vecteur()
Vecteur(x=0, y=0)
print(Vecteur())
(0, 0)
Vecteur() + Vecteur()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_2236/3829631129.py in <module> ----> 1 Vecteur() + Vecteur() TypeError: unsupported operand type(s) for +: 'Vecteur' and 'Vecteur'
Pour faire une addition en fait
x + y
est d'abord remplacé par
x.__add__(y)
ensuite on aura le remplacement
Vecteur.__add__(x, y)
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self):
return f"Vecteur(x={self.x}, y={self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
def __add__(self, autre):
return Vecteur(x=self.x+autre.x, y=self.y+autre.y)
Vecteur(1, 2) + Vecteur(1, 3)
Vecteur(x=2, y=5)
2 * Vecteur()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_2236/1234919735.py in <module> ----> 1 2 * Vecteur() TypeError: unsupported operand type(s) for *: 'int' and 'Vecteur'
Comme ici on ne peut pas faire
2.__mul__(Vecteur())
car la classe int
est interne à python
on doit utiliser la méthode __rmul__
2 * Vecteur()
est remplacé après avoir échoué sur __mul__
par
Vecteur().__rmul__(2)
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self):
return f"Vecteur(x={self.x}, y={self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
def __add__(self, autre: Vecteur):
return Vecteur(x=self.x+autre.x, y=self.y+autre.y)
def __mul__(self, autre: Nombre):
return Vecteur(x=self.x*autre, y=self.y*autre)
def __rmul__(self, autre: Nombre):
return self * autre
Vecteur(1, 2) * 2
Vecteur(x=2, y=4)
2 * Vecteur(1, 3)
Vecteur(x=2, y=6)
- Vecteur(1, 3)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_2236/131461254.py in <module> ----> 1 - Vecteur(1, 3) TypeError: bad operand type for unary -: 'Vecteur'
Vecteur(1, 2) - Vecteur(1, 3)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_2236/2166496134.py in <module> ----> 1 Vecteur(1, 2) - Vecteur(1, 3) TypeError: unsupported operand type(s) for -: 'Vecteur' and 'Vecteur'
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self):
return f"Vecteur(x={self.x}, y={self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
def __add__(self, autre: Vecteur):
return Vecteur(x=self.x+autre.x, y=self.y+autre.y)
def __mul__(self, autre: Nombre):
return Vecteur(x=self.x*autre, y=self.y*autre)
def __rmul__(self, autre: Nombre):
return self * autre
def __neg__(self):
return Vecteur(x=-self.x, y=-self.y)
- Vecteur(1, 2)
Vecteur(x=-1, y=-2)
Vecteur(1, 2) - Vecteur(1, 3)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_2236/2166496134.py in <module> ----> 1 Vecteur(1, 2) - Vecteur(1, 3) TypeError: unsupported operand type(s) for -: 'Vecteur' and 'Vecteur'
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self):
return f"Vecteur(x={self.x}, y={self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
def __add__(self, autre: Vecteur):
return Vecteur(x=self.x+autre.x, y=self.y+autre.y)
def __mul__(self, autre: Nombre):
return Vecteur(x=self.x*autre, y=self.y*autre)
def __rmul__(self, autre: Nombre):
return self * autre
def __neg__(self):
return Vecteur(x=-self.x, y=-self.y)
def __sub__(self, autre):
return self + (- autre)
Vecteur(1, 2) - Vecteur(1, 3)
Vecteur(x=0, y=-1)
Vecteur(1, 2) / 2
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_2236/452967259.py in <module> ----> 1 Vecteur(1, 2) / 2 TypeError: unsupported operand type(s) for /: 'Vecteur' and 'int'
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self):
return f"Vecteur(x={self.x}, y={self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
def __add__(self, autre: "Vecteur"):
return Vecteur(x=self.x+autre.x, y=self.y+autre.y)
def __mul__(self, autre: Nombre):
return Vecteur(x=self.x*autre, y=self.y*autre)
def __rmul__(self, autre: Nombre):
return self * autre
def __neg__(self):
return Vecteur(x=-self.x, y=-self.y)
def __sub__(self, autre):
return self + (- autre)
def __truediv__(self, autre: Nombre):
return self * (Fraction(1, 1) / autre)
Vecteur(1, 2) / 3
Vecteur(x=1/3, y=2/3)
Vecteur(1, 2) | Vecteur(1, 3)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_2236/4141625625.py in <module> ----> 1 Vecteur(1, 2) | Vecteur(1, 3) TypeError: unsupported operand type(s) for |: 'Vecteur' and 'Vecteur'
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self) -> str:
return f"Vecteur(x={self.x}, y={self.y})"
def __str__(self) -> str:
return f"({self.x}, {self.y})"
def __add__(self, autre: "Vecteur") -> "Vecteur":
return Vecteur(x=self.x+autre.x, y=self.y+autre.y)
def __mul__(self, autre: Nombre) -> "Vecteur":
return Vecteur(x=self.x*autre, y=self.y*autre)
def __rmul__(self, autre: Nombre) -> "Vecteur":
return self * autre
def __neg__(self) -> "Vecteur":
return Vecteur(x=-self.x, y=-self.y)
def __sub__(self, autre: "Vecteur") -> "Vecteur":
return self + (- autre)
def __truediv__(self, autre: Nombre) -> "Vecteur":
return self * (Fraction(1, 1) / autre)
def __or__(self, autre: "Vecteur") -> Nombre:
"""Renvoie le produit scalaire des deux vecteurs."""
return self.x * autre.x + self.y * autre.y
Vecteur(1, 2) | Vecteur(1, 3)
7
Implémenter une classe Point
.
class Point:
def __init__(self, x: Nombre, y: Nombre):
self.x = x
self.y = y
def __repr__(self) -> str:
return f"Point(x={self.x}, y={self.y})"
def __str__(self) -> str:
return f"[{self.x}, {self.y}]"
def __add__(self, autre: Vecteur) -> "Point":
return Point(x=self.x+autre.x, y=self.y+autre.y)
def __sub__(self, autre: "Point") -> Vecteur:
return Vecteur(x=self.x-autre.x, y=self.y-autre.y)
Point(1, 2) + Vecteur(2, 1)
Point(x=3, y=3)
Point(1, 2) + Point(2, 1)
Point(x=3, y=3)
class Point:
def __init__(self, x: Nombre, y: Nombre):
self.x = x
self.y = y
def __repr__(self) -> str:
return f"Point(x={self.x}, y={self.y})"
def __str__(self) -> str:
return f"[{self.x}, {self.y}]"
def __add__(self, autre: Vecteur) -> "Point":
if isinstance(autre, Vecteur):
return Point(x=self.x+autre.x, y=self.y+autre.y)
else:
raise TypeError("On ne peut faire que Point + Vecteur")
def __sub__(self, autre: "Point") -> Vecteur:
return Vecteur(x=self.x-autre.x, y=self.y-autre.y)
Point(1, 2) + Point(2, 1)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_2236/3352171232.py in <module> ----> 1 Point(1, 2) + Point(2, 1) /tmp/ipykernel_2236/1736066452.py in __add__(self, autre) 14 return Point(x=self.x+autre.x, y=self.y+autre.y) 15 else: ---> 16 raise TypeError("On ne peut faire que Point + Vecteur") 17 18 def __sub__(self, autre: "Point") -> Vecteur: TypeError: On ne peut faire que Point + Vecteur
Vecteur(1, 2) + Point(2, 1)
Vecteur(x=3, y=3)
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self) -> str:
return f"Vecteur(x={self.x}, y={self.y})"
def __str__(self) -> str:
return f"({self.x}, {self.y})"
def __add__(self, autre: "Vecteur") -> "Vecteur":
if isinstance(autre, self.__class__):
return Vecteur(x=self.x+autre.x, y=self.y+autre.y)
else:
raise TypeError("On ne peut faire que Vecteur + Vecteur.")
def __mul__(self, autre: Nombre) -> "Vecteur":
return Vecteur(x=self.x*autre, y=self.y*autre)
def __rmul__(self, autre: Nombre) -> "Vecteur":
return self * autre
def __neg__(self) -> "Vecteur":
return Vecteur(x=-self.x, y=-self.y)
def __sub__(self, autre: "Vecteur") -> "Vecteur":
return self + (- autre)
def __truediv__(self, autre: Nombre) -> "Vecteur":
return self * (Fraction(1, 1) / autre)
def __or__(self, autre: "Vecteur") -> Nombre:
"""Renvoie le produit scalaire des deux vecteurs."""
return self.x * autre.x + self.y * autre.y
Vecteur(1, 2) + Point(2, 1)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_2236/3392772751.py in <module> ----> 1 Vecteur(1, 2) + Point(2, 1) /tmp/ipykernel_2236/2475645050.py in __add__(self, autre) 14 return Vecteur(x=self.x+autre.x, y=self.y+autre.y) 15 else: ---> 16 raise TypeError("On ne peut faire que Vecteur + Vecteur.") 17 18 def __mul__(self, autre: Nombre) -> "Vecteur": TypeError: On ne peut faire que Vecteur + Vecteur.
Point(1, 2) - Vecteur(1, 2)
Vecteur(x=0, y=0)
class Point:
def __init__(self, x: Nombre, y: Nombre):
self.x = x
self.y = y
def __repr__(self) -> str:
return f"Point(x={self.x}, y={self.y})"
def __str__(self) -> str:
return f"[{self.x}, {self.y}]"
def __add__(self, autre: Vecteur) -> "Point":
if isinstance(autre, Vecteur):
return Point(x=self.x+autre.x, y=self.y+autre.y)
else:
raise TypeError("On ne peut faire que Point + Vecteur")
def __sub__(self, autre: "Point") -> Vecteur:
if isinstance(autre, self.__class__):
return Vecteur(x=self.x-autre.x, y=self.y-autre.y)
else:
raise TypeError("On ne peut faire que Point - Point")
Point(1, 2) - Vecteur(1, 2)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_2236/317016459.py in <module> ----> 1 Point(1, 2) - Vecteur(1, 2) /tmp/ipykernel_2236/640575544.py in __sub__(self, autre) 20 return Vecteur(x=self.x-autre.x, y=self.y-autre.y) 21 else: ---> 22 raise TypeError("On ne peut faire que Point - Point") TypeError: On ne peut faire que Point - Point
Vecteur() == Vecteur()
False
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self) -> str:
return f"Vecteur(x={self.x}, y={self.y})"
def __str__(self) -> str:
return f"({self.x}, {self.y})"
def __add__(self, autre: "Vecteur") -> "Vecteur":
if isinstance(autre, self.__class__):
return Vecteur(x=self.x+autre.x, y=self.y+autre.y)
else:
raise TypeError("On ne peut faire que Vecteur + Vecteur.")
def __mul__(self, autre: Nombre) -> "Vecteur":
return Vecteur(x=self.x*autre, y=self.y*autre)
def __rmul__(self, autre: Nombre) -> "Vecteur":
return self * autre
def __neg__(self) -> "Vecteur":
return Vecteur(x=-self.x, y=-self.y)
def __sub__(self, autre: "Vecteur") -> "Vecteur":
return self + (- autre)
def __truediv__(self, autre: Nombre) -> "Vecteur":
return self * (Fraction(1, 1) / autre)
def __or__(self, autre: "Vecteur") -> Nombre:
"""Renvoie le produit scalaire des deux vecteurs."""
return self.x * autre.x + self.y * autre.y
def __eq__(self, autre: Any) -> bool:
if isinstance(autre, self.__class__):
return self.x == autre.x and self.y == autre.y
else:
return False
Vecteur(1, 2) == Vecteur(1, 2)
True
Vecteur(1, 2) is Vecteur(1, 2)
False
class Point:
def __init__(self, x: Nombre, y: Nombre):
self.x = x
self.y = y
def __repr__(self) -> str:
return f"Point(x={self.x}, y={self.y})"
def __str__(self) -> str:
return f"[{self.x}, {self.y}]"
def __add__(self, autre: Vecteur) -> "Point":
if isinstance(autre, Vecteur):
return Point(x=self.x+autre.x, y=self.y+autre.y)
else:
raise TypeError("On ne peut faire que Point + Vecteur")
def __sub__(self, autre: "Point") -> Vecteur:
if isinstance(autre, self.__class__):
return Vecteur(x=self.x-autre.x, y=self.y-autre.y)
else:
raise TypeError("On ne peut faire que Point - Point")
def __eq__(self, autre: Any) -> bool:
if isinstance(autre, self.__class__):
return self.x == autre.x and self.y == autre.y
else:
return False
Point(1, 2) == Point(1, 2)
True
Point(1, 2) == Vecteur(1, 2)
False
Point(1, 2) != Point(0, 0)
True
p = Point(1, 2)
p != p
False
Implémenter les réflexions par rapport aux droites.
class Vecteur:
def __init__(self, x: Nombre=0, y: Nombre=0):
self.x = x
self.y = y
def __repr__(self) -> str:
return f"Vecteur(x={self.x}, y={self.y})"
def __str__(self) -> str:
return f"({self.x}, {self.y})"
def __add__(self, autre: "Vecteur") -> "Vecteur":
if isinstance(autre, self.__class__):
return Vecteur(x=self.x+autre.x, y=self.y+autre.y)
else:
raise TypeError("On ne peut faire que Vecteur + Vecteur.")
def __mul__(self, autre: Nombre) -> "Vecteur":
return Vecteur(x=self.x*autre, y=self.y*autre)
def __rmul__(self, autre: Nombre) -> "Vecteur":
return self * autre
def __neg__(self) -> "Vecteur":
return Vecteur(x=-self.x, y=-self.y)
def __sub__(self, autre: "Vecteur") -> "Vecteur":
return self + (- autre)
def __truediv__(self, autre: Nombre) -> "Vecteur":
return self * (Fraction(1, 1) / autre)
def __or__(self, autre: "Vecteur") -> Nombre:
"""Renvoie le produit scalaire des deux vecteurs."""
return self.x * autre.x + self.y * autre.y
def __eq__(self, autre: Any) -> bool:
if isinstance(autre, self.__class__):
return self.x == autre.x and self.y == autre.y
else:
return False
def __xor__(self, autre: Vecteur) -> Nombre:
"""Produit vectoriel."""
if isinstance(autre, self.__class__):
return self.x * autre.y - self.y * autre.x
else:
raise TypeError("On ne fait le produit vectoriel qu'entre vecteurs!")
Vecteur(1, 2) ^ Vecteur(2, 4)
0
class Droite:
def __init__(self, p1: Point, p2: Point):
if not (isinstance(p1, Point) and isinstance(p2, Point)):
raise TypeError("On utilise des points pour définir une droite.")
if p1 == p2:
raise ValueError("On définit une droite par des points distincts.")
self.p1 = p1
self.p2 = p2
def __repr__(self) -> str:
return f"Droite(p1={self.p1}, p2={self.p2}"
def __str__(self) -> str:
return f"({self.p1} {self.p2})"
def __contains__(self, p: Point) -> bool:
if isinstance(p, Point):
if p == self.p1:
return True
return (self.p2 - self.p1) ^ (p - self.p1) == 0
else:
raise TypeError("On teste un point dans une droite.")
def __eq__(self, autre: Any) -> bool:
if isinstance(autre, self.__class__):
return (autre.p1 in self) and (autre.p2 in self)
else:
return False