diff --git a/11-pythonic-obj/vector2d_v3.py b/11-pythonic-obj/vector2d_v3.py index 5812dcf..6f5e465 100644 --- a/11-pythonic-obj/vector2d_v3.py +++ b/11-pythonic-obj/vector2d_v3.py @@ -79,8 +79,8 @@ Tests of hashing: >>> v1 = Vector2d(3, 4) >>> v2 = Vector2d(3.1, 4.2) - >>> hash(v1), hash(v2) - (7, 384307168202284039) + >>> hash(v1) != hash(v2) + True >>> len(set([v1, v2])) 2 @@ -122,7 +122,7 @@ class Vector2d: return tuple(self) == tuple(other) def __hash__(self): - return hash(self.x) ^ hash(self.y) + return hash((self.x, self.y)) def __abs__(self): return math.hypot(self.x, self.y) diff --git a/11-pythonic-obj/vector2d_v3_prophash.py b/11-pythonic-obj/vector2d_v3_prophash.py index 2eca4ec..37a8e4a 100644 --- a/11-pythonic-obj/vector2d_v3_prophash.py +++ b/11-pythonic-obj/vector2d_v3_prophash.py @@ -81,8 +81,8 @@ Tests of hashing: >>> v1 = Vector2d(3, 4) >>> v2 = Vector2d(3.1, 4.2) - >>> hash(v1), hash(v2) - (7, 384307168202284039) + >>> hash(v1) != hash(v2) + True >>> len(set([v1, v2])) 2 @@ -131,7 +131,7 @@ class Vector2d: # BEGIN VECTOR_V3_HASH def __hash__(self): - return hash(self.x) ^ hash(self.y) + return hash((self.x, self.y)) # END VECTOR_V3_HASH def __abs__(self): diff --git a/11-pythonic-obj/vector2d_v3_slots.py b/11-pythonic-obj/vector2d_v3_slots.py index a9d700d..cc091b0 100644 --- a/11-pythonic-obj/vector2d_v3_slots.py +++ b/11-pythonic-obj/vector2d_v3_slots.py @@ -78,8 +78,8 @@ Tests of hashing: >>> v1 = Vector2d(3, 4) >>> v2 = Vector2d(3.1, 4.2) - >>> hash(v1), hash(v2) - (7, 384307168202284039) + >>> hash(v1) != hash(v2) + True >>> len(set([v1, v2])) 2 @@ -129,7 +129,7 @@ class Vector2d: return tuple(self) == tuple(other) def __hash__(self): - return hash(self.x) ^ hash(self.y) + return hash((self.x, self.y)) def __abs__(self): return math.hypot(self.x, self.y) diff --git a/16-op-overloading/vector2d_v3.py b/16-op-overloading/vector2d_v3.py deleted file mode 100644 index 5812dcf..0000000 --- a/16-op-overloading/vector2d_v3.py +++ /dev/null @@ -1,151 +0,0 @@ -""" -A 2-dimensional vector class - - >>> v1 = Vector2d(3, 4) - >>> print(v1.x, v1.y) - 3.0 4.0 - >>> x, y = v1 - >>> x, y - (3.0, 4.0) - >>> v1 - Vector2d(3.0, 4.0) - >>> v1_clone = eval(repr(v1)) - >>> v1 == v1_clone - True - >>> print(v1) - (3.0, 4.0) - >>> octets = bytes(v1) - >>> octets - b'd\\x00\\x00\\x00\\x00\\x00\\x00\\x08@\\x00\\x00\\x00\\x00\\x00\\x00\\x10@' - >>> abs(v1) - 5.0 - >>> bool(v1), bool(Vector2d(0, 0)) - (True, False) - - -Test of ``.frombytes()`` class method: - - >>> v1_clone = Vector2d.frombytes(bytes(v1)) - >>> v1_clone - Vector2d(3.0, 4.0) - >>> v1 == v1_clone - True - - -Tests of ``format()`` with Cartesian coordinates: - - >>> format(v1) - '(3.0, 4.0)' - >>> format(v1, '.2f') - '(3.00, 4.00)' - >>> format(v1, '.3e') - '(3.000e+00, 4.000e+00)' - - -Tests of the ``angle`` method:: - - >>> Vector2d(0, 0).angle() - 0.0 - >>> Vector2d(1, 0).angle() - 0.0 - >>> epsilon = 10**-8 - >>> abs(Vector2d(0, 1).angle() - math.pi/2) < epsilon - True - >>> abs(Vector2d(1, 1).angle() - math.pi/4) < epsilon - True - - -Tests of ``format()`` with polar coordinates: - - >>> format(Vector2d(1, 1), 'p') # doctest:+ELLIPSIS - '<1.414213..., 0.785398...>' - >>> format(Vector2d(1, 1), '.3ep') - '<1.414e+00, 7.854e-01>' - >>> format(Vector2d(1, 1), '0.5fp') - '<1.41421, 0.78540>' - - -Tests of `x` and `y` read-only properties: - - >>> v1.x, v1.y - (3.0, 4.0) - >>> v1.x = 123 - Traceback (most recent call last): - ... - AttributeError: can't set attribute - - -Tests of hashing: - - >>> v1 = Vector2d(3, 4) - >>> v2 = Vector2d(3.1, 4.2) - >>> hash(v1), hash(v2) - (7, 384307168202284039) - >>> len(set([v1, v2])) - 2 - -""" - -from array import array -import math - -class Vector2d: - typecode = 'd' - - def __init__(self, x, y): - self.__x = float(x) - self.__y = float(y) - - @property - def x(self): - return self.__x - - @property - def y(self): - return self.__y - - def __iter__(self): - return (i for i in (self.x, self.y)) - - def __repr__(self): - class_name = type(self).__name__ - return '{}({!r}, {!r})'.format(class_name, *self) - - def __str__(self): - return str(tuple(self)) - - def __bytes__(self): - return (bytes([ord(self.typecode)]) + - bytes(array(self.typecode, self))) - - def __eq__(self, other): - return tuple(self) == tuple(other) - - def __hash__(self): - return hash(self.x) ^ hash(self.y) - - def __abs__(self): - return math.hypot(self.x, self.y) - - def __bool__(self): - return bool(abs(self)) - - def angle(self): - return math.atan2(self.y, self.x) - - def __format__(self, fmt_spec=''): - if fmt_spec.endswith('p'): - fmt_spec = fmt_spec[:-1] - coords = (abs(self), self.angle()) - outer_fmt = '<{}, {}>' - else: - coords = self - outer_fmt = '({}, {})' - components = (format(c, fmt_spec) for c in coords) - return outer_fmt.format(*components) - - @classmethod - def frombytes(cls, octets): - typecode = chr(octets[0]) - memv = memoryview(octets[1:]).cast(typecode) - return cls(*memv)