From f5518f6ccf55e92b93c96c73f32178196481d215 Mon Sep 17 00:00:00 2001 From: leufen1 <l.leufen@fz-juelich.de> Date: Fri, 30 Sep 2022 15:06:47 +0200 Subject: [PATCH] relative_round can now ceil and floor --- mlair/helpers/helpers.py | 20 +++++++++- test/test_helpers/test_helpers.py | 66 ++++++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 3 deletions(-) diff --git a/mlair/helpers/helpers.py b/mlair/helpers/helpers.py index 7911a572..dbfe75ce 100644 --- a/mlair/helpers/helpers.py +++ b/mlair/helpers/helpers.py @@ -123,7 +123,7 @@ def float_round(number: float, decimals: int = 0, round_type: Callable = math.ce return round_type(number * multiplier) / multiplier -def relative_round(x: float, sig: int) -> float: +def relative_round(x: float, sig: int, ceil=False, floor=False) -> float: """ Round small numbers according to given "significance". @@ -135,7 +135,23 @@ def relative_round(x: float, sig: int) -> float: :return: rounded number """ assert sig >= 1 - return round(x, sig-int(np.floor(np.log10(abs(x))))-1) + assert not (ceil and floor) + if x == 0: + return 0 + else: + rounded_number = round(x, sig-get_order(x)-1) + if floor is True and rounded_number > round(x, sig-get_order(x)): + res = rounded_number - 10 ** (get_order(x) - sig + 1) + elif ceil is True and rounded_number < round(x, sig-get_order(x)): + res = rounded_number + 10 ** (get_order(x) - sig + 1) + else: + res = rounded_number + return round(res, sig-get_order(res)-1) + + +def get_order(x: float): + """Get order of number (as power of 10)""" + return int(np.floor(np.log10(abs(x)))) def remove_items(obj: Union[List, Dict, Tuple], items: Any): diff --git a/test/test_helpers/test_helpers.py b/test/test_helpers/test_helpers.py index 6f787d58..bcc255bb 100644 --- a/test/test_helpers/test_helpers.py +++ b/test/test_helpers/test_helpers.py @@ -16,7 +16,7 @@ from mlair.helpers import to_list, dict_to_xarray, float_round, remove_items, ex sort_like, filter_dict_by_value from mlair.helpers import PyTestRegex, check_nested_equality from mlair.helpers import Logger, TimeTracking -from mlair.helpers.helpers import is_xarray, convert2xrda, relative_round +from mlair.helpers.helpers import is_xarray, convert2xrda, relative_round, get_order class TestToList: @@ -191,6 +191,10 @@ class TestRelativeRound: assert relative_round(0.03112, 1) == 0.03 assert relative_round(0.031126, 4) == 0.03113 + def test_relative_round_zero(self): + assert relative_round(0, 1) == 0 + assert relative_round(0, 4) == 0 + def test_relative_round_negative_numbers(self): assert relative_round(-101.2033, 5) == -101.2 assert relative_round(-106, 2) == -110 @@ -204,6 +208,66 @@ class TestRelativeRound: with pytest.raises(TypeError): relative_round(300, 1.1) + def test_relative_round_floor(self): + assert relative_round(7.5, 1, floor=True) == 7 + assert relative_round(7.7, 1, floor=True) == 7 + assert relative_round(7.9, 1, floor=True) == 7 + assert relative_round(7.993, 2, floor=True) == 7.9 + assert relative_round(17.9312, 1, floor=True) == 10 + assert relative_round(17.9312, 2, floor=True) == 17 + assert relative_round(127.43, 3, floor=True) == 127 + assert relative_round(0.025, 1, floor=True) == 0.02 + + def test_relative_round_floor_neg_numbers(self): + assert relative_round(-7.9, 1, floor=True) == -8 + assert relative_round(-7.4, 1, floor=True) == -8 + assert relative_round(-7.42, 2, floor=True) == -7.5 + assert relative_round(-127.43, 3, floor=True) == -128 + assert relative_round(-127.43, 2, floor=True) == -130 + assert relative_round(-127.43, 1, floor=True) == -200 + + def test_relative_round_ceil(self): + assert relative_round(7.5, 1, ceil=True) == 8 + assert relative_round(7.7, 1, ceil=True) == 8 + assert relative_round(7.2, 1, ceil=True) == 8 + assert relative_round(7.993, 2, ceil=True) == 8 + assert relative_round(17.9312, 1, ceil=True) == 20 + assert relative_round(17.9312, 2, ceil=True) == 18 + assert relative_round(127.43, 3, ceil=True) == 128 + + def test_relative_round_ceil_neg_numbers(self): + assert relative_round(-7.9, 1, ceil=True) == -7 + assert relative_round(-7.4, 1, ceil=True) == -7 + assert relative_round(-7.42, 2, ceil=True) == -7.4 + assert relative_round(-127.43, 3, ceil=True) == -127 + assert relative_round(-127.43, 2, ceil=True) == -120 + assert relative_round(-127.43, 1, ceil=True) == -100 + + def test_relative_round_ceil_floor(self): + with pytest.raises(AssertionError): + relative_round(300, -1, ceil=True, floor=True) + + +class TestGetOrder: + + def test_get_order(self): + assert get_order(10) == 1 + assert get_order(11) == 1 + assert get_order(9.99) == 0 + assert get_order(1000) == 3 + assert get_order(.006) == -3 + + def test_get_order_neg_orders(self): + assert get_order(.006) == -3 + assert get_order(0) == 0 + assert get_order(0.00622) == -3 + assert get_order(0.00022) == -4 + + def test_get_order_neg_numbers(self): + assert get_order(-0.00622) == -3 + assert get_order(-0.1) == -1 + assert get_order(-622) == 2 + class TestSelectFromDict: -- GitLab