"""Convert to and from Roman numerals
This program is part of "Dive Into Python", a free Python book for
experienced programmers. Visit http://diveintopython.org/ for the
latest version.
"""
__author__ = "Mark Pilgrim (mark@diveintopython.org)"
__version__ = "$Revision: 1.3 $"
__date__ = "$Date: 2004/05/05 21:57:20 $"
__copyright__ = "Copyright (c) 2001 Mark Pilgrim"
__license__ = "Python"
import re
#Klasy wyjątków
class RomanError(Exception): pass
class OutOfRangeError(RomanError): pass
class NotIntegerError(RomanError): pass
class InvalidRomanNumeralError(RomanError): pass
#Mapowanie znaków na liczby
romanNumeralMap = (('M', 1000),
('CM', 900),
('D', 500),
('CD', 400),
('C', 100),
('XC', 90),
('L', 50),
('XL', 40),
('X', 10),
('IX', 9),
('V', 5),
('IV', 4),
('I', 1))
def toRoman(n):
u"""konwertuje liczbę całkowitą na jej reprezentację rzymską"""
if not (0 < n < 4000):
raise OutOfRangeError, u"liczba spoza przedziału (1..3999)"
if int(n) <> n:
raise NotIntegerError, u"liczby niecałkowite nie mogą być poddane konwersji"
result = ""
for numeral, integer in romanNumeralMap:
while n >= integer:
result += numeral
n -= integer
return result
#Określ wzorzec do wykrywania prawidłowych zapisów liczb rzymskich
romanNumeralPattern = '^M?M?M?(CM|CD|D?C?C?C?)(XC|XL|L?X?X?X?)(IX|IV|V?I?I?I?)$'
def fromRoman(s):
u"""konwertuje zapis rzymski na liczbę całkowitą"""
if not s:
raise InvalidRomanNumeralError, u'Argument nie może być pusty'
if not re.search(romanNumeralPattern, s):
raise InvalidRomanNumeralError, u'Nieprawidłowy zapis: %s' % s
result = 0
index = 0
for numeral, integer in romanNumeralMap:
while s[index:index+len(numeral)] == numeral:
result += integer
index += len(numeral)
return result