views:

276

answers:

7

I need to convert a string inputed by a user into morse code. The way our professor wants us to do this is to read from a morseCode.txt file, seperate the letters from the morseCode into two lists, then convert each letter to morse code (inserting a new line when there is a space).

I have the beginning. What it does is reads the morseCode.txt file and seperates the letters into a list [A, B, ... Z] and the codes into a list ['– – . . – –\n', '. – . – . –\n'...].

We haven't learned "sets" yet, so I can't use that. How would I then take the string that they inputed, go through letter by letter, and convert it to morse code? I'm a bit caught up. Here's what I have right now (not much at all...)

EDIT: completed the program!

# open morseCode.txt file to read
morseCodeFile = open('morseCode.txt', 'r') # format is <letter>:<morse code translation><\n>   
# create an empty list for letters
letterList = []    
# create an empty list for morse codes
codeList = []
# read the first line of the morseCode.txt
line = morseCodeFile.readline()    
# while the line is not empty
while line != '':        
    # strip the \n from the end of each line
    line = line.rstrip()        
    # append the first character of the line to the letterList        
    letterList.append(line[0])           
    # append the 3rd to last character of the line to the codeList
    codeList.append(line[2:])        
    # read the next line
    line = morseCodeFile.readline()        
# close the file    
morseCodeFile.close()


try:
    # get user input
    print("Enter a string to convert to morse code or press <enter> to quit")    
    userInput = input("")  
    # while the user inputs something, continue   
    while userInput:
        # strip the spaces from their input
        userInput = userInput.replace(' ', '')
        # convert to uppercase
        userInput = userInput.upper()

        # set string accumulator
        accumulateLetters = ''
        # go through each letter of the word
        for x in userInput:            
            # get the index of the letterList using x
            index = letterList.index(x)
            # get the morse code value from the codeList using the index found above
            value = codeList[index]
            # accumulate the letter found above
            accumulateLetters += value
        # print the letters    
        print(accumulateLetters)
        # input to try again or <enter> to quit
        print("Try again or press <enter> to quit")
        userInput = input("")

except ValueError:
    print("Error in input. Only alphanumeric characters, a comma, and period allowed")
    main()   
+1  A: 
# Retain a map of the Morse code
conversion = {}

# Read map from file, add it to the datastructure
morseCodeFile = file('morseCode.txt')
for line in moreCodeFile:
    conversion[line[0]] = line[2:]
morseCodeFile.close()

# Ask for input from the user
s = raw_input("Please enter string to translate")
# Go over each character, and print it the translation.
# Defensive programming: do something sane if the user 
# inputs non-Morse compatible strings.    
for c in s:
    print conversion.get(c, "No translation for "+c)
moshez
can't use this, didn't learn this much. i've edited my original post to include a bit more code. just need help finishing it off
dan
What you have "so far" does not really work, so it's hard to "finish it". What parts didn't you learn?
moshez
haven't learned maps. if you take a look at my edits, why would i not be able to use a loop to go through the string that is stripped of spaces, take the current letter and search the letterList list for its index, then use that corresponding location to find the morse code in the morseCode list, and return that
dan
Ouch. That's like writing your own maps, slowly. You can do that, but it's horrible.[That's unrelated to the fact that what you have "so far" is incorrect, really. For example, "morseCodeFile.rstrip()" will fail. But I'm not sure there's much pedagogical value in "learn to use Python without maps" -- maps the very soul of Python...]
moshez
well i fixed that rstrip() line. it's line = line.rstrip() now so that's not the prob. this sucks :(
dan
+1  A: 

Use 'index'.

def GetMorseCode(letter):
   index = letterList.index(letter)
   code = codeList[index]
   return code

Of course, you'll want to validate your input letter (convert its case as necessary, make sure it's in the list in the first place by checking that index != -1), but that should get you down the path.

dash-tom-bang
+1 both for answering the question, but also for doing so in a way that forces the questioner to actually finish the project solo.
acrosman
A: 
# Open the file
f = open('morseCode.txt', 'r')

# Read the morse code data into "letters" [(lowercased letter, morse code), ...]
letters = []
for Line in f:
    if not Line.strip(): break
    letter, code = Line.strip().split() # Assuming the format is <letter><whitespace><morse code><newline>
    letters.append((letter.lower(), code))
f.close()

# Get the input from the user
# (Don't use input() - it calls eval(raw_input())!)
i = raw_input("Enter a string to be converted to morse code or press <enter> to quit ") 

# Convert the codes to morse code
out = []
for c in i:
    found = False
    for letter, code in letters:
        if letter == c.lower():
            found = True
            out.append(code)
            break

    if not found: 
        raise Exception('invalid character: %s' % c)

# Print the output
print ' '.join(out)
David Morrissey
A: 

For the actual processing I'd keep a string of finished product, and loop through each letter in the string they have entered. I'd call a function to convert a letter to morse code, then add it to the string of existing morse code.

finishedProduct = []
userInput = input("Enter text")
for letter in userInput:
    finishedProduct.append( letterToMorseCode(letter) )
theString = ''.join(finishedProduct)
print(theString)

You could either check for space in the loop, or in the function that is called.

Iuvat
that's fine, i just have trouble splitting the string into individual letters
dan
It's a bad idea to build a string that way in Python -- it's O(N**2). Build a list, then join it with "".join(l), and print that.
moshez
A: 

creating table

morse = [None] * (ord('z') - ord('a') + 1)
for line in moreCodeFile:
    morse[ord(line[0].lower()) - ord('a')] = line[2:]

for converting

for ch in userInput:
    print morse[ord(ch.lower()) - ord('a')]
hamax
Ouch. Don't change the return value of range -- it happens to work, but it's not really supported or good style. If you want a list of a given length,morse = [None]*(ord('z')-(ord('a')) would work a lot better
moshez
@moshez thanks :)
hamax
+2  A: 

Why not just iterate through the string?

a_string="abcd"
for letter in a_string:
    print letter

returns

a
b
c
d

So, in pseudo-ish code, I would do this:

user_string = raw_input()
list_of_output = []
for letter in user_string:
   list_of_output.append(morse_code_ify(letter))

output_string = "".join(list_of_output)

Note: the morse_code_ify function is pseudo-code.

You definitely want to make a list of the characters you want to output rather than just concatenating on them on the end of some string. As stated above, it's O(n^2): bad. Just append them onto a list, and then use "".join(the_list).

As a side note: why are you removing the spaces? Why not just have morse_code_ify(" ") return a "\n"?

mellort
+1  A: 

A couple of things for ya:

The loading would be "better" like this:

with file('morsecodes.txt', 'rt') as f:
   for line in f:
      line = line.strip()
      if len(line) > 0:
         # do your stuff to parse the file

That way you don't need to close, and you don't need to manually load each line, etc., etc.

for letter in userInput:
   if ValidateLetter(letter):  # you need to define this
      code = GetMorseCode(letter)  # from my other answer
      # do whatever you want
dash-tom-bang
+1 that's good python style...learn this and you'll save a lot of code in the rest of your class and python life.
fitzgeraldsteele
Correction: "with open('morsecodes.txt') as f:"
Mark Tolonen
lol whoops, thanks.
dash-tom-bang
`len(line)` is always positive since it always contains at least end of the line character
SilentGhost
ah yes. <grumble grumble>
dash-tom-bang