Challenge
Write a program which reads a file containing Morse Code and outputs the conversion.
Specifications
- The first argument is a path to a file.
- The file contains multiple lines.
- Each line is a string of Morse code.
- Each letter is separated by a space.
- Each word is separated by two spaces.
Constraints
- The input file is correctly formatted.
- The Morse Code strings are alphanumeric.
Sample Input
.- ...- ..--- .-- .... .. . -.-. -..- ....- ..... -... .... ...--
Sample Output
AV2WHIECX 45
BH3
My Solution:
import sys
import re
morse_alphabet = {
'' : ' ',
'.-' : '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'
}
def decode(morse):
decoded = ''
line = re.split('\s', morse)
for letter in line:
decoded += morse_alphabet.get(letter)
return decoded
def main(filename):
with open(filename) as input_file:
for line in input_file:
print(decode(line))
if __name__ == "__main__":
try:
main(sys.argv[1])
except:
sys.exit("No argument provided / file not found.")
Applying the insight gained from my previous question. It seems fairly succinct but I wonder is it pythonic?
2 Answers 2
My remarks are similar to last time. morse_alphabet
should be MORSE_ALPHABET
. Repeated string concatenation (decoded += ...
) is bad for performance. The main task could be accomplished using a one-liner substitution.
MORSE_ALPHABET = {
' ' : ' ', # Note: Changed the key from '' to ' '
'.-' : 'A',
'-...' : 'B',
'-.-.' : 'C',
...
}
def decode(morse):
return re.sub(' ?( |[.-]*)', lambda m: MORSE_ALPHABET.get(m.group(1)), morse)
The main code would be simpler if you used fileinput
. Despite the current Pokémon craze, you should not Catch 'Em All, but only catch the exceptions that you intend to handle.
def main():
try:
for line in fileinput.input():
print(decode(line), end='')
except IOError as e:
sys.exit(e)
if __name__ == "__main__":
main()
-
\$\begingroup\$ If there are no arguments argv[1] will raise an IndexError \$\endgroup\$Fabián Heredia Montiel– Fabián Heredia Montiel2016年07月25日 01:37:14 +00:00Commented Jul 25, 2016 at 1:37
-
\$\begingroup\$ @FabiánH.jr. I never use
argv
. If there are not arguments, it will read fromsys.stdin
. \$\endgroup\$200_success– 200_success2016年07月25日 01:38:27 +00:00Commented Jul 25, 2016 at 1:38 -
\$\begingroup\$ Oh nice, didn't know about that; will def read more about fileinput. \$\endgroup\$Fabián Heredia Montiel– Fabián Heredia Montiel2016年07月25日 01:40:51 +00:00Commented Jul 25, 2016 at 1:40
-
\$\begingroup\$ @Legato Any
'\n'
that may be in the input is simply passed through unchanged bydecode()
. Since the newline was never stripped in the first place, it doesn't need to be added, either. \$\endgroup\$200_success– 200_success2016年07月25日 01:59:17 +00:00Commented Jul 25, 2016 at 1:59 -
\$\begingroup\$ Realized the error, thought about it in terms of my original at first. Thank you. \$\endgroup\$Legato– Legato2016年07月25日 02:03:30 +00:00Commented Jul 25, 2016 at 2:03
No need to do a regex; Python already has str.split()
and you can condense it to a ''.join(generator)
def decode(morse):
return ''.join(morse_alphabet.get(letter)
for letter in morse.split(' '))
-
3\$\begingroup\$ Instead of a list comprehension, omit the
[]
and make it a generator expression. \$\endgroup\$200_success– 200_success2016年07月25日 01:09:46 +00:00Commented Jul 25, 2016 at 1:09 -
\$\begingroup\$ Is this really valid...? I get an error trying to run it. \$\endgroup\$Legato– Legato2016年07月25日 01:54:13 +00:00Commented Jul 25, 2016 at 1:54
-
\$\begingroup\$ Yes, it is valid python. Could you do me a favour and tell me the output of
python --version
? \$\endgroup\$Fabián Heredia Montiel– Fabián Heredia Montiel2016年07月25日 01:59:10 +00:00Commented Jul 25, 2016 at 1:59 -
\$\begingroup\$ I'm running version 3.4.3 \$\endgroup\$Legato– Legato2016年07月25日 02:09:29 +00:00Commented Jul 25, 2016 at 2:09
-
\$\begingroup\$ Add [] around the generator; I tested the code on Python 3.5.2 and it is working great. \$\endgroup\$Fabián Heredia Montiel– Fabián Heredia Montiel2016年07月25日 02:11:17 +00:00Commented Jul 25, 2016 at 2:11
Explore related questions
See similar questions with these tags.