numeral

Numeral: support for various integer-to-numeral (and back) conversion.

numeral._multi_replace(text, replaces)[source]

Perform multiple replacements in a string.

Parameters:
  • text (str) – The input string.
  • replaces (Sequence[Sequence[str]]) – The listing of the replacements. Format: ((<old>, <new>), …).
Returns:

The string after the performed replacements.

Return type:

text (str)

Examples

>>> _multi_replace('python.best', (('thon', 'mrt'), ('est', 'ase')))
'pymrt.base'
>>> _multi_replace('x-x-x-x', (('x', 'est'), ('est', 'test')))
'test-test-test-test'
>>> _multi_replace('x-x-', (('-x-', '.test'),))
'x.test'
numeral.int2letter(num, alphabet='abcdefghijklmnopqrstuvwxyz', negative_sign='-')[source]

Convert a number to the least amount letters (within an alphabet).

Items in the alphabet must not repeat.

This is the inverse of letter2int() given the same alphabet.

Parameters:
  • num (int) – The input number to convert.
  • alphabet (str) – The alphabet to use for the representation. Characters within the alphabet must not repeat.
  • negative_sign (str) – The symbol to use for negative numbers. The negative sign will be the first character of the representation.
Returns:

The integer represented.

Return type:

text (str)

Examples

>>> [int2letter(i) for i in range(14)]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n']
>>> [int2letter(i) for i in [23, 26, 27, 28, 29, 702, 703, 704, 1983]]
['x', 'aa', 'ab', 'ac', 'ad', 'aaa', 'aab', 'aac', 'bxh']
>>> all(n == letter2int(int2letter(n)) for n in range(-999, 99))
True

See also

letter2int(), tokens2int(), int2tokens()

numeral.int2roman(num, only_ascii=False, only_additive=False, extended=True, uppercase=True, claudian=False, alternatives=None, signed=True, negative_sign='-')[source]

Convert an integer to its corresponding Roman number representation.

Parameters:
  • num (int) – The input number to convert
  • only_ascii (bool) – Force the use of only-ASCII characters. If True only valid ASCII characters are used. The Apostrophus notation is forced to expand using the Claudian symbol (a specular C), which is in turn converted to a valid ASCII character with some resemblance to it, i.e. the letter O.
  • only_additive (bool) – Force only-additive notation. This means that the symbols are strictly sorted according decreasing value left-to-right and they all add up. Otherwise, a single lower-value symbol preceding a larger-value one is used to indicate subtraction, thus avoiding 4 symbols repetition.
  • extended (bool) – Allow for 0 and large numbers to be included. Large numbers are above 3999 if only_additive is False, otherwise they are above 4999.
  • uppercase (bool) – Use uppercase for the output. If False, the output is converted to lowercase.
  • claudian (bool) – Force the use of Claudian for apostrophus notation.
  • alternatives (Iterable[Iterable[str]]) – Use alternate symbols. Mostly useful in conjunction with ROMAN_ALTERNATIVES
  • signed (bool) – Accept negative numbers. The minus symbol is then prepended to string for negative numbers. No symbol is added for positive numbers.
  • negative_sign (str) – The symbol to use for negative numbers. The negative sign will be the first character of the representation.
Returns:

The converted Roman number.

By default the dedicated uppercase Unicode characters are used. This can be tweaked through the appropriate options.

Return type:

text (str)

Examples

