Created
June 11, 2013 07:09
-
-
Save bloomonkey/5754968 to your computer and use it in GitHub Desktop.
Convert Roman numeral strings to integers
#PyPool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Roman Numeral to Arabic Numbers. | |
Some doctests: | |
>>> convert_to_arabic('Nulla') | |
0 | |
>>> convert_to_arabic('i') | |
1 | |
>>> convert_to_arabic('v') | |
5 | |
>>> convert_to_arabic('x') | |
10 | |
>>> convert_to_arabic('l') | |
50 | |
>>> convert_to_arabic('c') | |
100 | |
>>> convert_to_arabic('d') | |
500 | |
>>> convert_to_arabic('m') | |
1000 | |
>>> convert_to_arabic('MMXiV') | |
2014 | |
>>> c2a('MCMLIV') | |
1954 | |
>>> c2a('MDCCCCLXXXXVIIII') | |
1999 | |
Check for handling of expected errors: | |
>>> c2a('MMCIIV') | |
Traceback (most recent call last): | |
... | |
ValueError: MMCIIV non valet numerales Romani | |
>>> c2a('cow') | |
Traceback (most recent call last): | |
... | |
ValueError: O is not a roman numeral | |
>>> c2a('ivx') | |
Traceback (most recent call last): | |
... | |
ValueError: IVX non valet numerales Romani | |
""" | |
import sys | |
lookup_table = { | |
'I': 1, | |
'V': 5, | |
'X': 10, | |
'L': 50, | |
'C': 100, | |
'D': 500, | |
'M': 1000 | |
} | |
def _test(): | |
import doctest | |
doctest.testmod(verbose=True) | |
def convert_to_arabic(roman): | |
global lookup_table | |
roman = roman.upper() | |
number = 0 | |
inSubtract = False | |
if roman == 'NULLA': | |
return number | |
# Check input only contains roman numerals | |
for char in roman: | |
if char not in lookup_table: | |
raise ValueError("{char} is not a roman numeral".format(char=char)) | |
reversed_roman = roman[::-1] | |
for i, char in enumerate(reversed_roman): | |
if i == 0: | |
number += lookup_table[char] | |
elif lookup_table[char] < lookup_table[reversed_roman[i - 1]]: | |
if inSubtract: | |
# Must be 2 consecutive subtractions | |
raise ValueError("{0} non valet numerales Romani".format(roman)) | |
number -= lookup_table[char] | |
inSubtract = True | |
elif lookup_table[char] <= lookup_table[reversed_roman[i - 1]] and inSubtract: | |
raise ValueError("{0} non valet numerales Romani".format(roman)) | |
else: | |
number += lookup_table[char] | |
inSubtract = False | |
return number | |
# Alias function for less typing! | |
c2a = convert_to_arabic | |
if __name__ == "__main__" and '-t' in sys.argv: | |
_test() | |
else: | |
for roman in sys.argv[1:]: | |
print convert_to_arabic(roman) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment