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
Python Using Variables from Another File
How to Use Numpy.Correlate to Do Autocorrelation
Setting Up S3 for Logs in Airflow
Broken References in Virtualenvs
How to Convert an Int to a Hex String
Why Does the Floating-Point Value of 4*0.1 Look Nice in Python 3 But 3*0.1 Doesn'T
Python Insert Numpy Array into SQLite3 Database
How to Multiply Individual Elements of a List with a Number
How to Use a Default Namespace in an Lxml Xpath Query
Source Interface with Python and Urllib2
Scale Everything on Pygame Display Surface
What Does Model.Train() Do in Pytorch
What Is the Official "Preferred" Way to Install Pip and Virtualenv Systemwide
How to Compare Times of the Day
How to Get the Ip Address from a Http Request Using the Requests Library
Safely Create a File If and Only If It Does Not Exist with Python
Overflowerror: Long Int Too Large to Convert to Float in Python