Inspired by this question.
Here's the code:
class FishyError(Exception):
__module__ = Exception.__module__
def string_to_fishy(string: str) -> str:
"""
Converts a string to fishy code
Examples:
Hello World!
><72> ><101> ><108> ><108> ><111> ><32> ><87> ><111> ><114> ><108> ><100> ><33>
007 James bond
><48> ><48> ><55> ><32> ><74> ><97> ><109> ><101> ><115> ><32> ><98> ><111> ><110> ><100>
"""
l = []
for char in string:
l.append(f'><{ord(char)}>')
return ' '.join(l)
def fishy_to_string(fishy: str) -> str:
"""
Converts a fishy code to string
Examples:
><72> ><101> ><108> ><108> ><111> ><32> ><87> ><111> ><114> ><108> ><100> ><33>
Hello World!
><48> ><48> ><55> ><32> ><74> ><97> ><109> ><101> ><115> ><32> ><98> ><111> ><110> ><100>
007 James bond
"""
if not fishy:
return ''
fishy_chars = fishy.split(' ')
string = ''
for char in fishy_chars:
if not char:
raise FishyError('Invalid syntax: Extra whitespace')
if not (char.startswith('><') and char.endswith('>')):
raise FishyError('Invalid syntax: ' + char)
try:
value = int(char[2:-1])
string += chr(value)
except ValueError:
raise FishyError('Invalid syntax: ' + char)
return string
while True:
print(fishy_to_string(input()))
This works well, but doesn't look that great. Any ideas?
1 Answer 1
I'm not entirely sure why you are not satisfied with your code as it looks quite good. Maybe too many blank lines that seem to stretch the code length. There are also a few things on the Python side that could be changed to reduce the amount of source lines needed for the task:
string_to_fishy
string_to_fishy
can be rewritten using a list comprehension:
def string_to_fishy(string: str) -> str:
"""..."""
return ' '.join(f'><{ord(char)}>' for char in string)
fishy_to_string
The inverse function could use a similar technique in order to avoid repeated creations of new strings in string += chr(value)
:
def fishy_to_string(fishy: str) -> str:
"""
Converts a fishy code to string
Examples:
><72> ><101> ><108> ><108> ><111> ><32> ><87> ><111> ><114> ><108> ><100> ><33>
Hello World!
><48> ><48> ><55> ><32> ><74> ><97> ><109> ><101> ><115> ><32> ><98> ><111> ><110> ><100>
007 James bond
"""
if not fishy:
return ''
def parse_fish(token):
if not token:
raise FishyError('Invalid syntax: Extra whitespace')
if not (token.startswith('><') and token.endswith('>')):
raise FishyError('Invalid syntax: ' + token)
try:
value = int(token[2:-1])
string += chr(value)
except ValueError:
raise FishyError('Input cannot be parsed as character: ' + token)
return ''.join(parse_fish(token) for token in fishy.split(' '))
I also allowed myself to change the variable name char
to token
, because I find it more appropriate in that context, and also slightly reworded the last error message to make it more expressive.