1 # Functions to convert between integers and Roman numerals. Doctest examples included.
 
   3 # http://code.activestate.com/recipes/81611-roman-numerals/
 
   4 # PSFL (GPL compatible)
 
   6 def int_to_roman(input):
 
   8     Convert an integer to Roman numerals.
 
  12     Traceback (most recent call last):
 
  13     ValueError: Argument must be between 1 and 3999
 
  16     Traceback (most recent call last):
 
  17     ValueError: Argument must be between 1 and 3999
 
  20     Traceback (most recent call last):
 
  21     TypeError: expected integer, got <type 'float'>
 
  23     >>> for i in range(1, 21): print int_to_roman(i)
 
  45     >>> print int_to_roman(2000)
 
  47     >>> print int_to_roman(1999)
 
  50     if type(input) != type(1):
 
  51         raise TypeError, "expected integer, got %s" % type(input)
 
  52     if not 0 < input < 4000:
 
  53         raise ValueError, "Argument must be between 1 and 3999"    
 
  54     ints = (1000, 900,  500, 400, 100,  90, 50,  40, 10,  9,    5,  4,    1)
 
  55     nums = ('M',  'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')
 
  57     for i in range(len(ints)):
 
  58         count = int(input / ints[i])
 
  59         result += nums[i] * count
 
  60         input -= ints[i] * count
 
  63 def roman_to_int(input):
 
  65     Convert a roman numeral to an integer.
 
  67     >>> r = range(1, 4000)
 
  68     >>> nums = [int_to_roman(i) for i in r]
 
  69     >>> ints = [roman_to_int(n) for n in nums]
 
  73     >>> roman_to_int('VVVIV')
 
  74     Traceback (most recent call last):
 
  76     ValueError: input is not a valid roman numeral: VVVIV
 
  78     Traceback (most recent call last):
 
  80     TypeError: expected string, got <type 'int'>
 
  82     Traceback (most recent call last):
 
  84     ValueError: input is not a valid roman numeral: A
 
  85     >>> roman_to_int('IL')
 
  86     Traceback (most recent call last):
 
  88     ValueError: input is not a valid roman numeral: IL
 
  90     if type(input) != type(""):
 
  91         raise TypeError, "expected string, got %s" % type(input)
 
  93     nums = ['M', 'D', 'C', 'L', 'X', 'V', 'I']
 
  94     ints = [1000, 500, 100, 50,  10,  5,    1]
 
  98             raise ValueError, "input is not a valid roman numeral: %s" % input
 
  99     for i in range(len(input)):
 
 101         value = ints[nums.index(c)]
 
 102         # If the next place holds a larger number, this value is negative.
 
 104             nextvalue = ints[nums.index(input[i +1])]
 
 105             if nextvalue > value:
 
 108             # there is no next place.
 
 112     for n in places: sum += n
 
 113     # Easiest test for validity...
 
 114     if int_to_roman(sum) == input:
 
 117         raise ValueError, 'input is not a valid roman numeral: %s' % input