Search
This week we will work with classes representing:
class Point: """Representation of a 2D point.""" def __init__(self, x, y): """Initializes the Point object. Attributes: x (float): x coordinate of the point. y (float): y coordinate of the point. """ self.x = x self.y = y def move(self, dx, dy): return Point(self.x + dx, self.y + dy) def __str__(self): return "Point(x={}, y={})".format(self.x, self.y) def __eq__(self, other): return (self.x == other.x and self.y == other.y)
class Rectangle: """Representation of a rectangle""" def __init__(self, corner, height, width): """Initializes the Rectangle object. Attributes: corner (Point): coordinates of the left upper corner of the rectangle. height (float): height of the rectangle. width (float): width of the rectangle. """ self.corner = corner self.height = height self.width = width def __str__(self): return "Rectangle({}, h={}, w={})".format(str(self.corner), self.height, self.width) def __eq__(self, other): return (self.corner == other.corner and self.height == other.height and self.width == other.width)
If a function/method operating on an object is pure (returns a modified copy of the original object), it is common to use the dot operator multiple times.
if __name__ == "__main__": p1 = Point(2, 3) print(p1) # dot operator composition p2 = p1.move(1, -2) print(p2) p3 = p1.move(1, 0).move(0, -2) print(p3)
Now, let's try changing the object's attributes via a (global) function:
def move_point(p, dx, dy): p.x += dx p.y += dy
p1 = Point(2, 3) # objects mutable print(p1) move_point(p1, 2, 3) print(p1)
There are several ways to copy an object, each of which copies an object in a slight difference sense:
=
copy.copy()
copy.deepcopy()
There are also 2 ways of comparing 2 objects:
is
is not
==
!=
__eq__()
1. Copy using the “=” operator. The 2 variables pointing to the exact same object in memory.
if __name__ == "__main__": r1 = Rectangle(Point(2, 3), 10, 8) print("r1:", r1) # copy using the "=" operator # only reference is copied # difference variables pointing to the exact same object r2 = r1 print("r1 == r2: ", r1 == r2) print("r1 is r2: ", r1 is r2) print("\nr2.height = 5") r2.height = 5 print("r1:", r1) print("r2:", r2) print("r1 == r2: ", r1 == r2) print("r1 is r2: ", r1 is r2) print("\nr2.corner.x = 0") r2.corner.x = 0 print("r1:", r1) print("r2:", r2) print("r1 == r2: ", r1 == r2) print("r1 is r2: ", r1 is r2)
r1: Rectangle(Point(x=2, y=3), h=10, w=8) r1 == r2: True r1 is r2: True r2.height = 5 r1: Rectangle(Point(x=2, y=3), h=5, w=8) r2: Rectangle(Point(x=2, y=3), h=5, w=8) r1 == r2: True r1 is r2: True r2.corner.x = 0 r1: Rectangle(Point(x=0, y=3), h=5, w=8) r2: Rectangle(Point(x=0, y=3), h=5, w=8) r1 == r2: True r1 is r2: True
2. Copy using the copy.copy() fuction (shallow copy). Separate copies up to the 1st level.
if __name__ == "__main__": r1 = Rectangle(Point(2, 3), 10, 8) print("r1:", r1) # copy using the copy.copy() function # copy only 1 level deep # called a shallow copy r3 = copy.copy(r1) print("r1 == r3: ", r1 == r3) print("r1 is r3: ", r1 is r3) print("\nr3.height = 5") r3.height = 5 print("r1:", r1) print("r3:", r3) print("r1 == r3: ", r1 == r3) print("r1 is r3: ", r1 is r3) print("\nr3.corner.x = 0") r3.corner.x = 0 print("r1:", r1) print("r3:", r3) print("r1 == r3: ", r1 == r3) print("r1 is r3: ", r1 is r3)
r1: Rectangle(Point(x=2, y=3), h=10, w=8) r1 == r3: True r1 is r3: False r3.height = 5 r1: Rectangle(Point(x=2, y=3), h=10, w=8) r3: Rectangle(Point(x=2, y=3), h=5, w=8) r1 == r3: False r1 is r3: False r3.corner.x = 0 r1: Rectangle(Point(x=0, y=3), h=10, w=8) r3: Rectangle(Point(x=0, y=3), h=5, w=8) r1 == r3: False r1 is r3: False
Shallow copy (1st level copy)
1st level variable change
2nd level variable change
3. Copy using the copy.deepcopy() function (deep copy). Separate copies including child objects.
if __name__ == "__main__": r1 = Rectangle(Point(2, 3), 10, 8) print("r1:", r1) # copy using the copy.deepcopy() function # copy of the child objects (recursively) # called a deep copy r4 = copy.deepcopy(r1) print("r1 == r4: ", r1 == r4) print("r1 is r4: ", r1 is r4) print("\nr4.height = 5") r4.height = 5 print("r1:", r1) print("r4:", r4) print("r1 == r4: ", r1 == r4) print("r1 is r4: ", r1 is r4) print("\nr4.corner.x = 0") r4.corner.x = 0 print("r1:", r1) print("r4:", r4) print("r1 == r4: ", r1 == r4) print("r1 is r4: ", r1 is r4)
r1: Rectangle(Point(x=2, y=3), h=10, w=8) r1 == r4: True r1 is r4: False r4.height = 5 r1: Rectangle(Point(x=2, y=3), h=10, w=8) r4: Rectangle(Point(x=2, y=3), h=5, w=8) r1 == r4: False r1 is r4: False r4.corner.x = 0 r1: Rectangle(Point(x=2, y=3), h=10, w=8) r4: Rectangle(Point(x=0, y=3), h=5, w=8) r1 == r4: False r1 is r4: False
Motivation: The + operator will perform arithmetic addition on two numbers, merge two lists, or concatenate two strings. How should it work with your class?
+
__str__(self)
str()
format()
__eq__(self, other)
__add__(self, other)
__lt__(self, other)
<
class Point: """Representation of a 2D point.""" def __init__(self, x, y): """Initializes the Point object. Attributes: x (float): x coordinate of the point. y (float): y coordinate of the point. """ self.x = x self.y = y def __add__(self, other): return Point(self.x + other.x, self.y + other.y) def __lt__(self, other): norm_self_quadr = self.x ** 2 + self.y ** 2 norm_other_quadr = other.x ** 2 + other.y ** 2 return norm_self_quadr < norm_other_quadr
Create a class representing a 2D point in polar coordinates. Each such point is characterized by an ordered pair $(r, \phi)$:
Your class must have the following structure. Copy-paste the following code and implement the (special) methods:
Note:
__mul__(self, other)
__truediv__(self, other)
⇐
>
>=
Required filename: 11_weekly_hw.py.
11_weekly_hw.py
class PointPolar: """represents a point in polar coordinates""" def __init__(self, r, phi): """ :param r: float, norm of the point :param phi: float, angular coordinate """ def __str__(self): """ >>> p1 = PointPolar(5.1, 0.2) >>> print(p1) Point: r=5.1, phi=0.2 """ def __eq__(self, other): """Equality given by both parameters""" def __mul__(self, other): """Multiplication of 2 points""" def __truediv__(self, other): """Division of 2 points""" def __lt__(self, other): """Is self < other?""" def __le__(self, other): """Is self <= other?""" def __gt__(self, other): """Is self > other?""" def __ge__(self, other): """Is self >= other?"""
The assignment will be explained more in detail during this week's lecture.