Skip to content

Instantly share code, notes, and snippets.

@bloomonkey
Created June 11, 2013 07:09
Show Gist options
  • Save bloomonkey/5754968 to your computer and use it in GitHub Desktop.
Save bloomonkey/5754968 to your computer and use it in GitHub Desktop.
Convert Roman numeral strings to integers #PyPool
"""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