Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/docutils/utils/roman.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
author | shellac |
---|---|
date | Mon, 01 Jun 2020 08:59:25 -0400 |
parents | 79f47841a781 |
children |
comparison
equal
deleted
inserted
replaced
4:79f47841a781 | 5:9b1c78e6ba9c |
---|---|
1 """Convert to and from Roman numerals""" | |
2 | |
3 __author__ = "Mark Pilgrim (f8dy@diveintopython.org)" | |
4 __version__ = "1.4" | |
5 __date__ = "8 August 2001" | |
6 __copyright__ = """Copyright (c) 2001 Mark Pilgrim | |
7 | |
8 This program is part of "Dive Into Python", a free Python tutorial for | |
9 experienced programmers. Visit http://diveintopython.org/ for the | |
10 latest version. | |
11 | |
12 This program is free software; you can redistribute it and/or modify | |
13 it under the terms of the Python 2.1.1 license, available at | |
14 http://www.python.org/2.1.1/license.html | |
15 """ | |
16 | |
17 import re | |
18 | |
19 #Define exceptions | |
20 class RomanError(Exception): pass | |
21 class OutOfRangeError(RomanError): pass | |
22 class NotIntegerError(RomanError): pass | |
23 class InvalidRomanNumeralError(RomanError): pass | |
24 | |
25 #Define digit mapping | |
26 romanNumeralMap = (('M', 1000), | |
27 ('CM', 900), | |
28 ('D', 500), | |
29 ('CD', 400), | |
30 ('C', 100), | |
31 ('XC', 90), | |
32 ('L', 50), | |
33 ('XL', 40), | |
34 ('X', 10), | |
35 ('IX', 9), | |
36 ('V', 5), | |
37 ('IV', 4), | |
38 ('I', 1)) | |
39 | |
40 def toRoman(n): | |
41 """convert integer to Roman numeral""" | |
42 if not (0 < n < 5000): | |
43 raise OutOfRangeError("number out of range (must be 1..4999)") | |
44 if int(n) != n: | |
45 raise NotIntegerError("decimals can not be converted") | |
46 | |
47 result = "" | |
48 for numeral, integer in romanNumeralMap: | |
49 while n >= integer: | |
50 result += numeral | |
51 n -= integer | |
52 return result | |
53 | |
54 #Define pattern to detect valid Roman numerals | |
55 romanNumeralPattern = re.compile(""" | |
56 ^ # beginning of string | |
57 M{0,4} # thousands - 0 to 4 M's | |
58 (CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's), | |
59 # or 500-800 (D, followed by 0 to 3 C's) | |
60 (XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's), | |
61 # or 50-80 (L, followed by 0 to 3 X's) | |
62 (IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's), | |
63 # or 5-8 (V, followed by 0 to 3 I's) | |
64 $ # end of string | |
65 """, re.VERBOSE) | |
66 | |
67 def fromRoman(s): | |
68 """convert Roman numeral to integer""" | |
69 if not s: | |
70 raise InvalidRomanNumeralError('Input can not be blank') | |
71 | |
72 if not romanNumeralPattern.search(s): | |
73 raise InvalidRomanNumeralError('Invalid Roman numeral: %s' % s) | |
74 | |
75 result = 0 | |
76 index = 0 | |
77 for numeral, integer in romanNumeralMap: | |
78 while s[index:index+len(numeral)] == numeral: | |
79 result += integer | |
80 index += len(numeral) | |
81 return result | |
82 |