"""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__ = "Steve Lamm, Mark Pilgrim (mark@diveintopython.org)"
__version__ = "$Revision: 1.3 $"
__date__ = "$Date: 2004/05/05 21:57:20 $"
__copyright__ = "Copyright (c) 2001 Steve Lamm, 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
#Liczby rzymskie muszą być mniejsze niż 5000
MAX_ROMAN_NUMERAL = 4999
#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))
#Utwórz tablice do szybkiej kowersji liczb na zapis rzymski i spowrotem.
#Zobacz: fillLookupTables() poniżej.
toRomanTable = [ None ] # Pomiń indeks zerowy, gdyż w zapisie rzymskim nie ma cyfry zero
fromRomanTable = {}
def toRoman(n):
u"""konwertuje liczbę całkowitą na jej reprezentację rzymską"""
if not (0 < n <= MAX_ROMAN_NUMERAL):
raise OutOfRangeError, u"liczba spoza przedziału (1..4999)"
if int(n) <> n:
raise NotIntegerError, u"liczby niecałkowite nie mogą być poddane konwersji"
return toRomanTable[n]
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 fromRomanTable.has_key(s):
raise InvalidRomanNumeralError, u'Nieprawidłowy zapis: %s' % s
return fromRomanTable[s]
def toRomanDynamic(n):
u"""konwersja liczby na jej reprezentację rzymską z użyciem programowania dynamicznego"""
assert(0 < n <= MAX_ROMAN_NUMERAL)
assert(int(n) == n)
result = ""
for numeral, integer in romanNumeralMap:
if n >= integer:
result = numeral
n -= integer
break
if n > 0:
result += toRomanTable[n]
return result
def fillLookupTables():
u"""generuje wszystkie możliwe liczby rzymskie"""
#Zapisz wygenerowane wartości w dwóch tablicach globalnych do konwersji z i do liczb rzymskich.
for integer in range(1, MAX_ROMAN_NUMERAL + 1):
romanNumber = toRomanDynamic(integer)
toRomanTable.append(romanNumber)
fromRomanTable[romanNumber] = integer
fillLookupTables()