skybreaker - 1 year ago 120

Python Question

I'm trying to write a code that converts a user-inputted integer into its Roman numeral equivalent. What I have so far is:

The point of the generate_all_of_numeral function is so that it creates a string for each specific numeral. For example, generate_all_of_numeral(2400, 'M', 2000) would return the string 'MM'.

I'm struggling with the main program. I start off finding the Roman numeral count for M and saving that into the variable M. Then I subtract by the number of M's times the symbol value to give me the next value to work with for the next largest numeral.

Any nod to the right direction? Right now my code doesn't even print anything.

Answer Source

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:
roman_num(num)
else:
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
```