2 Replies - 414 Views - Last Post: 16 February 2014 - 05:33 PM Rate Topic: -----

#1 cupppycupp  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 15-February 14

Simple Integer to Roman numeral converter

Posted 15 February 2014 - 11:29 PM

I've just started to program with python without any prior coding experience whatsoever. At the moment I am trying to code up a program that will convert and integer to a roman numeral. When coding i'll only be able to use if/elif/else statements and while loops, along with certain keywords like and , or , and print. I can't use functions or the keyword 'return'.
Here's what i've written so far, it feels really long and clunky to me.
number = int(raw_input('Enter a number between 1 and 3999: '))



if number < 4:
    print 'I' * number

elif number % 10 == 1 and number < 50:
    if number < 40:
        print 'X' * (number / 10) + 'I'
    else:
        print 'XLI'

elif number % 10 == 2 and number < 50:
    if number < 40:
        print 'X' * (number / 10) + 'II'
    else:
        print 'XLII'

elif number % 10 == 3 and number < 50:
    if number < 40:
        print 'X' * (number / 10) + 'III'
    else:
        print 'XLIII'
    
elif number % 10 == 4 and number < 50:
    if number < 40:
        print 'X' * (number / 10) + 'IV'
    else:
        print 'XLIV'

elif number % 10 == 5 and number < 50:
    if number < 40:
        print 'X' * (number / 10) + 'V'
    else:
        print 'XLV'
    
elif number % 10 == 6 and number < 50:
    if number < 40:
        print 'X' * (number / 10) + 'VI'
    else:
        print 'XLVI'
    
elif number % 10 == 9 and number < 50:
    if number < 40:
        print 'X' * (number / 10) + 'IX'
    else:
        print 'XLIX'

elif number % 10 == 0 and number < 50:
    if number < 40:
        print 'X' * (number / 10)
    else:
        print 'XL'

# 50 > Number > 100

elif number == 50:
    print 'L'
#1
elif number% 50 % 10 == 1 and number < 100:
    if number < 90:
        print 'L' + 'X' * (number % 50 / 10) + 'I'
    else:
        print 'XCI'
#2
elif number % 50 % 10 == 2 and number < 100:
    if number < 90:
        print 'L' + 'X' * (number % 50 / 10) + 'II'
    else:
        print 'XCII'
#3
elif number % 50 % 10 == 3 and number < 100:
    if number < 90:
        print 'L' + 'X' * (number % 50 / 10) + 'III'
    else:
        print 'XCII'
#4
elif number % 50 % 10 == 4 and number < 100:
    if number < 90:
        print 'L' + 'X' * (number % 50 / 10) + 'IV'
    else:
        print 'XCIV'
#5
elif number % 50 % 10 == 5 and number < 100:
    if number < 90:
        print 'L' + 'X' * (number % 50 / 10) + 'V'
    else:
        print 'XCV'
#6
elif number % 50 % 10 == 6 and number < 100:
    if number < 90:
        print 'L' + 'X' * (number % 50 / 10) + 'VI'
    else:
        print 'XCVI'
#7
elif number % 50 % 10 == 7 and number < 100:
    if number < 90:
        print 'L' + 'X' * (number % 50 / 10) + 'VII'
    else:
        print 'XCVII'
#8
elif number % 50 % 10 == 8 and number < 100:
    if number < 90:
        print 'L' + 'X' * (number % 50 / 10) + 'VIII'
    else:
        print 'XCVIII'
#9
elif number % 50 % 10 == 9 and number < 100:
    if number < 90:
        print 'L' + 'X' * (number % 50 / 10) + 'IX'
    else:
        print 'XCIX'


I've been having trouble thinking of ways i can make this shorter and nicer. A few pointers in the right direction would be greatly appreciated!

-cupppy :)

Is This A Good Question/Topic? 0
  • +

Replies To: Simple Integer to Roman numeral converter

#2 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5777
  • View blog
  • Posts: 12,591
  • Joined: 16-October 07

Re: Simple Integer to Roman numeral converter

Posted 16 February 2014 - 05:40 AM

