Skip to content

Instantly share code, notes, and snippets.

@JakeTheCorn
Last active February 22, 2021 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JakeTheCorn/020d9b59b1bdbd677fcf27251949ec1e to your computer and use it in GitHub Desktop.
Save JakeTheCorn/020d9b59b1bdbd677fcf27251949ec1e to your computer and use it in GitHub Desktop.
import unittest
# todo: make this a "parameterized" test
HEX_NUGGET_MAP = {
'0': '0000',
'1': '0001',
'2': '0010',
'3': '0011',
'4': '0100',
'5': '0101',
'6': '0110',
'7': '0111',
'8': '1000',
'9': '1001',
'A': '1010',
'B': '1011',
'C': '1100',
'D': '1101',
'E': '1110',
'F': '1111',
}
def hex_to_nugget(hex_value):
return HEX_NUGGET_MAP[hex_value]
def hex_to_binary(hex_string):
binary_string = ''
result = HexResult()
original = hex_string
result.original = original
sanitized_hex_string = hex_string.strip().upper()
for hex_char in sanitized_hex_string:
if hex_char not in HEX_NUGGET_MAP:
result.error = ValueError('Received non hexadecimal value - "%s"' % original)
result._empty_bits()
return result
result.bits += hex_to_nugget(hex_char)
result.original = hex_string
result.bit_count = len(result.bits)
return result
class Tests(unittest.TestCase):
def test1(self):
tables = [
Table(
input='0',
expected=HexResult(
bits='0000',
bit_count=4,
original='0',
error=None,
)
),
Table(
input='1',
expected=HexResult(
bits='0001',
bit_count=4,
original='1',
error=None,
)
),
Table(
input='2',
expected=HexResult(
bits='0010',
bit_count=4,
original='2',
error=None,
)
),
Table(
input='3',
expected=HexResult(
bits='0011',
bit_count=4,
original='3',
error=None,
)
),
Table(
input='4',
expected=HexResult(
bits='0100',
bit_count=4,
original='4',
error=None,
)
),
Table(
input='F',
expected=HexResult(
bits='1111',
bit_count=4,
original='F',
error=None,
)
),
Table(
input='f',
expected=HexResult(
bits='1111',
bit_count=4,
original='f',
error=None,
)
),
Table(
input='FF',
expected=HexResult(
bits='11111111',
bit_count=8,
original='FF',
error=None,
)
),
Table(
input='GF',
expected=HexResult(
bits='',
bit_count=0,
original='GF',
error=ValueError('Received non hexadecimal value - "GF"'),
)
),
Table(
input='P',
expected=HexResult(
bits='',
bit_count=0,
original='',
error=ValueError('Received non hexadecimal value - "P"'),
)
),
Table(
input=' F',
expected=HexResult(
bits='1111',
bit_count=4,
original=' F',
error=None,
)
),
Table(
input=' F F',
expected=HexResult(
bits='',
bit_count=0,
original=' F F',
error=ValueError('Received non hexadecimal value - " F F"'),
)
),
]
for table in tables:
result = hex_to_binary(table.input)
self.assertEqual(type(table.expected.error), type(result.error))
if table.expected.error:
self.assertEqual(str(table.expected.error), str(result.error))
self.assertEqual(table.expected.bits, result.bits)
self.assertEqual(table.expected, result)
class Table(object):
input = None
expected = None
def __init__(self, input, expected):
self.input = input
self.expected = expected
class HexResult(object):
bits = ''
bit_count = 0
original = ''
error = None
def __init__(
self,
bits='',
bit_count=0,
original='',
error=None,
):
self.bits = bits
self.bit_count = bit_count
self.original = original
self.error = error
def __eq__(self, other):
if not isinstance(other, HexResult):
return False
bits_equal = self.bits == other.bits
bit_count_equal = self.bit_count == other.bit_count
error_types_equal = type(self.error) == type(other.error)
error_messages_equal = True
if not error_types_equal:
return False
if self.error is not None:
error_messages_equal = str(self.error) == str(other.error)
return bits_equal and bit_count_equal and error_messages_equal
# Private
def _empty_bits(self):
self.bits = ''
self.bit_count = 0
# TODO: test errors
HEX_CHAR_MAP = {
'0': 0,
'1': 1,
'2': 2,
'3': 3,
'4': 4,
'5': 5,
'6': 6,
'7': 7,
'8': 8,
'9': 9,
'A': 10,
'B': 11,
'C': 12,
'D': 13,
'E': 14,
'F': 15,
}
def hex_to_decimal(hex_value):
result = HexToDecimalResult()
result.hex = hex_value
total = 0
for idx, hex_char in enumerate(hex_value[::-1]):
current_multiplier = _get_current_multiplier(idx)
current_hex_decimal_value = HEX_CHAR_MAP[hex_char]
total += current_hex_decimal_value * current_multiplier
result.decimal = total
return result
def _get_current_multiplier(idx):
return 16 ** idx
class HexToDecimalTests(unittest.TestCase):
def test(self):
tables = [
Table(
input='0',
expected=HexToDecimalResult(
decimal=0,
hex='0',
error=None,
)
),
Table(
input='1',
expected=HexToDecimalResult(
decimal=1,
hex='1',
error=None,
)
),
Table(
input='A',
expected=HexToDecimalResult(
decimal=10,
hex='A',
error=None,
)
),
Table(
input='10',
expected=HexToDecimalResult(
decimal=16,
hex='10',
error=None,
)
),
Table(
input='20',
expected=HexToDecimalResult(
decimal=32,
hex='20',
error=None,
)
),
Table(
input='AA',
expected=HexToDecimalResult(
decimal=170,
hex='AA',
error=None,
)
),
Table(
input='AAA',
expected=HexToDecimalResult(
decimal=2730,
hex='AAA',
error=None,
)
),
Table(
input='FF',
expected=HexToDecimalResult(
decimal=255,
hex='FF',
error=None,
)
),
Table(
input='FFF',
expected=HexToDecimalResult(
decimal=4095,
hex='FFF',
error=None,
)
),
]
for table in tables:
result = hex_to_decimal(table.input)
self.assertEqual(table.expected, result)
class HexToDecimalResult(object):
decimal = 0
hex = ''
error = None
def __init__(
self,
decimal=0,
hex='',
error=None,
):
self.decimal = decimal
self.hex = hex
self.error = error
def __eq__(self, other):
if not isinstance(other, HexToDecimalResult):
return False
hex_values_equal = self.hex == other.hex
decimal_values_equal = self.decimal == other.decimal
return hex_values_equal and decimal_values_equal
@JakeTheCorn
Copy link
Author

todo: this needs redesign... it's overengineered, but I did it for fun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment