The code works not only as a normal run length encoder and decoder, but it also works for values like 3ABC
(Prints ABCABCABC
), but the same doesn't happen for encoding
class DecodeError(BaseException):
__module__ = Exception.__module__
class EncodeError(BaseException):
__module__ = Exception.__module__
def run_length_encode(string: str) -> str:
if any(not i.isalpha() for i in string):
raise EncodeError('String must contain only alphabets')
final_string = ''
number = 1
character = string[0]
for i in string[1:]:
if i != character:
final_string += str(number) + character
number = 0
number += 1
character = i
final_string += str(number) + character
return final_string
def run_length_decode(encoded_string: str) -> str:
if not encoded_string:
return ''
if encoded_string[-1].isnumeric():
raise DecodeError('Ending character must not be an integer')
if not encoded_string[0].isnumeric():
raise DecodeError('Starting character must be an integer')
number = character = ''
final_string = ''
for c in encoded_string:
if c.isnumeric():
if character:
final_string += int(number) * character
number = character = ''
number += c
if number == '0':
raise DecodeError('Number cannot start with 0')
else:
if not c.isalpha():
raise DecodeError('String must contain only alphabets')
character += c
final_string += int(number) * character
return final_string
if __name__ == '__main__':
t = int(input('Enter if you want to encode(1) or decode(2): '))
string = input('Enter string: ')
if t == 1: print(run_length_encode(string))
elif t == 2: print(run_length_decode(string))
else: raise ValueError('Value must be 1 or 2')
Is it possible make this code shorter, neater, and faster?
A few testcases:
For encode:
Enter if you want to encode(1) or decode(2): 1
Enter string: AABBCCDD
2A2B2C2D
Enter if you want to encode(1) or decode(2): 1
Enter string: AB1
Traceback (most recent call last):
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 67, in <module>
if t == 1: print(run_length_encode(string))
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 9, in run_length_encode
raise EncodeError('String must contain only alphabets')
EncodeError: String must contain only alphabets
Enter if you want to encode(1) or decode(2): 1
Enter string: AAABBcCCddee
3A2B1c2C2d2e
Enter if you want to encode(1) or decode(2): 1
Enter string: AAABBCC.
Traceback (most recent call last):
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 67, in <module>
if t == 1: print(run_length_encode(string))
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 9, in run_length_encode
raise EncodeError('String must contain only alphabets')
EncodeError: String must contain only alphabets
For decode:
Enter if you want to encode(1) or decode(2): 2
Enter string: 2A3C4D
AACCCDDDD
Enter if you want to encode(1) or decode(2): 2
Enter string: 1ABC
ABC
Enter if you want to encode(1) or decode(2): 2
Enter string: 2A3B1ABC
AABBBABC
Enter if you want to encode(1) or decode(2): 2
Enter string: 0X
Traceback (most recent call last):
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 68, in <module>
elif t == 2: print(run_length_decode(string))
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 50, in run_length_decode
raise DecodeError('Number cannot start with 0')
DecodeError: Number cannot start with 0
Enter if you want to encode(1) or decode(2): 2
Enter string: 0123A
Traceback (most recent call last):
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 68, in <module>
elif t == 2: print(run_length_decode(string))
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 50, in run_length_decode
raise DecodeError('Number cannot start with 0')
DecodeError: Number cannot start with 0
Enter if you want to encode(1) or decode(2): 2
Enter string: 2A3#
Traceback (most recent call last):
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 68, in <module>
elif t == 2: print(run_length_decode(string))
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 54, in run_length_decode
raise DecodeError('String must contain only alphabets')
DecodeError: String must contain only alphabets
Enter if you want to encode(1) or decode(2): 2
Enter string: A2A
Traceback (most recent call last):
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 68, in <module>
elif t == 2: print(run_length_decode(string))
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 36, in run_length_decode
raise DecodeError('Starting character must be an integer')
DecodeError: Starting character must be an integer
Enter if you want to encode(1) or decode(2): 2
Enter string: 1A2
Traceback (most recent call last):
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 68, in <module>
elif t == 2: print(run_length_decode(string))
File "C:/Users/Administrator/.PyCharmCE2018.3/config/scratches/scratch_62.py", line 33, in run_length_decode
raise DecodeError('Ending character must not be an integer')
DecodeError: Ending character must not be an integer
If you want more testcases, say so in the comments and I'll add them!
run_length_decode("10abc2err3.0bbc")
givesabcabcabcabcabcabcabcabcabcabcerrerr...
. Is that expected? 1) sequence of chars 2) float numbers 3)0
digit before a letter ? \$\endgroup\$abcabcabc...
was expected, but the others were not. Thanks for pointing that out!. I'll edit my code soon \$\endgroup\$