From b92adff783eaba9c75bb82ada28d8cedefdf0d49 Mon Sep 17 00:00:00 2001 From: David Michaels Date: Wed, 7 Aug 2024 14:00:53 -0400 Subject: [PATCH] Added to_number function to misc_utils. --- dcicutils/misc_utils.py | 10 +++++----- dcicutils/structured_data.py | 4 ++-- test/test_misc_utils.py | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/dcicutils/misc_utils.py b/dcicutils/misc_utils.py index a25d13a55..7143706f7 100644 --- a/dcicutils/misc_utils.py +++ b/dcicutils/misc_utils.py @@ -1022,15 +1022,15 @@ def to_integer(value: str, fallback: Optional[Any] = None, strict: bool = False) def to_number(value: str, allow_commas: bool = False, allow_multiplier_suffix: bool = False, - allow_float: bool = False, + as_float: bool = False, fallback: Optional[Union[int, float]] = None) -> Optional[Union[int, float]]: """ - Converts the give string value to an int, or possibly float if allow_float is True. + Converts the give string value to an int, or float if as_float is True. If allow_commas is True (default: False) then allow commas (only) every three digits. If allow_multiplier_suffix is True (default: False) allow any of K, Kb, KB; or M, Mb, MB; or G, Gb, or GB; or T, Tb, TB, to mean multiply value by one thousand; one million; - one billion; or one trillion; respectively. If allow_float is True (default: False) + one billion; or one trillion; respectively. If as_float is True (default: False) allow the value to be floating point (i.e. with a decimal point and a fractional part), in which case the returned value will be of type float rather than int. If the string is not well formated then returns None. @@ -1058,7 +1058,7 @@ def to_number(value: str, return fallback break - if allow_float is True: + if as_float is True: if (dot_index := value.rfind(".")) >= 0: if value_fraction := value[dot_index + 1:].strip(): try: @@ -1083,7 +1083,7 @@ def to_number(value: str, if value_negative: result = -result - return result + return float(result) if as_float is True else result def to_float(value: str, fallback: Optional[Any] = None) -> Optional[Any]: diff --git a/dcicutils/structured_data.py b/dcicutils/structured_data.py index b1d57c600..8891b28d0 100644 --- a/dcicutils/structured_data.py +++ b/dcicutils/structured_data.py @@ -727,7 +727,7 @@ def _map_function_integer(self, typeinfo: dict) -> Callable: allow_multiplier_suffix = typeinfo.get("allow_multiplier_suffix") is True def map_integer(value: str, src: Optional[str]) -> Any: # noqa nonlocal allow_commas, allow_multiplier_suffix - return to_number(value, fallback=value, allow_float=False, + return to_number(value, fallback=value, as_float=False, allow_commas=allow_commas, allow_multiplier_suffix=allow_multiplier_suffix) return map_integer @@ -737,7 +737,7 @@ def _map_function_number(self, typeinfo: dict) -> Callable: allow_multiplier_suffix = typeinfo.get("allow_multiplier_suffix") is True def map_number(value: str, src: Optional[str]) -> Any: # noqa nonlocal allow_commas, allow_multiplier_suffix - return to_number(value, fallback=value, allow_float=True, + return to_number(value, fallback=value, as_float=True, allow_commas=allow_commas, allow_multiplier_suffix=allow_multiplier_suffix) return map_number diff --git a/test/test_misc_utils.py b/test/test_misc_utils.py index 58fbbf97b..44ae1931e 100644 --- a/test/test_misc_utils.py +++ b/test/test_misc_utils.py @@ -3733,9 +3733,11 @@ def test_to_number(): assert to_number("1234") == 1234 assert to_number("1,234,567") is None assert to_number("27500") == 27500 + assert to_number("789", as_float=True) == 789.0 + assert type(to_number("789", as_float=True)) == float assert to_number("27500", allow_commas=True) == 27500 assert to_number("1,234,567", allow_commas=True) == 1234567 - assert to_number("1234.0567", allow_float=True) == 1234.0567 + assert to_number("1234.0567", as_float=True) == 1234.0567 assert to_number("1K", allow_multiplier_suffix=True) == 1000 assert to_number("1Kb", allow_multiplier_suffix=True) == 1000 assert to_number("1KB", allow_multiplier_suffix=True) == 1000