Step 1, write your code so you can test it. This would involve a function. Something like:
def toRoman(number):
    if number < 4:
        print 'I' * number

    elif number % 10 == 1 and number < 50:
#...

number = int(raw_input('Enter a number between 1 and 3999: '))
toRoman(number)



With that in place, you can run some checks...
for i in range(1,21):
    print i,
    # this had to be done because you print, rather than return, a value
    toRoman(i)



Results:
1 I
2 II
3 III
4 IV
5 V
6 VI
7 LVII
8 LVIII
9 IX
10 X
11 XI
12 XII
13 XIII
14 XIV
15 XV
16 XVI
17 LXVII
18 LXVIII
19 XIX
20 XX



You got something wonky going on with the Ls.

You're clearly reinventing the wheel with each sub category. Instead, use a loop and work your way down. A list also helps here, but I'll avoid that for now.

What if the highest symbol I know is X. How high can I count? I believe I can get all the way up to 39...

def toRoman(n):
    # note, once you have this all the way up to M, you only need bounds check <1
    if n<1 or n>39:
        return "ERR"

    # our result
    result = ""
    # loop: we want to keep going while there is value left in our number
    while n>0:
        if n>=10:
            result += "X" # we add the symbol to our result
            n -= 10       # we decrement the number by the value of the symbol
        # this is where it gets interesting
        # at each level, if you allow for 9s and 4s, you're good
        elif n==9: 
            result += "IX"
            n -= 9
        elif n>=5: 
            result += "V"
            n -= 5
        elif n==4: 
            result += "IV"
            n -= 4
        else:
            # if you got here, you're still >0, so
            result += "I"
            n -= 1
    return result

print([(i,toRoman(i)) for i in range(42)])



Results:
[(0, 'ERR'), (1, 'I'), (2, 'II'), (3, 'III'), (4, 'IV'), (5, 'V'), (6, 'VI'), (7, 'VII'), (8, 'VIII'), (9, 'IX'), (10, 'X'), (11, 'XI'), (12, 'XII'), (13, 'XIII'), (14, 'XIV'), (15, 'XV'), (16, 'XVI'), (17, 'XVII'), (18, 'XVIII'), (19, 'XIX'), (20, 'XX'), (21, 'XXI'), (22, 'XXII'), (23, 'XXIII'), (24, 'XXIV'), (25, 'XXV'), (26, 'XXVI'), (27, 'XXVII'), (28, 'XXVIII'), (29, 'XXIX'), (30, 'XXX'), (31, 'XXXI'), (32, 'XXXII'), (33, 'XXXIII'), (34, 'XXXIV'), (35, 'XXXV'), (36, 'XXXVI'), (37, 'XXXVII'), (38, 'XXXVIII'), (39, 'XXXIX'), (40, 'ERR'), (41, 'ERR')]



Note, this is still not the most optimized code. You see I repeat n= and n-= in the block. If I simply had a list of values in the proper order I could just loop through...

Hope this helps.
Was This Post Helpful? 1
  • +
  • -

#3 woooee  Icon User is offline

  • D.I.C Head

Reputation: 21
  • View blog
  • Posts: 78
  • Joined: 21-November 12

Re: Simple Integer to Roman numeral converter

Posted 16 February 2014 - 05:33 PM

This is a simple example using lists to convert for numbers up to 100 (if I understand Roman Numerals correctly). To make this workable code for larger numbers, you would possibly want to use a dictionary to convert for however many digits you want as a max. Or you can use a list of lists and process the number right to left, so the units would access the zero sub-list to use to convert, tens the [1] sub-list, etc. Note the code is not thoroughly tested and is meant to be an example for a starting point. Whenever code contains many if/elif/else statements, there is a usually a better way to code it.
units=("", "I", "II", "III",  "IV", "V",
       "VI", "VII", "VIII", "IX")
tens=("", "X", "XX", "XXX", "XL", "L",
      "LX", "LXX", "LXXX", "XC")

for test_it in range(100):
    ten, unit = divmod(test_it, 10)
    print test_it, tens[ten]+units[unit]

This post has been edited by woooee: 16 February 2014 - 05:47 PM

Was This Post Helpful? 1
  • +
  • -

Page 1 of 1