#!/usr/bin/python3
# ===================================================================
# Converting Roman Numerals To Decimal
#
# From: stackoverflow.com/questions/9073150/
# converting-roman-numerals-to-decimal
#
# I found this code on the web. I really like the recursive
# approach to solving the problem. (Note: It was originally
# written in javascript.)
#
# ===================================================================
# This code does not recognize the following error situation:
#
# A letter cannot be repeated more than 3 times, and only powers
# of 10 can be repeated. IIII converts to 4 but is not
# allowed by the rules for roman numerals.
#
# Perhaps check for bad input before trying to convert?
# re.search("IIII")
# re.search("XXXX")
# re.search("CCCC")
# re.search("LL")
# re.search("CC")
# re.search("DD")
#
# ===================================================================
# Rules for writing roman numerals
# (From: www.cuemath.com/numbers/roman-numerals/)
#
# a. The letters I,X,C can be repeated three time in succession.
# L, V, D cannot be repeated or the number is considered to
# be invalid.
# b. If a lower value digit is written to the left of a higher
# value digit, it is subtracted
# c. If a lower value digit is written to the right of a higher
# value, it is added
# d.Only I,X and C can be used as subtractive numerals
#
# ===================================================================
import re
import sys
# -------------------------------------------------------------------
# ---- convert roman numerals to decimal (recursive function)
# ---- input must be all caps
# -------------------------------------------------------------------
def roman_to_integer(nstr):
print(f'*** roman_to_integer({nstr})')
if nstr == '':
return 0
if re.match("^M",nstr):
return 1000 + roman_to_integer(nstr[1:])
if re.match("^CM",nstr):
return 900 + roman_to_integer(nstr[2:])
if re.match("^D",nstr):
return 500 + roman_to_integer(nstr[1:])
if re.match("^CD",nstr):
return 400 + roman_to_integer(nstr[2:])
if re.match("^C",nstr):
return 100 + roman_to_integer(nstr[1:])
if re.match("^XC",nstr):
return 90 + roman_to_integer(nstr[2:])
if re.match("^L",nstr):
return 50 + roman_to_integer(nstr[1:])
if re.match("^XL",nstr):
return 40 + roman_to_integer(nstr[2:])
if re.match("^X",nstr):
return 10 + roman_to_integer(nstr[1:])
if re.match("^IX",nstr):
return 9 + roman_to_integer(nstr[2:])
if re.match("^V",nstr):
return 5 + roman_to_integer(nstr[1:])
if re.match("^IV",nstr):
return 4 + roman_to_integer(nstr[2:])
if re.match("^I",nstr):
return 1 + roman_to_integer(nstr[1:])
print('error: something bad happened with ({nstr})')
sys.exit()
# -------------------------------------------------------------------
# ---- main
# -------------------------------------------------------------------
if __name__ == '__main__':
import user_interface as ui
while(True):
ui.clear_screen()
print()
s = ui.get_user_input('Enter roman number: ')
if not s:
break
n = roman_to_integer(s.upper())
print()
if n > 0:
print(f'roman number is {n} decimal')
else:
print(f'bad roman number input ({s})')
ui.pause()