Hi I'm trying to solve this problem but I can't solve these errors
The idea of how I wanted to solve the problem is by first splitting the names into names and Roman number and after that converting Roman to Arabic numbers, after that sort like integers and do the conversion in reverse Arabic to Roman
def from_roman(num):
roman_numerals = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
result = 0
for i,c in enumerate(num):
if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
result += roman_numerals[c]
else:
result -= roman_numerals[c]
return result
# convert from arabic to roman
def to_roman(num):
roman_numerals = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'}
result=''
for i,c in enumerate(num):
if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
result += roman_numerals[c]
else:
result -= roman_numerals[c]
return result
def SortPrintKingsNames(kings):
romanList=[]
arabicList=[]
#sort kings name first
kings.sort()
#sort roman numbers by converting them to arabic and sorting them
for king in kings:
romanList.append(from_roman(king.split()[-1]))
romanList.sort()
#convert to roman again
for roman in romanList:
arabicList=to_roman(roman)
for k in kings:
# print names with roman number
print(k,arabicList[k])
Here are the errors:
Traceback (most recent call last):
File "Solution.py", line 58, in <module>
SortPrintKingsNames(kingsNames)
File "Solution.py", line 48, in SortPrintKingsNames
arabicList=to_roman(roman)
File "Solution.py", line 29, in to_roman
for i,c in enumerate(num):
TypeError: 'int' object is not iterable
The error is raised because you are trying to enumerate the arabic (integer) values.
Update the to_roman
function to resolve the issue.
Try this code:
def from_roman(num): # IV > 4
roman_numerals = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
result = 0
for i,c in enumerate(num):
if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
result += roman_numerals[c]
else:
result -= roman_numerals[c]
return result
# convert from arabic to roman
def to_roman(num): # 4 > IV
roman_numerals = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'}
result=''
for k in list(roman_numerals.keys())[::-1]:
while num >= k:
result+=roman_numerals[k]
num -= k
# do replacements based on 'max 3' rule
rt = [('DCCCC','CM'), ('CCCC','CD'), ('LXXXX','XC'), ('XXXX','XL'), ('VIIII','IX'), ('IIII','IV')]
for r in rt:
result = result.replace(*r) # convert tuple to args
# for i,c in enumerate(num):
# if (i+1) == len(num) or roman_numerals[c] >= roman_numerals[num[i+1]]:
# result += roman_numerals[c]
# else:
# result -= roman_numerals[c]
return result
def SortPrintKingsNames(kings):
print(kings)
romanList=[]
arabicList=[]
#sort kings name first
#kings.sort()
#sort roman numbers by converting them to arabic and sorting them
#romanlist = from_roman(kings)
for king in kings:
romanList.append(from_roman(king.split()[-1]))
print(romanList)
romanList.sort()
print(romanList)
#convert to roman again
for roman in romanList:
arabicList.append(to_roman(roman))
print(arabicList)
# for k in kings:
# print names with roman number
# print(k,arabicList[k])
k = SortPrintKingsNames(['VI','I','IC','XX'])
Output
['VI', 'I', 'IC', 'XX']
[6, 1, 99, 20]
[1, 6, 20, 99]
['I', 'VI', 'XX', 'XCIX']
Note that IC (99) is not a valid roman numeral, so it is converted to XCIX.
Replacements are done based on the 'max 3' rule. Only 6 replacements are needed for any number so it's cleaner to list the replacements instead of using a complicated loop.
Roman numeral rules (note rule #4):
https://classace.io/learn/math/3rdgrade/roman-numerals-ivxlcdm
As a side note, if this is being used for regnal numbers, the biggest number you need is 72 (LXXII).
https://en.wikipedia.org/wiki/Heinrich_LXXII,_Prince_Reuss_of_Lobenstein_and_Ebersdorf