pythonooproman-numerals

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


I am trying to write a Python program that accepts integer as input and displays the equivalent roman numeral and vice-versa. The program should be written in OOP. I have right now is the structure of the class and its methods but I can't execute the conversion, does anyone know a good way to use OOP to my problem? It's an assigned homework as part of my learning of scientific computing with Python. I am open to other good approaches you may have that follows and satisfies the given test cases below as long as it is in OOP.

Important Requirements:

See Roman Numerals Table

import sys


class Convert:
    """Accepts integer as input and display
    the equivalent roman numeral and vice-versa.
    """

    def __int__(self, user_input):
        """Initialize attributes."""
        self.user_input = user_input

    def int_to_roman(self):
        """Convert integer input to roman."""
        pass

    def roman_to_int(self):
        """Convert roman input to integer."""
        pass


# Main Menu
def main():
    print("\nMENU")
    print("[1] Convert an Integer to a Roman Numeral")
    print("[2] convert a Roman Numeral to an Integer")
    print("[3] exit")


while True:
    main()
    choice = eval(input("\nEnter your choice: "))

    if choice == 1:
        # call int_to_roman() method
        # after output, return to main()
        pass
    elif choice == 2:
        # call roman_to_int() method
        # after output, return to main()
        pass
    elif choice == 3:
        sys.exit()


**TEST CASE 1**

MENU
[1] Convert an Integer to a Roman Numeral
[2] Convert a Roman Numeral to an Integer
[3] exit

Enter your choice: 1
Enter Integer: 1
Output in Roman Numeral is: I

Enter Integer: 3000
Output in Roman Numeral is: MMM

------------------------------------

**TEST CASE 2**

Enter your choice: 2
Enter Roman Numeral: MMM
Output in Integer is: 3000

Enter Roman Numeral: I
Output in Integer is: 1

Solution

  • 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