roman.py

Go to the documentation of this file.
00001 ##
00002 # 
00003 # Provides two functions to convert back and forth between roman and
00004 # decimal numbers.
00005 # 
00006 # Copyright (C) 2002 GDS Software
00007 # 
00008 # This program is free software; you can redistribute it and/or
00009 # modify it under the terms of the GNU General Public License as
00010 # published by the Free Software Foundation; either version 2 of
00011 # the License, or (at your option) any later version.
00012 # 
00013 # This program is distributed in the hope that it will be useful,
00014 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 # GNU General Public License for more details.
00017 # 
00018 # You should have received a copy of the GNU General Public
00019 # License along with this program; if not, write to the Free
00020 # Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00021 # MA  02111-1307  USA
00022 # 
00023 # See http://www.gnu.org/licenses/licenses.html for more details.
00024 # 
00025 
00026 import re
00027 __version__ = "$Id: roman.py,v 1.3 2002/08/21 12:41:49 donp Exp $"
00028 
00029 iv = re.compile("IV")
00030 ix = re.compile("IX")
00031 xl = re.compile("XL")
00032 xc = re.compile("XC")
00033 cd = re.compile("CD")
00034 cm = re.compile("CM")
00035 i  = re.compile("I" )
00036 v  = re.compile("V" )
00037 x  = re.compile("X" )
00038 l  = re.compile("L" )
00039 c  = re.compile("C" )
00040 d  = re.compile("D" )
00041 m  = re.compile("M" )
00042 
00043 def RomanNumeralsToDecimal(roman_string):
00044     import re, string
00045     str = string.upper(roman_string)
00046     exp = ""
00047     if iv.search(str) != None:  str = iv.sub("+4",    str)
00048     if ix.search(str) != None:  str = ix.sub("+9",    str)
00049     if xl.search(str) != None:  str = xl.sub("+40",   str)
00050     if xc.search(str) != None:  str = xc.sub("+90",   str)
00051     if cd.search(str) != None:  str = cd.sub("+400",  str)
00052     if cm.search(str) != None:  str = cm.sub("+900",  str)
00053     if  i.search(str) != None:  str =  i.sub("+1",    str)
00054     if  v.search(str) != None:  str =  v.sub("+5",    str)
00055     if  x.search(str) != None:  str =  x.sub("+10",   str)
00056     if  l.search(str) != None:  str =  l.sub("+50",   str)
00057     if  c.search(str) != None:  str =  c.sub("+100",  str)
00058     if  d.search(str) != None:  str =  d.sub("+500",  str)
00059     if  m.search(str) != None:  str =  m.sub("+1000", str)
00060     exec "num = " + str
00061     return num
00062     
00063 
00064 ##
00065 # Translated from a public domain C routine by Jim Walsh in the
00066 #     Snippets collection.
00067 #     
00068 def DecimalToRomanNumerals(base10_integer):
00069     roman = ""
00070     n, base10_integer = divmod(base10_integer, 1000)
00071     roman = "M"*n
00072     if base10_integer >= 900:
00073         roman = roman + "CM"
00074         base10_integer = base10_integer - 900
00075     while base10_integer >= 500:
00076         roman = roman + "D"
00077         base10_integer = base10_integer - 500
00078     if base10_integer >= 400:
00079         roman = roman + "CD"
00080         base10_integer = base10_integer - 400
00081     while base10_integer >= 100:
00082         roman = roman + "C"
00083         base10_integer = base10_integer - 100
00084     if base10_integer >= 90:
00085         roman = roman + "XC"
00086         base10_integer = base10_integer - 90
00087     while base10_integer >= 50:
00088         roman = roman + "L"
00089         base10_integer = base10_integer - 50
00090     if base10_integer >= 40:
00091         roman = roman + "XL"
00092         base10_integer = base10_integer - 40
00093     while base10_integer >= 10:
00094         roman = roman + "X"
00095         base10_integer = base10_integer - 10
00096     if base10_integer >= 9:
00097         roman = roman + "IX"
00098         base10_integer = base10_integer - 9
00099     while base10_integer >= 5:
00100         roman = roman + "V"
00101         base10_integer = base10_integer - 5
00102     if base10_integer >= 4:
00103         roman = roman + "IV"
00104         base10_integer = base10_integer - 4
00105     while base10_integer > 0:
00106         roman = roman + "I"
00107         base10_integer = base10_integer - 1
00108     return roman
00109 
00110 if __name__ == "__main__":
00111     '''We'll test the conversion routines by converting from a decimal
00112     integer n to a Roman numeral and then back again.  If the operations
00113     are not the identity transformation, it's an error.
00114     '''
00115     largest_number = 5000
00116     for num in xrange(1,largest_number+1):
00117         str = DecimalToRomanNumerals(int(num))
00118         number = RomanNumeralsToDecimal(str)
00119         if number != num:
00120             print "Routines failed for", num
00121             raise "Test failure"
00122     print "Test passed."
00123 
00124 

© Copyright 2008-2009 Vyper Logix Corp., All Right Reserved; If you reference this document or any part of this document you must use the citation verbatim (including the link) "© Copyright 2008-2009 Vyper Logix Corp., All Right Reserved."

Notice: This source code contained in this document is NOT open source and is NOT being distributed as open source.

122,241 lines of code and growing...