forked from cool-RR/python_toolbox
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnumber_encoding.py
More file actions
54 lines (43 loc) · 1.78 KB
/
number_encoding.py
File metadata and controls
54 lines (43 loc) · 1.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# Copyright 2009-2017 Ram Rachum.
# This program is distributed under the MIT license.
from python_toolbox import sequence_tools
class NumberEncoder:
'''
A very simple encoder between lines and strings.
Example:
>>> my_encoder = number_encoding.NumberEncoder('isogram')
>>> my_encoder.encode(10000)
'rssir'
>>> my_encoder.encode(10000000)
'saimmmgrg'
>>> my_encoder.decode('saimmmgrg')
10000000
'''
def __init__(self, characters):
self.characters = \
sequence_tools.ensure_iterable_is_immutable_sequence(characters)
recurrences = sequence_tools.get_recurrences(self.characters)
if recurrences:
raise Exception('`characters` must not have recurring characters.')
def encode(self, number, minimum_length=1):
'''
Encode the number into a string.
If `minimum_length > 1`, the string will be padded (with the "zero"
character) if the number isn't big enough.
'''
current_number = number
result = ''
while current_number:
current_number, modulo = divmod(current_number,
len(self.characters))
result = self.characters[modulo] + result
if len(result) <= minimum_length:
result = (self.characters[0] * (minimum_length - len(result))) + result
return result
def decode(self, string):
'''Decode `string` into a number'''
assert isinstance(string, (str, bytes))
return sum((len(self.characters)**i) * self.characters.index(x)
for (i, x) in enumerate(string[::-1]))
def __repr__(self):
return '<%s: %s>' % (type(self).__name__, repr(self.characters))