In ancient Rome a numeric system was used based on Roman numerals for the representation of integers. This numeric system is not a positional system, but an additive system in which the value of the integer is determined as the total sum of the digits used in the representation. The numbers one to ten can be expressed as Roman numerals as follows: I, II, III, IV, V, VI, VII, VIII, IX and X. Negative numbers and the zero value cannot be represented in the Roman numeric system. The Roman numeric system has largely become in disuse since the fourteenth century, in favor of the decimal numeric system that is based on Arab digits. However, Roman numeral are still in common use today in some applications, such as in numbering kings having the same name (e.g. Louis XIV of France), in numbering annual events and in numbering centuries in some countries (e.g. XIXe siècle).

In the Roman numeric system, integers are represented using symbols, the actual digits, where each symbol has a certain value independent of the position where it occurs in the integer representation. The symbols used in the Roman numeric system are:

symbol value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000

The order of the Roman digits in the integer representation is not random. The values of the individual digits are added, except if a symbol with a lower value is immediately followed by a symbol with a higher value: in that case, the lower value is subtracted instead of being added. The rules for representing integers using Roman numerals has been very loose in Ancient times. As such, in its credits the BBC used the typographically more elegant representation MIM for the year 1999, instead of MCMXCIX.

Assignment

PEP 3131 was a proposal to extend the Python programming language with support for the representation of Roman numerals as a literal data type. This proposal was rejected by Guido Van Rossum, who created the Python language and is nicknamed the Benevolent Dictator for Life (BDFL). However, since it is possible to extend Python by defining new data types, it is possible that we create or own data type to represent Roman numerals in Python. In order to do so, you proceed as follows:

Example

>>> roman2arab('MDCCCCX')
1910

>>> arab2roman(1910)
'MCMX'

>>> int(Roman('MDCCCCX'))
1910
>>> int(Roman('MCMLIV'))
1954
>>> int(Roman('MCMXC'))
1990
>>> rsum = Roman('MDCCCCX') + Roman('MCMXC')
>>> isinstance(rsum, Roman)
True
>>> print(rsum)
MMMCM
>>> difference = Roman('MCMXC') - Roman('MDCCCCX')
>>> isinstance(difference, Roman)
True
>>> str(difference)
'LXXX'
>>> product = Roman('CMX') * Roman('III')
>>> isinstance(product, Roman)
True
>>> product
MMDCCXXX

>>> print(Roman('mdccccx'))
MCMX
>>> Roman(1234)
MCCXXXIV
>>> Roman(4321)
Traceback (most recent call last):
AssertionError: invalid roman numeral
>>> Roman('ABCDEF')
Traceback (most recent call last):
AssertionError: invalid roman numeral
>>> Roman(3.14)
Traceback (most recent call last):
AssertionError: invalid roman numeral