I have made a morse_code decoder in python as an assignment as shown below. It handles all characters available in morse_code. Although my approach works, it feels like a very amateurish way of doing things in python. The format in which morse code is sent:
In my code below I create an empty list, which get filled with a list in which each item represents a single morse code character, that is then replaced with the actual character. Finally, the lists within the list are joined, and the resulting list is joined as well so it can be returned as a string value. The reason I work with lists is because strings are immutable in python. I can't create an empty string, go into a for loop, and append to the string. I can not create a new string within the for loop either, since the variable will be lost upon leaving the for loop scope.
I have tried to do it with the replace method first, but I ran into trouble because replace doesn't have the flexibility needed to decode morse code.
decode_morse(morse_code):
morse_code_q = " "+morse_code+" "
morse_code_r = morse_code_q.replace(" .- ", ' A ').replace(" -... ", ' B ').replace(' -.-. ', ' C ').replace(' -.. ', 'D ').replace(' . ', ' E ').replace(' ..-. ', ' F ').replace(' --. ', ' G ').replace(' .... ', ' H ').replace(' .. ', ' I ').replace(' .--- ', ' J ').replace(' .-. ', ' K ').replace(' .-.. ', ' L ').replace(' -- ', ' M ').replace(' -. ', ' N ').replace(' --- ', ' O ').replace(' .--. ', ' P ').replace(' --.- ', ' Q ').replace(' .-. ', ' R ').replace(' ... ', ' S ').replace(' - ', ' T ').replace(' ..- ', ' U ').replace(' ...- ', ' V ').replace(' .--', ' W ').replace(' -..- ', ' X ').replace(' -.-- ', ' Y ').replace(' --.. ', ' Z ').replace(' ----- ', '0').replace(' .---- ', '1').replace(' ..--- ', '2').replace(' ...-- ', '3').replace(' ....- ', '4').replace(' ..... ', '5').replace(' -.... ', '6').replace(' --... ', '7').replace(' ---.. ', '8').replace(' ----. ', '9').replace(' .-.-.- ', '.').replace(' --..-- ', ',').replace(' ..--.. ', '?')
return morse_code_r.strip()
print(decode_morse('.... . -.-- .--- ..- -.. .'))
This returns H E Y J U D E, rather than HEY JUDE. Leaving out the spaces won't do much good. After replacing a character, the next replace function won't be able to find a character, because it needs the spaces to determine the start and the end of a character (else .... for H would resolve to EEEE, since . = E)
So here is my very ugly but working approach:
def decode_morse(morse_code):
result=[]
words = morse_code.split(" ")
for j in range(0,len(words)):
reverser = words[j].split(" ")
for i in range(0,len(reverser)):
if reverser[i]==".-":
reverser[i]='A'
elif reverser[i]=="-...":
reverser[i]='B'
elif reverser[i]=="-.-.":
reverser[i]='C'
elif reverser[i]=="-..":
reverser[i]='D'
elif reverser[i]==".":
reverser[i]='E'
elif reverser[i]=="..-.":
reverser[i]='F'
elif reverser[i]=="--.":
reverser[i]='G'
elif reverser[i]=="....":
reverser[i]='H'
elif reverser[i]=="..":
reverser[i]='I'
elif reverser[i]==".---":
reverser[i]='J'
elif reverser[i]==".-.":
reverser[i]='K'
elif reverser[i]==".-..":
reverser[i]='L'
elif reverser[i]=="--":
reverser[i]='M'
elif reverser[i]=="-.":
reverser[i]='N'
elif reverser[i]=="---":
reverser[i]='O'
elif reverser[i]==".--.":
reverser[i]='P'
elif reverser[i]=="--.-":
reverser[i]='Q'
elif reverser[i]==".-.":
reverser[i]='R'
elif reverser[i]=="...":
reverser[i]='S'
elif reverser[i]=="-":
reverser[i]='T'
elif reverser[i]=="..-":
reverser[i]='U'
elif reverser[i]=="...-":
reverser[i]='V'
elif reverser[i]==".--":
reverser[i]='W'
elif reverser[i]=="-..-":
reverser[i]='X'
elif reverser[i]=="-.--":
reverser[i]='Y'
elif reverser[i]=="--..":
reverser[i]='Z'
elif reverser[i]=="-----":
reverser[i]='0'
elif reverser[i]==".----":
reverser[i]='1'
elif reverser[i]=="..---":
reverser[i]='2'
elif reverser[i]=="...--":
reverser[i]='3'
elif reverser[i]=="....-":
reverser[i]='4'
elif reverser[i]==".....":
reverser[i]='5'
elif reverser[i]=="-....":
reverser[i]='6'
elif reverser[i]=="--...":
reverser[i]='7'
elif reverser[i]=="---..":
reverser[i]='8'
elif reverser[i]=="----.":
reverser[i]='9'
elif reverser[i]==".-.-.-":
reverser[i]='.'
elif reverser[i]=="--..--":
reverser[i]=','
elif reverser[i]=="..--..":
reverser[i]='?'
result.append(reverser)
final =[]
for h in range(0,len(result)):
final.append("".join(result[h])+" ")
return "".join(final)
print(decode_morse('.... . -.-- .--- ..- -.. .')) #returns HEY JUDE
Anyone with a solution that makes this more pythonic? For this exercise, we are not allowed to use regexp library. Thanks in advance.
Always turn code into data whenever possible.
# Full table at bottom of answer.
encode_table = {
"A": ".-",
"B": "-...",
"C": "-.-.",
...
" ": "SPACE", # Special "sentinel" value to simplify decoder.
}
# Reverse of encode_table.
decode_table = {v: k for k, v in encode_table.items()}
Now, simply:
def encode(s):
enc = " ".join(encode_table[x] for x in s)
return enc.replace(" SPACE ", " ")
def decode(encoded):
symbols = encoded.replace(" ", " SPACE ").split(" ")
return "".join(decode_table[x] for x in symbols)
Test:
>>> encode("HEY JUDE")
'.... . -.-- .--- ..- -.. .'
>>> decode(".... . -.-- .--- ..- -.. .")
'HEY JUDE'
Full table:
encode_table = {
"A": ".-",
"B": "-...",
"C": "-.-.",
"D": "-..",
"E": ".",
"F": "..-.",
"G": "--.",
"H": "....",
"I": "..",
"J": ".---",
"K": "-.-",
"L": ".-..",
"M": "--",
"N": "-.",
"O": "---",
"P": ".--.",
"Q": "--.-",
"R": ".-.",
"S": "...",
"T": "-",
"U": "..-",
"V": "...-",
"W": ".--",
"X": "-..-",
"Y": "-.--",
"Z": "--..",
"0": "-----",
"1": ".----",
"2": "..---",
"3": "...--",
"4": "....-",
"5": ".....",
"6": "-....",
"7": "--...",
"8": "---..",
"9": "----.",
".": ".-.-.-",
",": "--..--",
"?": "..--..",
" ": "SPACE",
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With