From 707f7c9447b4e7e211fcd46b60155475a38d4c88 Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Fri, 14 Feb 2025 00:08:36 +0000 Subject: [PATCH 1/4] feat: unit converter --- crypto/utils/unit_converter.py | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 crypto/utils/unit_converter.py diff --git a/crypto/utils/unit_converter.py b/crypto/utils/unit_converter.py new file mode 100644 index 00000000..1a12ec8d --- /dev/null +++ b/crypto/utils/unit_converter.py @@ -0,0 +1,59 @@ +# import numpy as np +from decimal import Decimal + +class UnitConverter: + WEI_MULTIPLIER = '1' + GWEI_MULTIPLIER = '1000000000' # 1e9 + ARK_MULTIPLIER = '1000000000000000000' # 1e18 + + @staticmethod + def parse_units(value, unit='ark') -> str: + value = Decimal(str(value)) + + unit = unit.lower() + if unit == 'wei': + return format((value * Decimal(UnitConverter.WEI_MULTIPLIER)).normalize(), 'f') + + if unit == 'gwei': + return format((value * Decimal(UnitConverter.GWEI_MULTIPLIER)).normalize(), 'f') + + if unit == 'ark': + return format((value * Decimal(UnitConverter.ARK_MULTIPLIER)).normalize(), 'f') + + raise ValueError(f"Unsupported unit: {unit}. Supported units are 'wei', 'gwei', and 'ark'.") + + @staticmethod + def format_units(value, unit='ark') -> Decimal: + value = Decimal(str(value)) + + unit = unit.lower() + if unit == 'wei': + return value / Decimal(UnitConverter.WEI_MULTIPLIER) + + if unit == 'gwei': + return value / Decimal(UnitConverter.GWEI_MULTIPLIER) + + if unit == 'ark': + return value / Decimal(UnitConverter.ARK_MULTIPLIER) + + raise ValueError(f"Unsupported unit: {unit}. Supported units are 'wei', 'gwei', and 'ark'.") + + @staticmethod + def wei_to_ark(value, suffix=None): + converted_value = UnitConverter.format_units(UnitConverter.parse_units(value, 'wei'), 'ark') + converted_value = format(converted_value.normalize(), 'f') + + if suffix is not None: + return f"{converted_value} {suffix}" + + return str(converted_value) + + @staticmethod + def gwei_to_ark(value, suffix=None): + converted_value = UnitConverter.format_units(UnitConverter.parse_units(value, 'gwei'), 'ark') + converted_value = format(converted_value.normalize(), 'f') + + if suffix is not None: + return f"{converted_value} {suffix}" + + return str(converted_value) From d6a630c9731159bf172f08841fe21a57a2f12512 Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Fri, 14 Feb 2025 00:08:44 +0000 Subject: [PATCH 2/4] test --- tests/utils/test_unit_converter.py | 65 ++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 tests/utils/test_unit_converter.py diff --git a/tests/utils/test_unit_converter.py b/tests/utils/test_unit_converter.py new file mode 100644 index 00000000..9d00eddf --- /dev/null +++ b/tests/utils/test_unit_converter.py @@ -0,0 +1,65 @@ +from crypto.utils.unit_converter import UnitConverter + +def test_it_should_parse_units_into_wei(): + wei_value = UnitConverter.parse_units(1, 'wei') + + assert wei_value == '1' + +def test_it_should_parse_units_into_gwei(): + gwei_value = UnitConverter.parse_units(1, 'gwei') + + assert gwei_value == '1000000000' + +def test_it_should_parse_units_into_ark(): + ark_value = UnitConverter.parse_units(1, 'ark') + + assert ark_value == '1000000000000000000' + +def test_it_should_parse_decimal_units_into_ark(): + ark_value_decimal = UnitConverter.parse_units(0.1, 'ark') + + assert ark_value_decimal == '100000000000000000' + +def test_it_should_format_units_from_wei(): + formatted_value = UnitConverter.format_units('1', 'wei') + + assert formatted_value == 1.0 + +def test_it_should_format_units_from_gwei(): + formatted_value = UnitConverter.format_units('1000000000', 'gwei') + + assert formatted_value == 1.0 + +def test_it_should_format_units_from_ark(): + formatted_value = UnitConverter.format_units('1000000000000000000', 'ark') + + assert formatted_value == 1.0 + +def test_it_should_throw_exception_for_unsupported_unit_in_parse(): + try: + UnitConverter.parse_units(1, 'unsupported') + except ValueError as e: + assert str(e) == 'Unsupported unit: unsupported. Supported units are \'wei\', \'gwei\', and \'ark\'.' + +def test_it_should_throw_exception_for_unsupported_unit_in_format(): + try: + UnitConverter.format_units('1', 'unsupported') + except ValueError as e: + assert str(e) == 'Unsupported unit: unsupported. Supported units are \'wei\', \'gwei\', and \'ark\'.' + +def test_it_should_parse_units_into_ark_with_fraction(): + ark_value = UnitConverter.parse_units(0.1, 'ark') + + assert ark_value == '100000000000000000' + +def test_it_should_convert_wei_to_ark(): + assert UnitConverter.wei_to_ark(1, 'DARK') == '0.000000000000000001 DARK' + assert UnitConverter.wei_to_ark(1) == '0.000000000000000001' + assert UnitConverter.wei_to_ark('1000000000000000000', 'DARK') == '1 DARK' + assert UnitConverter.wei_to_ark('1000000000000000000') == '1' + +def test_it_should_convert_gwei_to_ark(): + assert UnitConverter.gwei_to_ark(1, 'DARK') == '0.000000001 DARK' + assert UnitConverter.gwei_to_ark(1) == '0.000000001' + assert UnitConverter.gwei_to_ark('1000000000', 'DARK') == '1 DARK' + assert UnitConverter.gwei_to_ark('1000000000') == '1' From d7093382f525b6217a505f32822267b3ed861ed5 Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Fri, 14 Feb 2025 00:34:16 +0000 Subject: [PATCH 3/4] update type hinting --- crypto/utils/unit_converter.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crypto/utils/unit_converter.py b/crypto/utils/unit_converter.py index 1a12ec8d..39688849 100644 --- a/crypto/utils/unit_converter.py +++ b/crypto/utils/unit_converter.py @@ -1,5 +1,6 @@ # import numpy as np from decimal import Decimal +from typing import Union class UnitConverter: WEI_MULTIPLIER = '1' @@ -7,7 +8,7 @@ class UnitConverter: ARK_MULTIPLIER = '1000000000000000000' # 1e18 @staticmethod - def parse_units(value, unit='ark') -> str: + def parse_units(value: Union[float, int, str, Decimal], unit='ark') -> str: value = Decimal(str(value)) unit = unit.lower() @@ -23,7 +24,7 @@ def parse_units(value, unit='ark') -> str: raise ValueError(f"Unsupported unit: {unit}. Supported units are 'wei', 'gwei', and 'ark'.") @staticmethod - def format_units(value, unit='ark') -> Decimal: + def format_units(value: Union[float, int, str, Decimal], unit='ark') -> Decimal: value = Decimal(str(value)) unit = unit.lower() @@ -39,7 +40,7 @@ def format_units(value, unit='ark') -> Decimal: raise ValueError(f"Unsupported unit: {unit}. Supported units are 'wei', 'gwei', and 'ark'.") @staticmethod - def wei_to_ark(value, suffix=None): + def wei_to_ark(value: Union[float, int, str, Decimal], suffix=None): converted_value = UnitConverter.format_units(UnitConverter.parse_units(value, 'wei'), 'ark') converted_value = format(converted_value.normalize(), 'f') @@ -49,7 +50,7 @@ def wei_to_ark(value, suffix=None): return str(converted_value) @staticmethod - def gwei_to_ark(value, suffix=None): + def gwei_to_ark(value: Union[float, int, str, Decimal], suffix=None): converted_value = UnitConverter.format_units(UnitConverter.parse_units(value, 'gwei'), 'ark') converted_value = format(converted_value.normalize(), 'f') From 8dfc1630deab07fcd3df4ec015ca7172bbbb4e78 Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Fri, 14 Feb 2025 00:34:23 +0000 Subject: [PATCH 4/4] additional tests --- tests/utils/test_unit_converter.py | 93 ++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/tests/utils/test_unit_converter.py b/tests/utils/test_unit_converter.py index 9d00eddf..64886b12 100644 --- a/tests/utils/test_unit_converter.py +++ b/tests/utils/test_unit_converter.py @@ -1,39 +1,67 @@ from crypto.utils.unit_converter import UnitConverter +from decimal import Decimal def test_it_should_parse_units_into_wei(): - wei_value = UnitConverter.parse_units(1, 'wei') + assert UnitConverter.parse_units(1, 'wei') == '1' + assert UnitConverter.parse_units(1.0, 'wei') == '1' + assert UnitConverter.parse_units('1', 'wei') == '1' + assert UnitConverter.parse_units('1.0', 'wei') == '1' - assert wei_value == '1' + assert UnitConverter.parse_units(Decimal(1), 'wei') == '1' + assert UnitConverter.parse_units(Decimal(1.0), 'wei') == '1' + assert UnitConverter.parse_units(Decimal('1'), 'wei') == '1' + assert UnitConverter.parse_units(Decimal('1.0'), 'wei') == '1' def test_it_should_parse_units_into_gwei(): - gwei_value = UnitConverter.parse_units(1, 'gwei') + assert UnitConverter.parse_units(1, 'gwei') == '1000000000' + assert UnitConverter.parse_units(1.0, 'gwei') == '1000000000' + assert UnitConverter.parse_units('1', 'gwei') == '1000000000' + assert UnitConverter.parse_units('1.0', 'gwei') == '1000000000' - assert gwei_value == '1000000000' + assert UnitConverter.parse_units(Decimal(1), 'gwei') == '1000000000' + assert UnitConverter.parse_units(Decimal(1.0), 'gwei') == '1000000000' + assert UnitConverter.parse_units(Decimal('1'), 'gwei') == '1000000000' + assert UnitConverter.parse_units(Decimal('1.0'), 'gwei') == '1000000000' def test_it_should_parse_units_into_ark(): - ark_value = UnitConverter.parse_units(1, 'ark') + assert UnitConverter.parse_units(1, 'ark') == '1000000000000000000' + assert UnitConverter.parse_units(1.0, 'ark') == '1000000000000000000' + assert UnitConverter.parse_units('1', 'ark') == '1000000000000000000' + assert UnitConverter.parse_units('1.0', 'ark') == '1000000000000000000' - assert ark_value == '1000000000000000000' + assert UnitConverter.parse_units(Decimal(1), 'ark') == '1000000000000000000' + assert UnitConverter.parse_units(Decimal(1.0), 'ark') == '1000000000000000000' + assert UnitConverter.parse_units(Decimal('1'), 'ark') == '1000000000000000000' + assert UnitConverter.parse_units(Decimal('1.0'), 'ark') == '1000000000000000000' def test_it_should_parse_decimal_units_into_ark(): - ark_value_decimal = UnitConverter.parse_units(0.1, 'ark') - - assert ark_value_decimal == '100000000000000000' + assert UnitConverter.parse_units(0.1, 'ark') == '100000000000000000' + assert UnitConverter.parse_units('0.1', 'ark') == '100000000000000000' def test_it_should_format_units_from_wei(): - formatted_value = UnitConverter.format_units('1', 'wei') + assert UnitConverter.format_units(1, 'wei') == 1.0 + assert UnitConverter.format_units(1.0, 'wei') == 1.0 + assert UnitConverter.format_units('1', 'wei') == 1.0 + assert UnitConverter.format_units('1.0', 'wei') == 1.0 - assert formatted_value == 1.0 + assert UnitConverter.format_units(Decimal(1), 'wei') == 1.0 + assert UnitConverter.format_units(Decimal(1.0), 'wei') == 1.0 + assert UnitConverter.format_units(Decimal('1'), 'wei') == 1.0 + assert UnitConverter.format_units(Decimal('1.0'), 'wei') == 1.0 def test_it_should_format_units_from_gwei(): - formatted_value = UnitConverter.format_units('1000000000', 'gwei') + assert UnitConverter.format_units(1000000000, 'gwei') == 1.0 + assert UnitConverter.format_units('1000000000', 'gwei') == 1.0 - assert formatted_value == 1.0 + assert UnitConverter.format_units(Decimal(1000000000), 'gwei') == 1.0 + assert UnitConverter.format_units(Decimal('1000000000'), 'gwei') == 1.0 def test_it_should_format_units_from_ark(): - formatted_value = UnitConverter.format_units('1000000000000000000', 'ark') + assert UnitConverter.format_units(1000000000000000000, 'ark') == 1.0 + assert UnitConverter.format_units('1000000000000000000', 'ark') == 1.0 - assert formatted_value == 1.0 + assert UnitConverter.format_units(Decimal(1000000000000000000), 'ark') == 1.0 + assert UnitConverter.format_units(Decimal('1000000000000000000'), 'ark') == 1.0 def test_it_should_throw_exception_for_unsupported_unit_in_parse(): try: @@ -48,18 +76,47 @@ def test_it_should_throw_exception_for_unsupported_unit_in_format(): assert str(e) == 'Unsupported unit: unsupported. Supported units are \'wei\', \'gwei\', and \'ark\'.' def test_it_should_parse_units_into_ark_with_fraction(): - ark_value = UnitConverter.parse_units(0.1, 'ark') - - assert ark_value == '100000000000000000' + assert UnitConverter.parse_units(0.1, 'ark') == '100000000000000000' + assert UnitConverter.parse_units('0.1', 'ark') == '100000000000000000' def test_it_should_convert_wei_to_ark(): assert UnitConverter.wei_to_ark(1, 'DARK') == '0.000000000000000001 DARK' assert UnitConverter.wei_to_ark(1) == '0.000000000000000001' + assert UnitConverter.wei_to_ark(1000000000000000000, 'DARK') == '1 DARK' + assert UnitConverter.wei_to_ark(1000000000000000000) == '1' + + assert UnitConverter.wei_to_ark('1', 'DARK') == '0.000000000000000001 DARK' + assert UnitConverter.wei_to_ark('1') == '0.000000000000000001' assert UnitConverter.wei_to_ark('1000000000000000000', 'DARK') == '1 DARK' assert UnitConverter.wei_to_ark('1000000000000000000') == '1' + assert UnitConverter.wei_to_ark(Decimal(1), 'DARK') == '0.000000000000000001 DARK' + assert UnitConverter.wei_to_ark(Decimal(1)) == '0.000000000000000001' + assert UnitConverter.wei_to_ark(Decimal(1000000000000000000), 'DARK') == '1 DARK' + assert UnitConverter.wei_to_ark(Decimal(1000000000000000000)) == '1' + + assert UnitConverter.wei_to_ark(Decimal('1'), 'DARK') == '0.000000000000000001 DARK' + assert UnitConverter.wei_to_ark(Decimal('1')) == '0.000000000000000001' + assert UnitConverter.wei_to_ark(Decimal('1000000000000000000'), 'DARK') == '1 DARK' + assert UnitConverter.wei_to_ark(Decimal('1000000000000000000')) == '1' + def test_it_should_convert_gwei_to_ark(): assert UnitConverter.gwei_to_ark(1, 'DARK') == '0.000000001 DARK' assert UnitConverter.gwei_to_ark(1) == '0.000000001' + assert UnitConverter.gwei_to_ark(1000000000, 'DARK') == '1 DARK' + assert UnitConverter.gwei_to_ark(1000000000) == '1' + + assert UnitConverter.gwei_to_ark('1', 'DARK') == '0.000000001 DARK' + assert UnitConverter.gwei_to_ark('1') == '0.000000001' assert UnitConverter.gwei_to_ark('1000000000', 'DARK') == '1 DARK' assert UnitConverter.gwei_to_ark('1000000000') == '1' + + assert UnitConverter.gwei_to_ark(Decimal(1), 'DARK') == '0.000000001 DARK' + assert UnitConverter.gwei_to_ark(Decimal(1)) == '0.000000001' + assert UnitConverter.gwei_to_ark(Decimal(1000000000), 'DARK') == '1 DARK' + assert UnitConverter.gwei_to_ark(Decimal(1000000000)) == '1' + + assert UnitConverter.gwei_to_ark(Decimal('1'), 'DARK') == '0.000000001 DARK' + assert UnitConverter.gwei_to_ark(Decimal('1')) == '0.000000001' + assert UnitConverter.gwei_to_ark(Decimal('1000000000'), 'DARK') == '1 DARK' + assert UnitConverter.gwei_to_ark(Decimal('1000000000')) == '1'