Reputation: 37
I have a simple task to convert roman to int. this is the code I have been trying.
def romanToInt(s):
"""
:type s: str
:rtype: int
"""
j=0
print(len(s))
for i in range(len(s)):
k=s[i]
l=i+1
if s[i]=="I":
if s[l]=="V":
j+=4
elif s[l]=="X":
j+=9
elif s[i]=="X":
if s[l]=="L":
j+=40
elif s[l]=="C":
j+=90
elif s[i]=="C":
if s[l]=="D":
j+=400
elif s[l]=="M":
j+=900
else:
match k :
case "I":
j+=1
case "V":
j+=5
case "X":
j+=10
case "L":
j+=50
case "C":
j+=100
case "D":
j+=500
case "M":
j+=1000
return j
a=input("Enter number")
b=romanToInt(a)
print(b)
this code gives this error .
Enter numberIII
3
Traceback (most recent call last):
File "C:\Users\admin\Desktop\Dekstop Folder\pycharm\python\Leetcode\Roman to int.py", line 46, in <module>
b=romanToInt(a)
^^^^^^^^^^^^^
File "C:\Users\admin\Desktop\Dekstop Folder\pycharm\python\Leetcode\Roman to int.py", line 13, in romanToInt
if s[l]=="V":
~^^^
IndexError: string index out of range
Process finished with exit code 1
I dont know why it says String index out of range.
I tried printing the length and it is in the range but i dont know why it does not work. please help.
Upvotes: 1
Views: 75
Reputation: 120509
It's often better to iterate over elements rather than the index to avoid some IndexError
. zip
can help you iterate over both the current character and the next one.
Another way to do it:
table = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
def roman_to_int(s):
num = 0
for c1, c2 in zip(s, s[1:]):
v1, v2 = table[c1], table[c2]
num += v1 if v1 >= v2 else -v1
return num + v2 # don't forget to add the last element
Usage:
>>> roman_to_int('IX')
9
>>> roman_to_int('VII')
7
Note: this code doesn't check the validity of the roman numerals (VIIIII = 10)
Upvotes: 2
Reputation: 39
TL;DR: Use the roman.toRoman('XVII')
function from the roman
package, found on pypi, to do this quickly and painlessly.
As suggested in the comment, the 1=i+1
will force the check on the last I
to go outside range of the provided string.
The way you are implementing this is very tedious and repetitive. For this reason, I will not try to fix the "index out of range" error with repetitive if
statements.
Simply use a python package called roman that does this for you in one line:
import roman
a = input("Enter number: ")
b = roman.toRoman(a)
print(b)
Upvotes: 0
Reputation: 308500
As mentioned in the comments, your problem comes when i
reaches len(s)-1
, meaning l=i+1
is one past the end of the string.
Instead of using s[l]
, you could use a slice of s[l:l+1]
. This will return an empty string when l
is out of bounds instead of generating an error.
Upvotes: 1