From 0c065daa5eef7868cf1825c247cf9628907b86a0 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sat, 29 Dec 2018 15:18:07 +0100 Subject: [PATCH 1/5] Add a test for Vector2.isclose --- tests/test_vector2_isclose.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/test_vector2_isclose.py diff --git a/tests/test_vector2_isclose.py b/tests/test_vector2_isclose.py new file mode 100644 index 00000000..df131982 --- /dev/null +++ b/tests/test_vector2_isclose.py @@ -0,0 +1,9 @@ +from ppb_vector import Vector2 +from utils import vectors +from hypothesis import assume, given, note, example +from hypothesis.strategies import floats + + +@given(x=vectors(), abs_tol=floats(min_value=0), rel_tol=floats(min_value=0)) +def test_isclose_to_self(x, abs_tol, rel_tol): + assert x.isclose(x, abs_tol=abs_tol, rel_tol=rel_tol) From 5a5b4038d89cf73e257723a2c8b59e547af3fe7e Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sat, 29 Dec 2018 15:19:53 +0100 Subject: [PATCH 2/5] Vector2.isclose: Use closed inequalities, to support null tolerances --- ppb_vector/vector2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ppb_vector/vector2.py b/ppb_vector/vector2.py index 74b730bb..535d7f45 100644 --- a/ppb_vector/vector2.py +++ b/ppb_vector/vector2.py @@ -241,8 +241,8 @@ def isclose(self: VectorOrSub, other: VectorLike, *, diff = (self - other).length return ( - diff < rel_tol * rel_length or - diff < float(abs_tol) + diff <= rel_tol * rel_length or + diff <= float(abs_tol) ) @staticmethod From 2142db8de793382bdfc56de9133b320b5d6f2690 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sat, 29 Dec 2018 15:24:14 +0100 Subject: [PATCH 3/5] Test Vector2.isclose with invalid values --- tests/test_vector2_isclose.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_vector2_isclose.py b/tests/test_vector2_isclose.py index df131982..e3b39c37 100644 --- a/tests/test_vector2_isclose.py +++ b/tests/test_vector2_isclose.py @@ -1,4 +1,5 @@ from ppb_vector import Vector2 +from pytest import raises # type: ignore from utils import vectors from hypothesis import assume, given, note, example from hypothesis.strategies import floats @@ -7,3 +8,13 @@ @given(x=vectors(), abs_tol=floats(min_value=0), rel_tol=floats(min_value=0)) def test_isclose_to_self(x, abs_tol, rel_tol): assert x.isclose(x, abs_tol=abs_tol, rel_tol=rel_tol) + + +def test_isclose_negative_tolerances(): + zero = Vector2(0, 0) + + with raises(ValueError): + zero.isclose(zero, abs_tol=-1) + + with raises(ValueError): + zero.isclose(zero, rel_tol=-1) From a4ced4b9dcaa87a811b8608940e34a1e16cad366 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sat, 29 Dec 2018 15:25:47 +0100 Subject: [PATCH 4/5] Vector2.isclose: Throw ValueError on invalid tolerances --- ppb_vector/vector2.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ppb_vector/vector2.py b/ppb_vector/vector2.py index 535d7f45..f80a7c5f 100644 --- a/ppb_vector/vector2.py +++ b/ppb_vector/vector2.py @@ -231,6 +231,9 @@ def isclose(self: VectorOrSub, other: VectorLike, *, For the values to be considered close, the difference between them must be smaller than at least one of the tolerances. """ + if abs_tol < 0 or rel_tol < 0: + raise ValueError("Vector2.isclose takes non-negative tolerances") + other = Vector2.convert(other) rel_length = max( From 0d6fb930c3983b59d01a07c99200c680c707d210 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sat, 29 Dec 2018 17:35:25 +0100 Subject: [PATCH 5/5] Vector2.isclose: Test absolute and relative errors --- tests/test_vector2_isclose.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/test_vector2_isclose.py b/tests/test_vector2_isclose.py index e3b39c37..ddc4eae8 100644 --- a/tests/test_vector2_isclose.py +++ b/tests/test_vector2_isclose.py @@ -1,6 +1,6 @@ from ppb_vector import Vector2 from pytest import raises # type: ignore -from utils import vectors +from utils import units, vectors from hypothesis import assume, given, note, example from hypothesis.strategies import floats @@ -9,6 +9,16 @@ def test_isclose_to_self(x, abs_tol, rel_tol): assert x.isclose(x, abs_tol=abs_tol, rel_tol=rel_tol) +@given(x=vectors(max_magnitude=1e75), direction=units(), + abs_tol=floats(min_value=0, max_value=1e75)) +def test_isclose_abs_error(x, direction, abs_tol): + assert x.isclose(x + (1 - 1e-12) * abs_tol * direction, abs_tol=abs_tol, rel_tol=0) + +@given(x=vectors(), direction=units(), + rel_tol=floats(min_value=0, max_value=1e75)) +def test_isclose_rel_error(x, direction, rel_tol): + assert x.isclose(x + rel_tol * x.length * direction, abs_tol=0, rel_tol=rel_tol) + def test_isclose_negative_tolerances(): zero = Vector2(0, 0)