views:

89

answers:

3

Hey StackOverflow, I've got a question related to a beginner Python snippet I've written to introduce myself to the language. It's an admittedly trivial early effort, but I'm still wondering how I could have written it more elegantly.

The program outputs NATO phoenetic readable versions of an argument, such "H2O" -> "Hotel 2 Oscar", or (lacking an argument) just outputs the whole alphabet. I mainly use it for calling in MAC addresses and IQNs, but it's useful for other phone support too.

Here's the body of the relevant portion of the program:

#!/usr/bin/env python

import sys

nato = {
"a": 'Alfa',
"b": 'Bravo',
"c": 'Charlie',
"d": 'Delta',
"e": 'Echo',
"f": 'Foxtrot',
"g": 'Golf',
"h": 'Hotel',
"i": 'India',
"j": 'Juliet',
"k": 'Kilo',
"l": 'Lima',
"m": 'Mike',
"n": 'November',
"o": 'Oscar',
"p": 'Papa',
"q": 'Quebec',
"r": 'Romeo',
"s": 'Sierra',
"t": 'Tango',
"u": 'Uniform',
"v": 'Victor',
"w": 'Whiskey',
"x": 'Xray',
"y": 'Yankee',
"z": 'Zulu',
}

if len(sys.argv) < 2:
    for n in nato.keys():
            print nato[n]
else:
    # if sys.argv[1] == "-i" # TODO
    for char in sys.argv[1].lower():
            if char in nato:
                    print nato[char],
            else: print char,

As I mentioned, I just want to see suggestions for a more elegant way to code this. My first guess was to use a list comprehension along the lines of [nato[x] for x in sys.argv[1].lower() if x in nato], but that doesn't allow me to output any non-alphabetic characters. My next guess was to use map, but I couldn't format any lambdas that didn't suffer from the same corner case.

Any suggestions? Maybe something with first-class functions? Messing with Array's guts?
This seems like it could almost be a Code Golf question, but I feel like I'm just overthinking :)

+5  A: 

The dict get with default perhaps?

for char in sys.argv[1].lower():
  print nato.get(char, char) # try to get nato[char] otherwise return char
extraneon
+3  A: 

Using the above suggestion and a generator expression to do it all in one line

print ' '.join(nato.get(c,c) for c in sys.argv[1].lower())
job
+1 for spacing everything out
thetaiko
Upvoted, but I had to give credit to Extraneon. Thanks! :)
scott_karana
+2  A: 

Here's a compact way of building your list:

import sys
import string

NATO = '''Alpha Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliet
Kilo Lima Mike November Oscar Papa Quebec Romeo Sierra Tango Uniform
Victor Whiskey X-Ray Yankee Zulu'''.split()

nato = dict(zip(string.lowercase,NATO))

if len(sys.argv) < 2:
    for n in nato:
        print n,nato[n]
else:
    for char in sys.argv[1].lower():
        print nato.get(char,char)
Mark Tolonen
The way you initialize the nato dict, there is an implicit requirement that the words in the NATO string are in alphabetical order (I know they already are). I would prefer something like `nato = dict( (word[0].lower(), word) for word in NATO). Your 'sierra' is also lower-case.
ΤΖΩΤΖΙΟΥ