Reputation: 96
I have the following code, which translates the input string into morse code. My code runs through every letter in the string and then through every character in the alphabet. This is very inefficient, because what if I was reading from a very large file, instead of a small alphabet string. Is there any way that I could improve my code, Maybe using the module re, to match my string with the morse code characters?
morse_alphabet = ".- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --.."
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
morse_letters = morse_alphabet.split(" ")
result = []
count_character = 0
def t(code):
for character in code:
count_letter = 0
for letter in ALPHABET:
lower_character = code[count_character].lower()
lower_letter = letter.lower()
if lower_character == lower_letter:
result.append(morse_letters[count_letter])
count_letter += 1
count_character += 1
return result
Upvotes: 1
Views: 247
Reputation: 64068
You could use a dictionary, like so:
morse_alphabet = ".- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --.."
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
morse_letters = morse_alphabet.split(' ')
char_to_morse = dict(zip(ALPHABET, morse_letters))
def t(code):
result = []
for char in code:
result.append(char_to_morse[char.lower()])
return result
print t('abc')
Basically, you would use a dictionary whenever you have a one-to-one mapping between two things (in this case, alphabetic characters to morse code).
Upvotes: 1
Reputation: 5874
Here's an approach using ascii codes:
morse_alphabet = ".- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --..".split(" ")
CHAR_OFFSET = 97 # ord(a) = 97, i.e. a is 97 in ascii
def string_to_morse_code(string):
morse_code = []
for char in string.lower():
try:
morse_code.append( morse_alphabet[ ord(char) - CHAR_OFFSET] )
except IndexError:
continue # ignore any chars we don't understand
return ' '.join(morse_code)
print string_to_morse_code("Help!!!")
This returns:
.... . .-.. .--.
Upvotes: 0
Reputation: 1240
What I would do is create a dictionary using the letter as the key and the morse code equivalent as the value. Then you can simply loop through the String you are converting and assign the correct value immediately.
Upvotes: 1
Reputation: 3737
Use a dictionary. Assign a dict-key for each letter, then let this have as its value the respective morse-code.
Example - assign morse code for each letter:
morse = {}
morse["a"] = ".-"
morse["b"] = "-..."
#...
Recall the morse code for a letter:
morse_for_a = morse["a"]
The time of a dict-lookup is not affected by the length/size of the dictionary - it is O(1). See this answer.
Upvotes: 2
Reputation: 1328
Do as little as possible "by hand". Looking up a code in a dict is much faster than using a for loop "manually". Also, you're calling lower() for the alfabet letters, even though you know that they're already lowercase. Calling it once on the entire string, just te be sure, is good. Calling it once for every letter is slow without a good reason.
Upvotes: 0
Reputation: 1121972
You can use string.ascii_lowercase
together with zip()
to make a dictionary instead:
import string
morse_alphabet = ".- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --.."
morse_letters = dict(zip(string.ascii_lowercase, morse_alphabet.split()))
def t(code):
return filter(None, (morse_letters.get(c.lower()) for c in code))
The t
function is reduced to a filter()
and a generator expression looping over each character in the input code.
The morse_letters
dictionary now makes for a very fast lookup of codes, the filter()
removes the None
results for anything that isn't a letter.
Result:
>>> t('S.O.S.')
['...', '---', '...']
>>> t('Stack Overflow')
['...', '-', '.-', '-.-.', '-.-', '---', '...-', '.', '.-.', '..-.', '.-..', '---', '.--']
Upvotes: 6
Reputation: 142156
You could use a dict
with defaults - so if a character exists, return that - otherwise it returns the original character...
morse_alphabet = ".- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --.."
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
lookup = dict(zip(ALPHABET, morse_alphabet.split()))
>>> from pprint import pprint
>>> pprint(lookup)
{'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': '--..'}
s = 'sos'
print ''.join(lookup.get(ch, ch) for ch in s)
'...---...'
Upvotes: 0