>>> [int2roman(i) for i in range(13)]
['N', 'Ⅰ', 'Ⅱ', 'Ⅲ', 'Ⅳ', 'Ⅴ', 'Ⅵ', 'Ⅶ', 'Ⅷ', 'Ⅸ', 'Ⅹ', 'Ⅺ', 'Ⅻ']
>>> [int2roman(i) for i in range(13, 23)]
['ⅩⅢ', 'ⅩⅣ', 'ⅩⅤ', 'ⅩⅥ', 'ⅩⅦ', 'ⅩⅧ', 'ⅩⅨ', 'ⅩⅩ', 'ⅩⅪ', 'ⅩⅫ']
>>> [int2roman(i) for i in [44, 51, 62, 73, 84, 95, 99]]
['ⅩⅬⅣ', 'ⅬⅠ', 'ⅬⅫ', 'ⅬⅩⅩⅢ', 'ⅬⅩⅩⅩⅣ', 'ⅬⅩⅬⅤ', 'ⅬⅩⅬⅨ']
>>> [int2roman(i) for i in range(1666, 3999, 517)]
['ⅯⅮⅭⅬⅩⅥ', 'ⅯⅯⅭⅬⅩⅩⅩⅢ', 'ⅯⅯⅮⅭⅭ', 'ⅯⅯⅯⅭⅭⅩⅦ', 'ⅯⅯⅯⅮⅭⅭⅩⅩⅩⅣ']
>>> [int2roman(i) for i in range(-1666, 1666, 639)]
['-ⅯⅮⅭⅬⅩⅥ', '-ⅯⅩⅩⅦ', '-ⅭⅭⅭⅬⅩⅩⅩⅧ', 'ⅭⅭⅬⅠ', 'ⅮⅭⅭⅭⅬⅩⅬ', 'ⅯⅮⅩⅩⅨ']
>>> [int2roman(k * 10 ** i) for i in range(3, 6) for k in [4, 5, 10]]
['Ⅿↁ', 'ↁ', 'ↂ', 'ↂↇ', 'ↇ', 'ↈ', 'ↈↇↃ', 'ↇↃ', 'ⅭↈↃ']
>>> [int2roman(2 ** i) for i in range(14, 17)]
['ↂↁⅯⅭⅭⅭⅬⅩⅩⅩⅣ', 'ↂↂↂⅯⅯⅮⅭⅭⅬⅩⅧ', 'ↇↂↁⅮⅩⅩⅩⅥ']
>>> [int2roman(i, only_ascii=True) for i in [1666, 3999, 4000, 189000]]
['MDCLXVI', 'MMMDCDLXLIX', 'MDO', 'CCCDOODOOCCDOCCDOCCDODOMDO']
>>> [int2roman(i, only_additive=True) for i in [4, 49, 949, 9494]]
['ⅡⅡ', 'ⅩⅩⅩⅩⅦⅡ', 'ⅮⅭⅭⅭⅭⅩⅩⅩⅩⅦⅡ', 'ↁⅯⅯⅯⅯⅭⅭⅭⅭⅬⅩⅩⅩⅩⅡⅡ']
>>> [int2roman(i, extended=False) for i in range(3995, 4001)]
Traceback (most recent call last):
    ...
ValueError: `4000` needs `extended` option
>>> [int2roman(i, uppercase=False) for i in range(1666, 5000, 631)]
['ⅿⅾⅽⅼⅹⅵ', 'ⅿⅿⅽⅽⅼⅹⅼⅶ', 'ⅿⅿⅾⅽⅾⅹⅹⅷ', 'ⅿⅿⅿⅾⅼⅸ', 'ⅿⅾↄⅽⅼⅹⅼ', 'ⅿⅾↄⅾⅽⅽⅽⅹⅺ']
>>> [int2roman(i, claudian=True) for i in [1666, 3999, 4000, 189000]]
['ⅯⅮⅭⅬⅩⅥ', 'ⅯⅯⅯⅮⅭⅮⅬⅩⅬⅨ', 'ⅯⅮↃ', 'ⅭⅭↀↃↃⅮↃↃⅭↀↃⅭↀↃⅭↀↃⅮↃⅯⅮↃ']
>>> [int2roman(i, alternatives=ROMAN_ALTERNATIVES)
...  for i in [6, 50, 1000, 56, 1006, 1050, 1056, 1057]]
['ↅ', 'ↆ', 'ↀ', 'ↆↅ', 'ↀↅ', 'ↀↆ', 'ↀↆↅ', 'ↀↆⅦ']
>>> [int2roman(i, signed=False) for i in [1666, -1666]]
Traceback (most recent call last):
    ...
ValueError: `-1666` needs `signed` option
numeral.int2tokens(num, tokens, negative_sign='-')[source]

Convert a group of tokens (within a given set) to a number.

Items in the tokens set must not repeat/overlap.

This is the inverse of int2tokens() given the same tokens set.

Parameters:
  • num (int) – The input number to convert.
  • tokens (Iterable[str]) – The tokens to use for the representation. Items within the tokens set must not repeat or overlap.
  • negative_sign (str) – The symbol to use for negative numbers. The negative sign will be the first character of the representation.
Returns:

The integer represented.

Return type:

text (str)

Examples

>>> [int2tokens(i, ('0', '1')) for i in range(10)]
['0', '1', '00', '01', '10', '11', '000', '001', '010', '011']
>>> [int2tokens(i, ('a', 'b', 'c')) for i in range(10)]
['a', 'b', 'c', 'aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca']
>>> [int2tokens(i, 'abc') for i in range(10)]
['a', 'b', 'c', 'aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca']
>>> [int2tokens(i, ('po', 'ta')) for i in range(8)]
['po', 'ta', 'popo', 'pota', 'tapo', 'tata', 'popopo', 'popota']
>>> int2tokens(161, ('po', 'ta'))
'potapopopotata'
>>> d = ('mo', 'no', 'ke')
>>> all(n == tokens2int(int2tokens(n, d), d) for n in range(-999, 99))
True

