From 9d91755a3ad84e0d10c0861134475f55577103e3 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sun, 9 Jun 2019 16:54:22 -0400 Subject: [PATCH 1/6] Vector.__bool__: Add docstring and example usage. --- ppb_vector/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ppb_vector/__init__.py b/ppb_vector/__init__.py index 591e7c83..51db0369 100644 --- a/ppb_vector/__init__.py +++ b/ppb_vector/__init__.py @@ -147,6 +147,11 @@ def _unpack(value: VectorLike) -> typing.Tuple[float, float]: raise ValueError(f"Cannot use {value} as a vector-like") def __bool__(self) -> bool: + """Check whether the vector is non-zero. + + >>> assert Vector(1, 1) + >>> assert not Vector(0, 0) + """ return self != (0, 0) @property From 6fc50307c4f05431785250636ef5eb7ade2614b2 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sun, 9 Jun 2019 16:58:47 -0400 Subject: [PATCH 2/6] Vector.__add__: Document that vector-like + vector works I don't believe it would make sense to have a separate entry for __radd__. --- docs/index.rst | 2 +- ppb_vector/__init__.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index e7691712..986155de 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,7 +11,7 @@ PPB's 2D Vector class .. autoclass:: ppb_vector.Vector :members: :special-members: - :exclude-members: __init__, __repr__, __weakref__, scale + :exclude-members: __init__, __radd__, __repr__, __weakref__, scale .. autoattribute:: x :annotation: : float diff --git a/ppb_vector/__init__.py b/ppb_vector/__init__.py index 51db0369..f2613cc6 100644 --- a/ppb_vector/__init__.py +++ b/ppb_vector/__init__.py @@ -189,6 +189,8 @@ def __add__(self, other: VectorLike) -> 'Vector': >>> Vector(1, 0) + (0, 1) Vector(1.0, 1.0) + >>> (0, 1) + Vector(1, 0) + Vector(1.0, 1.0) """ try: other_x, other_y = Vector._unpack(other) From 7fa6c2c9b982af1467c939ca339b097d311dbf8d Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sun, 9 Jun 2019 17:08:31 -0400 Subject: [PATCH 3/6] Vector.dot: Improve the docstring - Use a verbal sentence for the first line. - Provide an example, with the same values as in __mul__ - Show the equivalence to __mul__ (same as scale_by) --- ppb_vector/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ppb_vector/__init__.py b/ppb_vector/__init__.py index f2613cc6..561740a7 100644 --- a/ppb_vector/__init__.py +++ b/ppb_vector/__init__.py @@ -219,10 +219,17 @@ def __sub__(self, other: VectorLike) -> 'Vector': return Vector(self.x - other_x, self.y - other_y) def dot(self, other: VectorLike) -> float: - """Dot product of two vectors. + """Compute the dot product of two vectors. :param other: A :py:class:`Vector` or a vector-like. For a description of vector-likes, see :py:func:`__new__`. + + >>> Vector(1, 1).dot((-1, -1)) + -2.0 + + This can also be expressed with :py:meth:`* <__mul__>`: + + >>> assert Vector(1, 2).dot([2, 1]) == Vector(1, 2) * [2, 1] """ other_x, other_y = Vector._unpack(other) return self.x * other_x + self.y * other_y From 3659d75a4aa2fc0447b86778c2f74bfbd5813c07 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sun, 9 Jun 2019 17:20:33 -0400 Subject: [PATCH 4/6] Vector.scale_by: Improve the docstring - Use the imperative form in the description. - Simplify the __mul__ example by using an assert --- ppb_vector/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ppb_vector/__init__.py b/ppb_vector/__init__.py index 561740a7..0d999be1 100644 --- a/ppb_vector/__init__.py +++ b/ppb_vector/__init__.py @@ -235,15 +235,14 @@ def dot(self, other: VectorLike) -> float: return self.x * other_x + self.y * other_y def scale_by(self, scalar: typing.SupportsFloat) -> 'Vector': - """Scalar multiplication. + """Compute a vector-scalar multiplication. >>> Vector(1, 2).scale_by(3) Vector(3.0, 6.0) Can also be expressed with :py:meth:`* <__mul__>`: - >>> 3 * Vector(1, 2) - Vector(3.0, 6.0) + >>> assert Vector(1, 2).scale_by(3) == 3 * Vector(1, 2) """ scalar = float(scalar) return Vector(scalar * self.x, scalar * self.y) From 87a9257ce5527389c55cbd23106e8fb16ed8f068 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sun, 9 Jun 2019 18:08:16 -0400 Subject: [PATCH 5/6] Vector.__mul__: Improve the docstring - Use the imperative form in the description. - Simplify the examples showing the equivalence with dot and scale_by: use an assert rather than assume people notice the same value is produced. - Add a reference to __truediv__ --- ppb_vector/__init__.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/ppb_vector/__init__.py b/ppb_vector/__init__.py index 0d999be1..8bdccd07 100644 --- a/ppb_vector/__init__.py +++ b/ppb_vector/__init__.py @@ -254,33 +254,31 @@ def __mul__(self, other: VectorLike) -> float: pass def __mul__(self, other: typing.SupportsFloat) -> 'Vector': pass def __mul__(self, other): - """Performs a dot product or scalar product, based on the parameter type. + """Perform a dot product or a scalar product, based on the parameter type. :param other: If ``other`` is a scalar (an instance of :py:class:`typing.SupportsFloat`), return :py:meth:`self.scale_by(other) `. - >>> 3 * Vector(1, 1) + >>> v = Vector(1, 1) + >>> 3 * v Vector(3.0, 3.0) - >>> Vector(1, 1) * 3 - Vector(3.0, 3.0) - - >>> Vector(1, 1).scale_by(3) - Vector(3.0, 3.0) + >>> assert 3 * v == v * 3 == v.scale_by(3) - It is also possible to divide a :py:class:`Vector` by a scalar: - - >>> Vector(3, 3) / 3 - Vector(1.0, 1.0) + A :py:class:`Vector` can also be divided by a scalar, + using the :py:meth:`/ <__truediv__>` operator: + >>> assert 3 * v / 3 == v :param other: If ``other`` is a vector-like, return :py:meth:`self.dot(other) `. - >>> Vector(1, 1) * (-1, -1) + >>> v * (-1, -1) -2.0 + >>> assert v * (-1, -1) == (-1, -1) * v == v.dot((-1, -1)) + Vector-likes are defined in :py:meth:`convert`. """ if isinstance(other, (float, int)): From d61ceb3b4a43891cf3eb60650945a68e07813ce2 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sun, 9 Jun 2019 18:22:53 -0400 Subject: [PATCH 6/6] Vector.angle: Move the choice of unit to the long-form description. This feels more consistent, as it's not very helpful anyhow to know the choice of unit without knowing the coordinate system (i.e. the direction angles go in). --- ppb_vector/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ppb_vector/__init__.py b/ppb_vector/__init__.py index 8bdccd07..f791b4c6 100644 --- a/ppb_vector/__init__.py +++ b/ppb_vector/__init__.py @@ -362,7 +362,7 @@ def __neg__(self) -> 'Vector': return self.scale_by(-1) def angle(self, other: VectorLike) -> float: - """Compute the angle between two vectors, expressed in degrees. + """Compute the angle between two vectors. :param other: A :py:class:`Vector` or a vector-like. For a description of vector-likes, see :py:func:`__new__`. @@ -370,8 +370,9 @@ def angle(self, other: VectorLike) -> float: >>> Vector(1, 0).angle( (0, 1) ) 90.0 - As with :py:meth:`rotate`, angles are signed, and refer to a direct - coordinate system (i.e. positive rotations are counter-clockwise). + As with :py:meth:`rotate`, angles are expressed in degrees, signed, and + refer to a direct coordinate system (i.e. positive rotations are + counter-clockwise). :py:meth:`angle` is guaranteed to produce an angle between -180° and 180°. """