Basic Program to Convert Integer to Roman Numerals

Basic program to convert integer to Roman numerals?

One of the best ways to deal with this is using the divmod function. You check if the given number matches any Roman numeral from the highest to the lowest. At every match, you should return the respective character.

Some numbers will have remainders when you use the modulo function, so you also apply the same logic to the remainder. Obviously, I'm hinting at recursion.

See my answer below. I use an OrderedDict to make sure that I can iterate "downwards" the list, then I use a recursion of divmod to generate matches. Finally, I join all generated answers to produce a string.

from collections import OrderedDict

def write_roman(num):

roman = OrderedDict()
roman[1000] = "M"
roman[900] = "CM"
roman[500] = "D"
roman[400] = "CD"
roman[100] = "C"
roman[90] = "XC"
roman[50] = "L"
roman[40] = "XL"
roman[10] = "X"
roman[9] = "IX"
roman[5] = "V"
roman[4] = "IV"
roman[1] = "I"

def roman_num(num):
for r in roman.keys():
x, y = divmod(num, r)
yield roman[r] * x
num -= (r * x)
if num <= 0:
break

return "".join([a for a in roman_num(num)])

Taking it for a spin:

num = 35
print write_roman(num)
# XXXV

num = 994
print write_roman(num)
# CMXCIV

num = 1995
print write_roman(num)
# MCMXCV

num = 2015
print write_roman(num)
# MMXV

How to convert Python Integer to Roman Numeral and vice-versa?

Here's my take on an OOP approach to this.

We have a class Number which can be constructed in one of 3 ways. Either with a plain int, a string representation of an int or a Roman numeral.

The internal representation of the value is converted to a plain int.

Users can use the class's asInteger() and asRoman() functions to retrieve the class's value as an int or as a Roman numeral. These methods are impervious to the way the class was constructed.

Users can perform addition or subtraction using plain int or other instances of the Number class.

Examples of use follow the code:

class Number:
control = [
(1000, 'M', 1),
(900, 'CM', 2),
(500, 'D', 1),
(400, 'CD', 2),
(100, 'C', 1),
(90, 'XC', 2),
(50, 'L', 1),
(40, 'XL', 2),
(10, 'X', 1),
(9, 'IX', 2),
(5, 'V', 1),
(4, 'IV', 2),
(1, 'I', 1)]

def __init__(self, value):
if isinstance(value, int):
self.value = value
elif value.isdigit():
self.value = int(value)
else:
self.value = self._toInteger(value)
if value != self.toRoman(self.value):
raise ValueError('Not a valid Roman numeral')

def asInteger(self):
return self.value

def asRoman(self):
return self.toRoman(self.value)

def toRoman(self, num):
if num == 0:
return ''
for v, c, _ in Number.control:
if num >= v:
return c + self.toRoman(num-v)

def _toInteger(self, num):
result, offset = 0, 0
for c, r, l in Number.control:
while num[offset:].startswith(r):
result += c
offset += l
return result

def __add__(self, o):
if isinstance(o, Number):
self.value += o.value
elif isinstance(o, int):
self.value += o
else:
raise ValueError
return self

def __sub__(self, o):
if isinstance(o, Number):
self.value -= o.value
elif isinstance(o, int):
self.value -= o
else:
raise ValueError
return self

n = Number('MCMI')
m = Number(5)
print(n.asRoman())
n += m
print(n.asRoman())
m = 4
n -= m
print(n.asRoman())

Output:

MCMI
MCMVI
MCMII

Basic program to convert integer to Roman numerals?

One of the best ways to deal with this is using the divmod function. You check if the given number matches any Roman numeral from the highest to the lowest. At every match, you should return the respective character.

Some numbers will have remainders when you use the modulo function, so you also apply the same logic to the remainder. Obviously, I'm hinting at recursion.

See my answer below. I use an OrderedDict to make sure that I can iterate "downwards" the list, then I use a recursion of divmod to generate matches. Finally, I join all generated answers to produce a string.

from collections import OrderedDict

def write_roman(num):

roman = OrderedDict()
roman[1000] = "M"
roman[900] = "CM"
roman[500] = "D"
roman[400] = "CD"
roman[100] = "C"
roman[90] = "XC"
roman[50] = "L"
roman[40] = "XL"
roman[10] = "X"
roman[9] = "IX"
roman[5] = "V"
roman[4] = "IV"
roman[1] = "I"

def roman_num(num):
for r in roman.keys():
x, y = divmod(num, r)
yield roman[r] * x
num -= (r * x)
if num <= 0:
break

return "".join([a for a in roman_num(num)])

Taking it for a spin:

num = 35
print write_roman(num)
# XXXV

num = 994
print write_roman(num)
# CMXCIV

num = 1995
print write_roman(num)
# MCMXCV

num = 2015
print write_roman(num)
# MMXV

How to convert an integer into a roman numeral?

Your problem stems from the fact that you're passing a list with a character inside to your function. And that function expects an integer (if number in range(0, 9)), so you need to convert it to the right integer.

import sys

def numToRom(number):
if type(number) is list: # If you know your number might be a list with only one str(value)
number = int(number[0])

rom = ["", "I", "III", "IV", "V", "VI", "VII", "VIII", "IX"]

if number in range(0, 9):
result = rom[number]
return result

That will work specifically for your use case, if number is of the form ['{some digit}]. If you want to get fancier, you could use recursion to return a list with the roman number of each number in a list, like so:

def numToRom(number):
if type(number) is list:
rom = []
for value in number:
rom.append(numToRom(int(value)))
return rom
else:
rom = ["", "I", "III", "IV", "V", "VI", "VII", "VIII", "IX"]

if number in range(0, 9):
result = rom[number]
return result

>>> num = ['2', '3', '5']
>>> numToRom(num)
['2', '3', '5'] is ['III', 'IV', 'VI']

Note that this function works even if the values inside the input list are not characters, but normal integers.

>>> num = [2, 3, 5]
>>> rom = numToRom(num)
[2, 3, 5] is ['III', 'IV', 'VI']


Related Topics



Leave a reply



Submit