3
\$\begingroup\$

Challenge

Write a program which reads a file containing Morse Code and outputs the conversion.

Specifications

  1. The first argument is a path to a file.
  2. The file contains multiple lines.
  3. Each line is a string of Morse code.
    • Each letter is separated by a space.
    • Each word is separated by two spaces.

Constraints

  1. The input file is correctly formatted.
  2. The Morse Code strings are alphanumeric.

Sample Input

.- ...- ..--- .-- .... .. . -.-. -..- ....- ..... 
-... .... ...--

Sample Output

AV2WHIECX 45
BH3

Source

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?

asked Jul 24, 2016 at 22:14
\$\endgroup\$
0

2 Answers 2

10
\$\begingroup\$

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()
answered Jul 25, 2016 at 1:33
\$\endgroup\$
6
  • \$\begingroup\$ If there are no arguments argv[1] will raise an IndexError \$\endgroup\$ Commented Jul 25, 2016 at 1:37
  • \$\begingroup\$ @FabiánH.jr. I never use argv. If there are not arguments, it will read from sys.stdin. \$\endgroup\$ Commented Jul 25, 2016 at 1:38
  • \$\begingroup\$ Oh nice, didn't know about that; will def read more about fileinput. \$\endgroup\$ Commented Jul 25, 2016 at 1:40
  • \$\begingroup\$ @Legato Any '\n' that may be in the input is simply passed through unchanged by decode(). Since the newline was never stripped in the first place, it doesn't need to be added, either. \$\endgroup\$ Commented Jul 25, 2016 at 1:59
  • \$\begingroup\$ Realized the error, thought about it in terms of my original at first. Thank you. \$\endgroup\$ Commented Jul 25, 2016 at 2:03
5
\$\begingroup\$

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(' '))
answered Jul 25, 2016 at 0:40
\$\endgroup\$
6
  • 3
    \$\begingroup\$ Instead of a list comprehension, omit the [] and make it a generator expression. \$\endgroup\$ Commented Jul 25, 2016 at 1:09
  • \$\begingroup\$ Is this really valid...? I get an error trying to run it. \$\endgroup\$ Commented 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\$ Commented Jul 25, 2016 at 1:59
  • \$\begingroup\$ I'm running version 3.4.3 \$\endgroup\$ Commented 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\$ Commented Jul 25, 2016 at 2:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.