De-lint hybrid36.py

This commit is contained in:
Nathan Baker
2020-05-24 11:21:55 -07:00
parent a534d97016
commit 95e132e520
2 changed files with 77 additions and 15 deletions

View File

@@ -4,16 +4,21 @@ http://cci.lbl.gov/hybrid_36/
""" """
import string import string
_hybrid36_upper_chars = set(string.ascii_uppercase)
_hybrid36_lower_chars = set(string.ascii_lowercase) _HYBRID36_UPPER_CHARS = set(string.ascii_uppercase)
_hybrid36_digits = set(string.digits) _HYBRID36_LOWER_CHARS = set(string.ascii_lowercase)
_hybrid36_upper_set = _hybrid36_upper_chars | _hybrid36_digits _HYBRID36_DIGITS = set(string.digits)
_hybrid36_lower_set = _hybrid36_lower_chars | _hybrid36_digits _HYBRID36_UPPER_SET = _HYBRID36_UPPER_CHARS | _HYBRID36_DIGITS
_HYBRID36_LOWER_SET = _HYBRID36_LOWER_CHARS | _HYBRID36_DIGITS
def decode(input_string): def decode(input_string):
""" """Convert an input string of a number in hybrid-36 format to an integer.
Convert an input string of a number in hybrid-36 format to an integer.
Args:
input_string: input string
Returns:
integer
""" """
value_error_message = "invalid literal for hybrid-36 conversion: '%s'" value_error_message = "invalid literal for hybrid-36 conversion: '%s'"
@@ -27,7 +32,7 @@ def decode(input_string):
else: else:
sign = 1 sign = 1
if not len(input_string): if len(input_string) == 0:
raise ValueError(value_error_message % input_string) raise ValueError(value_error_message % input_string)
# See http://cci.lbl.gov/hybrid_36/ for documentation on the format. # See http://cci.lbl.gov/hybrid_36/ for documentation on the format.
@@ -35,21 +40,21 @@ def decode(input_string):
num_chars = len(input_string) num_chars = len(input_string)
first_char = input_string[0] first_char = input_string[0]
if first_char in _hybrid36_digits: if first_char in _HYBRID36_DIGITS:
return sign * int(input_string) return sign * int(input_string)
elif first_char in _hybrid36_upper_chars: elif first_char in _HYBRID36_UPPER_CHARS:
reference = - (10 * 36 ** (num_chars - 1) - 10 ** num_chars) reference = - (10 * 36 ** (num_chars - 1) - 10 ** num_chars)
_hybrid36_set = _hybrid36_upper_set _hybrid36_set = _HYBRID36_UPPER_SET
elif first_char in _hybrid36_lower_chars: elif first_char in _HYBRID36_LOWER_CHARS:
reference = (16 * 36 ** (num_chars - 1) + 10 ** num_chars) reference = (16 * 36 ** (num_chars - 1) + 10 ** num_chars)
_hybrid36_set = _hybrid36_lower_set _hybrid36_set = _HYBRID36_LOWER_SET
else: else:
raise ValueError(value_error_message % original_input_string) raise ValueError(value_error_message % original_input_string)
# Check the validity of the input string: ASCII characters should be # Check the validity of the input string: ASCII characters should be
# either all uppercase or all lowercase. # either all uppercase or all lowercase.
for c in input_string[1:]: for char in input_string[1:]:
if c not in _hybrid36_set: if char not in _hybrid36_set:
raise ValueError(value_error_message % original_input_string) raise ValueError(value_error_message % original_input_string)
# Convert with the int function. # Convert with the int function.

57
tests/test_hybrid36.py Normal file
View File

@@ -0,0 +1,57 @@
import unittest
import propka.hybrid36 as hybrid36
class Hybrid36Test(unittest.TestCase):
def testDecode(self):
test_values = {
"99999": 99999,
"A0000": 100000,
"0": 0,
"9": 9,
"A": 10,
" ZZZZY": 43770014,
"ZZZZZ": 43770015, # ZZZZZ - A0000 + 100000
"a0000": 43770016,
"zzzzz": 87440031,
"zzzzy": 87440030,
"99": 99,
"A0": 100,
"ZZ": 1035,
"zz": 1971,
"-99999": -99999,
"-A0000": -100000,
"-0": 0,
"-9": -9,
"-A": -10,
"-ZZZZY": -43770014,
"-ZZZZZ": -43770015, # ZZZZZ - A0000 + 100000
"-a0000": -43770016,
"-zzzzz": -87440031,
"-zzzzy": -87440030,
"-99": -99,
"-A0": -100,
"-ZZ": -1035,
"-zz": -1971,
"PROPKA": 954495146,
"A001Z": 100071,
"B0000": 1779616,
}
for k, v in test_values.items():
self.assertEqual(hybrid36.decode(k), v)
def testErrors(self):
test_values = [
"99X99",
"X9-99",
"XYZa",
"",
"-",
"!NotOk",
]
for v in test_values:
with self.assertRaises(ValueError) as e:
hybrid36.decode(v)
self.assertTrue(v in str(e.exception))