10
10
original character. The BWT is thus a "free" method of improving the efficiency
11
11
of text compression algorithms, costing only some extra computation.
12
12
"""
13
+ from typing import List , Dict
13
14
14
15
15
- def all_rotations (string ) :
16
+ def all_rotations (s : str ) -> List [ str ] :
16
17
"""
17
- :param str string: The string that will be rotated len(string) times.
18
- :return: A list with len(string) rotations of the parameter string.
19
- :rtype: list[str]
20
- :raises TypeError: If the string parameter type is not str.
18
+ :param s: The string that will be rotated len(s) times.
19
+ :return: A list with the rotations.
20
+ :raises TypeError: If s is not an instance of str.
21
21
Examples:
22
22
23
- >>> all_rotations("^BANANA|")
24
- ['^BANANA|', 'BANANA|^', 'ANANA|^B', 'NANA|^BA', 'ANA|^BAN', 'NA|^BANA',\
25
- 'A|^BANAN', '|^BANANA']
26
- >>> all_rotations("a_asa_da_casa")
27
- ['a_asa_da_casa', '_asa_da_casaa', 'asa_da_casaa_', 'sa_da_casaa_a',\
28
- 'a_da_casaa_as', '_da_casaa_asa', 'da_casaa_asa_', 'a_casaa_asa_d',\
29
- '_casaa_asa_da', 'casaa_asa_da_', 'asaa_asa_da_c', 'saa_asa_da_ca',\
30
- 'aa_asa_da_cas']
31
- >>> all_rotations("panamabanana")
32
- ['panamabanana', 'anamabananap', 'namabananapa', 'amabananapan',\
33
- 'mabananapana', 'abananapanam', 'bananapanama', 'ananapanamab',\
34
- 'nanapanamaba', 'anapanamaban', 'napanamabana', 'apanamabanan']
23
+ >>> all_rotations("^BANANA|") # doctest: +NORMALIZE_WHITESPACE
24
+ ['^BANANA|', 'BANANA|^', 'ANANA|^B', 'NANA|^BA', 'ANA|^BAN', 'NA|^BANA',
25
+ 'A|^BANAN', '|^BANANA']
26
+ >>> all_rotations("a_asa_da_casa") # doctest: +NORMALIZE_WHITESPACE
27
+ ['a_asa_da_casa', '_asa_da_casaa', 'asa_da_casaa_', 'sa_da_casaa_a',
28
+ 'a_da_casaa_as', '_da_casaa_asa', 'da_casaa_asa_', 'a_casaa_asa_d',
29
+ '_casaa_asa_da', 'casaa_asa_da_', 'asaa_asa_da_c', 'saa_asa_da_ca',
30
+ 'aa_asa_da_cas']
31
+ >>> all_rotations("panamabanana") # doctest: +NORMALIZE_WHITESPACE
32
+ ['panamabanana', 'anamabananap', 'namabananapa', 'amabananapan',
33
+ 'mabananapana', 'abananapanam', 'bananapanama', 'ananapanamab',
34
+ 'nanapanamaba', 'anapanamaban', 'napanamabana', 'apanamabanan']
35
35
>>> all_rotations(5)
36
36
Traceback (most recent call last):
37
37
...
38
- TypeError: The parameter string type must be str.
38
+ TypeError: The parameter s type must be str.
39
39
"""
40
- if not ( type ( string ) is str ):
41
- raise TypeError ("The parameter string type must be str." )
40
+ if not isinstance ( s , str ):
41
+ raise TypeError ("The parameter s type must be str." )
42
42
43
- return [string [i :] + string [:i ] for i in range (len (string ))]
43
+ return [s [i :] + s [:i ] for i in range (len (s ))]
44
44
45
45
46
- def bwt_transform (string ) :
46
+ def bwt_transform (s : str ) -> Dict :
47
47
"""
48
- :param str string: The string that will be used at bwt algorithm
49
- :return: A dictionary with the bwt result, the string composed of the last
50
- char of each row of the ordered rotations list and the index of the
51
- original string at ordered rotations list
52
- :rtype: dict
53
- :raises TypeError: If the string parameter type is not str
54
- :raises ValueError: If the string parameter is empty
48
+ :param s: The string that will be used at bwt algorithm
49
+ :return: the string composed of the last char of each row of the ordered
50
+ rotations and the index of the original string at ordered rotations list
51
+ :raises TypeError: If the s parameter type is not str
52
+ :raises ValueError: If the s parameter is empty
55
53
Examples:
56
54
57
55
>>> bwt_transform("^BANANA")
@@ -63,38 +61,38 @@ def bwt_transform(string):
63
61
>>> bwt_transform(4)
64
62
Traceback (most recent call last):
65
63
...
66
- TypeError: The parameter string type must be str.
64
+ TypeError: The parameter s type must be str.
67
65
>>> bwt_transform('')
68
66
Traceback (most recent call last):
69
67
...
70
- ValueError: The parameter string must not be empty.
68
+ ValueError: The parameter s must not be empty.
71
69
"""
72
- if not ( type ( string ) is str ):
73
- raise TypeError ("The parameter string type must be str." )
74
- if not string :
75
- raise ValueError ("The parameter string must not be empty." )
70
+ if not isinstance ( s , str ):
71
+ raise TypeError ("The parameter s type must be str." )
72
+ if not s :
73
+ raise ValueError ("The parameter s must not be empty." )
76
74
77
- rotations = all_rotations (string )
75
+ rotations = all_rotations (s )
78
76
rotations .sort () # sort the list of rotations in alphabetically order
79
77
# make a string composed of the last char of each rotation
80
78
return {
81
79
"bwt_string" : "" .join ([word [- 1 ] for word in rotations ]),
82
- "idx_original_string" : rotations .index (string ),
80
+ "idx_original_string" : rotations .index (s ),
83
81
}
84
82
85
83
86
- def reverse_bwt (bwt_string , idx_original_string ) :
84
+ def reverse_bwt (bwt_string : str , idx_original_string : int ) -> str :
87
85
"""
88
- :param str bwt_string: The string returned from bwt algorithm execution
89
- :param int idx_original_string: The index of the string that was used to
86
+ :param bwt_string: The string returned from bwt algorithm execution
87
+ :param idx_original_string: A 0-based index of the string that was used to
90
88
generate bwt_string at ordered rotations list
91
89
:return: The string used to generate bwt_string when bwt was executed
92
- :rtype str
93
90
:raises TypeError: If the bwt_string parameter type is not str
94
91
:raises ValueError: If the bwt_string parameter is empty
95
92
:raises TypeError: If the idx_original_string type is not int or if not
96
- possible to cast it to int
97
- :raises ValueError: If the idx_original_string value is lower than 0
93
+ possible to cast it to int
94
+ :raises ValueError: If the idx_original_string value is lower than 0 or
95
+ greater than len(bwt_string) - 1
98
96
99
97
>>> reverse_bwt("BNN^AAA", 6)
100
98
'^BANANA'
@@ -110,33 +108,49 @@ def reverse_bwt(bwt_string, idx_original_string):
110
108
Traceback (most recent call last):
111
109
...
112
110
ValueError: The parameter bwt_string must not be empty.
113
- >>> reverse_bwt("mnpbnnaaaaaa", "asd")
111
+ >>> reverse_bwt("mnpbnnaaaaaa", "asd") # doctest: +NORMALIZE_WHITESPACE
114
112
Traceback (most recent call last):
115
113
...
116
- TypeError: The parameter idx_original_string type must be int or passive of cast to int.
114
+ TypeError: The parameter idx_original_string type must be int or passive
115
+ of cast to int.
117
116
>>> reverse_bwt("mnpbnnaaaaaa", -1)
118
117
Traceback (most recent call last):
119
118
...
120
119
ValueError: The parameter idx_original_string must not be lower than 0.
120
+ >>> reverse_bwt("mnpbnnaaaaaa", 12) # doctest: +NORMALIZE_WHITESPACE
121
+ Traceback (most recent call last):
122
+ ...
123
+ ValueError: The parameter idx_original_string must be lower than
124
+ len(bwt_string).
121
125
>>> reverse_bwt("mnpbnnaaaaaa", 11.0)
122
126
'panamabanana'
123
127
>>> reverse_bwt("mnpbnnaaaaaa", 11.4)
124
128
'panamabanana'
125
129
"""
126
- if not ( type ( bwt_string ) is str ):
130
+ if not isinstance ( bwt_string , str ):
127
131
raise TypeError ("The parameter bwt_string type must be str." )
128
132
if not bwt_string :
129
133
raise ValueError ("The parameter bwt_string must not be empty." )
130
134
try :
131
135
idx_original_string = int (idx_original_string )
132
136
except ValueError :
133
137
raise TypeError (
134
- "The parameter idx_original_string type must be int or passive of cast to int."
138
+ (
139
+ "The parameter idx_original_string type must be int or passive"
140
+ " of cast to int."
141
+ )
135
142
)
136
143
if idx_original_string < 0 :
137
144
raise ValueError (
138
145
"The parameter idx_original_string must not be lower than 0."
139
146
)
147
+ if idx_original_string >= len (bwt_string ):
148
+ raise ValueError (
149
+ (
150
+ "The parameter idx_original_string must be lower than"
151
+ " len(bwt_string)."
152
+ )
153
+ )
140
154
141
155
ordered_rotations = ["" ] * len (bwt_string )
142
156
for x in range (len (bwt_string )):
@@ -147,19 +161,16 @@ def reverse_bwt(bwt_string, idx_original_string):
147
161
148
162
149
163
if __name__ == "__main__" :
150
- string = input ("Provide a string that I will generate its BWT transform: " )
151
- result = bwt_transform (string )
152
- print (
153
- "Burrows Wheeler tranform for string '{}' results in '{}'" .format (
154
- string , result ["bwt_string" ]
155
- )
156
- )
164
+ entry_msg = "Provide a string that I will generate its BWT transform: "
165
+ s = input (entry_msg ).strip ()
166
+ result = bwt_transform (s )
167
+ bwt_output_msg = "Burrows Wheeler tranform for string '{}' results in '{}'"
168
+ print (bwt_output_msg .format (s , result ["bwt_string" ]))
157
169
original_string = reverse_bwt (
158
170
result ["bwt_string" ], result ["idx_original_string" ]
159
171
)
160
- print (
161
- (
162
- "Reversing Burrows Wheeler tranform for entry '{}' we get original"
163
- " string '{}'"
164
- ).format (result ["bwt_string" ], original_string )
172
+ fmt = (
173
+ "Reversing Burrows Wheeler tranform for entry '{}' we get original"
174
+ " string '{}'"
165
175
)
176
+ print (fmt .format (result ["bwt_string" ], original_string ))
0 commit comments