See also

letter2int(), int2letter(), tokens2int()

numeral.letter2int(text, alphabet='abcdefghijklmnopqrstuvwxyz', negative_sign='-')[source]

Convert a group of letters (within a given alphabet) to a number.

Items in the alphabet must not repeat.

This is the inverse of int2letter() given the same alphabet.

Parameters:
  • text (str) – The input string to parse.
  • alphabet (str) – The alphabet to use for the representation. Characters within the alphabet must not repeat.
  • negative_sign (str) – The symbol to use for negative numbers. The negative sign must be the first character of the representation.
Returns:

The integer represented.

Return type:

num (int)

Raises:
  • ValueError – if text contains non-alphabet characters
  • ValueError – if negative_sign is in alphabet
  • ValueError – if negative_sign is present but not the first item

Examples

>>> [letter2int(s)
...     for s in ['a', 'z', 'aa', 'ad', 'aaa', 'aab', 'bxh']]
[0, 25, 26, 29, 702, 703, 1983]
>>> all(n == letter2int(int2letter(n)) for n in range(-99, 999))
True

See also

int2letter(), tokens2int(), int2tokens()

numeral.roman2int(text, strict=False, strict_regex='^M{0, 3}(CM|CD|D?C{0, 3})(XC|XL|L?X{0, 3})(IX|IV|V?I{0, 3})$', negative_sign='-')[source]

Convert a string representation of a Roman number to integer.

Parameters:
  • text (str) – The input number to parse.
  • strict (bool) –

    Only accept strictly formally valid Roman numbers. The following is checked:

    • repetition of identical symbols more than 3 times not allowed, except for apostrophus notation.
    • the symbols are sorted according decreasing value left-to-right, except for the subtraction notation, which allow a single symbol of next lower value to be placed on the left of a larger value symbol (this is to avoid the necessity for repeating the same symbol 4 times).
  • strict_regex (str) – The regular expression defining formal correctness. This must be a valid expression accepted by Python’s re.match(). If strict is False, this parameter is ignored.
  • negative_sign (str) – The symbol to use for negative numbers. The negative sign must be the first character of the representation.
Returns:

The integer represented.

Return type:

num (int)

Notes

  • Large numbers using the apostrophus notation cannot be parsed yet, but if no apostrophus notation is used (and strict parsing is not set) the parsing works.

Examples

>>> [roman2int(s) for s in ['MDCLXVI', 'iv', 'Ⅵ', 'IC', 'IIM', 'VL']]
[1666, 4, 6, 99, 998, 45]
>>> invalid = 0
>>> for s in ['MDCLXVI', 'IC', 'IIM', 'VL', 'MDO', 'CCDCCDOCCDODOMDO']:
...     try:
...         roman2int(s, strict=True)
...     except ValueError:
...         invalid += 1
...     except NotImplementedError:
...         pass
1666
>>> print('Invalid: {}'.format(invalid))
Invalid: 3
>>> roman2int('MMMMMM')
6000
>>> roman2int('MMMMMM', strict=True)
Traceback (most recent call last):
    ...
ValueError: Formally invalid input `MMMMMM`
>>> [roman2int(s) for s in ['CCDO', 'DO']]
Traceback (most recent call last):
    ...
NotImplementedError: Cannot parse large numbers yet!
>>> all(i == roman2int(int2roman(i)) for i in range(-3999, 4000, 7))
True
>>> all(i == roman2int(int2roman(i)) for i in range(1666, 10000, 973))
Traceback (most recent call last):
    ...
NotImplementedError: Cannot parse large numbers yet!
numeral.tokens2int(text, tokens, negative_sign='-')[source]

Convert a number to the least amount tokens (within a tokens set).

Items in the tokens set must not repeat/overlap.

This is the inverse of tokens2int() given the same tokens set.

Parameters:
  • text (str) – The input string to parse.
  • tokens (Iterable[str]) – The tokens to use for the representation. Items within the tokens set must not repeat or overlap.
  • negative_sign (str) – The symbol to use for negative numbers. The negative sign must be the first character of the representation.
Returns:

The integer represented.

Return type:

num (int)

Examples

>>> [tokens2int(s, ('po', 'ta')) for s in ['po', 'ta', 'popo', 'pota']]
[0, 1, 2, 3]
>>> tokens2int('potapopopotata', ('po', 'ta'))
161
>>> d = ('mo', 'no', 'ke')
>>> all(n == tokens2int(int2tokens(n, d), d) for n in range(-99, 999))
True

See also

letter2int(), int2letter(), int2tokens()