From 871a3f6a2425c74ec439612e6ad917f2128a96cc Mon Sep 17 00:00:00 2001 From: Jack Wearden Date: Sun, 16 Mar 2014 14:44:16 +0000 Subject: [PATCH 1/3] Initial Version This was made by myself and @Banford --- romans.py | 35 +++++++++++++++++++++++++++++++++++ romans.test.py | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 romans.py create mode 100644 romans.test.py diff --git a/romans.py b/romans.py new file mode 100644 index 0000000..7893611 --- /dev/null +++ b/romans.py @@ -0,0 +1,35 @@ +class Romans: + + def __init__(self, value): + if type(value) == str: + self._str = value + self._num = Romans.str_to_num(value) + elif type(value) == int: + self._str = "" + self._num = value + + def __str__(self): + return self._str + + def __int__(self): + return self._num + + @staticmethod + def str_to_num(value): + values = { + "I": 1, + "V": 5, + "X": 10, + "L": 50, + "C": 100, + "D": 500, + "M": 1000 + } + + result = [values.get(i) for i in value] + + for i in range(len(result)): + if result[i] < result[min(len(result)-1, i+1)]: + result[i] *= -1 + + return sum(result) diff --git a/romans.test.py b/romans.test.py new file mode 100644 index 0000000..be57fd1 --- /dev/null +++ b/romans.test.py @@ -0,0 +1,40 @@ +import unittest +from romans import Romans as R + +class TestRomans(unittest.TestCase): + + def test_i(self): + self.assertEqual(1, int(R("I"))) + + def test_v(self): + self.assertEqual(5, int(R("V"))) + + def test_x(self): + self.assertEqual(10, int(R("X"))) + + def test_l(self): + self.assertEqual(50, int(R("L"))) + + def test_c(self): + self.assertEqual(100, int(R("C"))) + + def test_d(self): + self.assertEqual(500, int(R("D"))) + + def test_m(self): + self.assertEqual(1000, int(R("M"))) + + def test_ii(self): + self.assertEqual(2, int(R("II"))) + + def test_iv(self): + self.assertEqual(4, int(R("IV"))) + + def test_xlix(self): + self.assertEqual(49, int(R("XLIX"))) + + def test_mmm(self): + self.assertEqual(3000, int(R("MMM"))) + +if __name__ == '__main__': + unittest.main() From 1b088001c750e53a3a58540e7ef05b48ceb2e2af Mon Sep 17 00:00:00 2001 From: Jack Wearden Date: Sun, 16 Mar 2014 15:52:03 +0000 Subject: [PATCH 2/3] In the other direction --- romans.py | 22 +++++++++++++++++++++- romans.test.py | 24 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/romans.py b/romans.py index 7893611..484d7dd 100644 --- a/romans.py +++ b/romans.py @@ -5,7 +5,7 @@ def __init__(self, value): self._str = value self._num = Romans.str_to_num(value) elif type(value) == int: - self._str = "" + self._str = Romans.num_to_str(value) self._num = value def __str__(self): @@ -33,3 +33,23 @@ def str_to_num(value): result[i] *= -1 return sum(result) + + @staticmethod + def num_to_str(value): + values = { + 1: "I", + 5: "V", + 10: "X", + 50: "L", + 100: "C", + 500: "D", + 1000: "M" + } + result = "" + for v in sorted(values.keys(), reverse=True): + unit_count = value // v + result += values[v] * unit_count + value -= unit_count * v + + result = result.replace("VIIII", "IX").replace("LXXXX", "XC").replace("DCCCC", "CM") + return result.replace("IIII", "IV").replace("XXXX", "XL").replace("CCCC", "CD") diff --git a/romans.test.py b/romans.test.py index be57fd1..1005ada 100644 --- a/romans.test.py +++ b/romans.test.py @@ -36,5 +36,29 @@ def test_xlix(self): def test_mmm(self): self.assertEqual(3000, int(R("MMM"))) + def test_1(self): + self.assertEqual("I", str(R(1))) + + def test_2(self): + self.assertEqual("II", str(R(2))) + + def test_3000(self): + self.assertEqual("MMM", str(R(3000))) + + def test_9(self): + self.assertEqual("IX", str(R(9))) + + def test_49(self): + self.assertEqual("XLIX", str(R(49))) + + def test_400(self): + self.assertEqual("CD", str(R(400))) + + def test_900(self): + self.assertEqual("CM", str(R(900))) + + def test_999(self): + self.assertEqual("CMXCIX", str(R(999))) + if __name__ == '__main__': unittest.main() From 154a21892b2e0201266449e6ada9c43635bbcedb Mon Sep 17 00:00:00 2001 From: Jack Wearden Date: Fri, 11 Jul 2014 16:22:03 +0100 Subject: [PATCH 3/3] extract mappings to class --- romans.py | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/romans.py b/romans.py index 484d7dd..0e2d6c6 100644 --- a/romans.py +++ b/romans.py @@ -1,5 +1,25 @@ class Romans: + roman_from_num = { + 1: "I", + 5: "V", + 10: "X", + 50: "L", + 100: "C", + 500: "D", + 1000: "M" + } + + num_from_roman = { + "I": 1, + "V": 5, + "X": 10, + "L": 50, + "C": 100, + "D": 500, + "M": 1000 + } + def __init__(self, value): if type(value) == str: self._str = value @@ -16,17 +36,7 @@ def __int__(self): @staticmethod def str_to_num(value): - values = { - "I": 1, - "V": 5, - "X": 10, - "L": 50, - "C": 100, - "D": 500, - "M": 1000 - } - - result = [values.get(i) for i in value] + result = [num_from_roman.get(i) for i in value] for i in range(len(result)): if result[i] < result[min(len(result)-1, i+1)]: @@ -36,20 +46,11 @@ def str_to_num(value): @staticmethod def num_to_str(value): - values = { - 1: "I", - 5: "V", - 10: "X", - 50: "L", - 100: "C", - 500: "D", - 1000: "M" - } result = "" - for v in sorted(values.keys(), reverse=True): + for v in sorted(num_from_roman.keys(), reverse=True): unit_count = value // v - result += values[v] * unit_count - value -= unit_count * v + result += num_from_roman[v] * unit_count + value -= unit_count* v result = result.replace("VIIII", "IX").replace("LXXXX", "XC").replace("DCCCC", "CM") return result.replace("IIII", "IV").replace("XXXX", "XL").replace("CCCC", "CD")