mirror of
https://github.com/python/cpython.git
synced 2024-12-17 05:43:48 +08:00
a3c242c19d
svn+ssh://pythondev@svn.python.org/python/trunk ........ r72558 | benjamin.peterson | 2009-05-11 01:52:09 +0200 (Mo, 11 Mai 2009) | 1 line sys.setdefaultencoding() strikes me as a bad example ........ r72745 | benjamin.peterson | 2009-05-17 16:16:29 +0200 (So, 17 Mai 2009) | 1 line ignore .rst files in sphinx its self ........ r72750 | benjamin.peterson | 2009-05-17 18:59:27 +0200 (So, 17 Mai 2009) | 1 line chop off slash ........ r72876 | benjamin.peterson | 2009-05-23 22:59:09 +0200 (Sa, 23 Mai 2009) | 1 line remove mention of old ctypes version ........ r73042 | benjamin.peterson | 2009-05-30 05:10:52 +0200 (Sa, 30 Mai 2009) | 1 line no fdatasync on macos ........ r73045 | georg.brandl | 2009-05-30 09:26:04 +0200 (Sa, 30 Mai 2009) | 1 line #6146: fix markup bug. ........ r73046 | georg.brandl | 2009-05-30 09:31:25 +0200 (Sa, 30 Mai 2009) | 1 line Use preferred form of raising exceptions. ........ r73047 | georg.brandl | 2009-05-30 12:33:23 +0200 (Sa, 30 Mai 2009) | 1 line Fix some more small markup problems. ........ r73048 | georg.brandl | 2009-05-30 12:34:25 +0200 (Sa, 30 Mai 2009) | 1 line Fix markup problem. ........ r73069 | benjamin.peterson | 2009-05-31 02:42:42 +0200 (So, 31 Mai 2009) | 1 line fix signature ........ r73089 | andrew.kuchling | 2009-06-01 02:14:19 +0200 (Mo, 01 Jun 2009) | 1 line The class for regexes isn't called RegexObject any more; correct the text ........ r73163 | georg.brandl | 2009-06-03 09:25:35 +0200 (Mi, 03 Jun 2009) | 1 line Use the preferred form of raise statements in the docs. ........ r73186 | georg.brandl | 2009-06-03 23:21:09 +0200 (Mi, 03 Jun 2009) | 1 line #6174: fix indentation in code example. ........ r73213 | georg.brandl | 2009-06-04 12:15:57 +0200 (Do, 04 Jun 2009) | 1 line #5967: note that the C slicing APIs do not support negative indices. ........ r73215 | georg.brandl | 2009-06-04 12:22:31 +0200 (Do, 04 Jun 2009) | 1 line #6176: fix man page section for flock(2). ........ r73217 | georg.brandl | 2009-06-04 12:27:21 +0200 (Do, 04 Jun 2009) | 1 line #6175: document that inet_aton supports alternate input formats with less than three dots. ........ r73257 | georg.brandl | 2009-06-06 19:50:05 +0200 (Sa, 06 Jun 2009) | 1 line #6211: elaborate a bit on ways to call the function. ........ r73258 | georg.brandl | 2009-06-06 19:51:31 +0200 (Sa, 06 Jun 2009) | 1 line #6204: use a real reference instead of "see later". ........ r73260 | georg.brandl | 2009-06-06 20:21:58 +0200 (Sa, 06 Jun 2009) | 1 line #6224: s/JPython/Jython/, and remove one link to a module nine years old. ........
81 lines
2.6 KiB
Python
81 lines
2.6 KiB
Python
"""Convert to and from Roman numerals"""
|
|
|
|
__author__ = "Mark Pilgrim (f8dy@diveintopython.org)"
|
|
__version__ = "1.4"
|
|
__date__ = "8 August 2001"
|
|
__copyright__ = """Copyright (c) 2001 Mark Pilgrim
|
|
|
|
This program is part of "Dive Into Python", a free Python tutorial for
|
|
experienced programmers. Visit http://diveintopython.org/ for the
|
|
latest version.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the Python 2.1.1 license, available at
|
|
http://www.python.org/2.1.1/license.html
|
|
"""
|
|
|
|
import re
|
|
|
|
#Define exceptions
|
|
class RomanError(Exception): pass
|
|
class OutOfRangeError(RomanError): pass
|
|
class NotIntegerError(RomanError): pass
|
|
class InvalidRomanNumeralError(RomanError): pass
|
|
|
|
#Define digit mapping
|
|
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):
|
|
"""convert integer to Roman numeral"""
|
|
if not (0 < n < 5000):
|
|
raise OutOfRangeError("number out of range (must be 1..4999)")
|
|
if int(n) != n:
|
|
raise NotIntegerError("decimals can not be converted")
|
|
|
|
result = ""
|
|
for numeral, integer in romanNumeralMap:
|
|
while n >= integer:
|
|
result += numeral
|
|
n -= integer
|
|
return result
|
|
|
|
#Define pattern to detect valid Roman numerals
|
|
romanNumeralPattern = re.compile("""
|
|
^ # beginning of string
|
|
M{0,4} # thousands - 0 to 4 M's
|
|
(CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
|
|
# or 500-800 (D, followed by 0 to 3 C's)
|
|
(XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
|
|
# or 50-80 (L, followed by 0 to 3 X's)
|
|
(IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
|
|
# or 5-8 (V, followed by 0 to 3 I's)
|
|
$ # end of string
|
|
""" ,re.VERBOSE)
|
|
|
|
def fromRoman(s):
|
|
"""convert Roman numeral to integer"""
|
|
if not s:
|
|
raise InvalidRomanNumeralError('Input can not be blank')
|
|
if not romanNumeralPattern.search(s):
|
|
raise InvalidRomanNumeralError('Invalid Roman numeral: %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
|