0

EDIT: Completely fixed now.

EDIT: Okay so now I got it to change '... --- ...' to 'sos' (yippee!) But for some reason, it gives me a KeyError when I input '... --- ... / ... --- ...'. This should give me 'sos sos' but I get a KeyError for ' '. I think this is because after the '/', there's a space which the program sees as a trigger to call the dictionary value of the current key. Problem being, the current key at that time is blank since the previous character was the '/'. How would I be able to fix this? Thanks.

I'm pretty new to programming with python (well, programming in general, really...) and today I had the bright idea of making a morse code converter.

I have the "plain text to morse code" working flawlessly, but the "morse code to plain text"?

Not so much.

The problem is that when I run the program, it doesn't give me anything, it just breaks its loop (like I told it to) without anything coming back to me.

If you guys could help me out, I'd very much appreciate it.

Oh also, 'decoding_dict' is the dictionary which I made which correlates morse code values to plain text. For example,

decoding_dict = {'...' : 's' , '---' : 'o'}

And so on and so forth.

def decode(text):
    text += ' ' 
    #I have it set up to trigger when there's a space, hence this.
    global key
    global decoded_text
    #I thought maybe this would fix it, it didn't. :(
    key = ''
    decoded_text = ''
    for i in text:
        if i == '.':
            key += i  #This adds a '.' to the key to reference later.
            continue
        elif i == '-':
            key += i   #See above comment.
            continue
        elif i == ' ':
            decoded_text += decoding_dict[key]
            text = text[(len(key) + 1) :]
            key = ''   #Calls the value of the key, cuts out the used text, and resets key.
            continue
        elif i == '/':
            decoded_text += decoding_dict['/']
            continue #In morse code, a '/' is a ' ' and that's in the dict.
        elif text == '':
            print "Result: " + decoded_text
            break #This is basically the end of the loop
        else:
            print "Error, please try again."
            break

Now when I run it with '... --- ...' , it goes back to the beginning and doesn't print anything. (By beginning, I mean the menu I made beforehand.)

Justin Son
  • 31
  • 1
  • 1
  • 6
  • 1
    The `text` value will never be an empty string. If that were true, your loop would already have ended. Along with that point, it's typically a bad idea to change the value of the thing you are iterating over within the loop – OneCricketeer Aug 01 '16 at 04:45
  • @Burhan: Although the linked question is also about Morse code, it doesn't explain what the problem is with the code in this question. – BrenBarn Aug 01 '16 at 04:56

3 Answers3

0

According to your code try something like this:-

def decode(text):
    text += '$' 
    #I have it set up to trigger when there's a space, hence this.
    global key
    global decoded_text
    #I thought maybe this would fix it, it didn't. :(
    key = ''
    decoded_text = ''
    for i in text:
        if i == '.':
            key += i  #This adds a '.' to the key to reference later.
            continue
        elif i == '-':
            key += i   #See above comment.
            continue
        elif i == ' ':
            decoded_text += decoding_dict[key]
            text = text[(len(key) + 1) :]
            key = ''   #Calls the value of the key, cuts out the used text, and resets key.
            continue
        elif i == '/':
            decoded_text += decoding_dict['/']
            continue #In morse code, a '/' is a ' ' and that's in the dict.
        elif text == '$':
            print "Result: " + decoded_text
            break #This is basically the end of the loop
        else:
            print "Error, please try again."
            break

According to My Suggestion Try This:-

def decode(text):
    error = False
    #I have it set up to trigger when there's a space, hence this.
    global key
    global decoded_text
    #I thought maybe this would fix it, it didn't. :(
    key = ''
    decoded_text = ''
    for i in text:
        if i == '.':
            key += i  #This adds a '.' to the key to reference later.
            continue
        elif i == '-':
            key += i   #See above comment.
            continue
        elif i == ' ':
            decoded_text += decoding_dict[key]
            text = text[(len(key) + 1) :]
            key = ''   #Calls the value of the key, cuts out the used text, and resets key.
            continue
        elif i == '/':
            decoded_text += decoding_dict['/']
            continue #In morse code, a '/' is a ' ' and that's in the dict.
        else:
            print "Error, please try again."
            error = True
            break
    else:
       If not error:
           print "Result: " + decoded_text

Last else is used with for instead of if else

Rakesh Kumar
  • 4,319
  • 2
  • 17
  • 30
  • Thanks man, but I ran the code like you suggested and now I'm getting a KeyError for ' '. I think this is because say if text = "... --- ... / ... --- ..." (which translates to sos sos) then the space after the '/' is a problem because at that point, it would try to call a blank key for the dictionary. How would you suggest I fix this? – Justin Son Aug 01 '16 at 05:40
  • To avoid getting keyError use decoding_dict.get(key, ' ') – Rakesh Kumar Aug 01 '16 at 05:59
  • Sorry, could you be more detailed? '/' : ' ' is already mapped in the dictionary and that still didn't solve the KeyError... – Justin Son Aug 01 '16 at 06:06
0

The for loop only considers the initial value of text. Your changes to text in the loop have no effect, because text is a string, and strings are immutable, so your modifications don't modify the original object that you're iterating over. The result is that your loop iterates over all of the original text, completing the loop without ever entering either of your break conditions.

Just get rid of the if text == '' check and move the "print results" line outside the for loop. You don't need to "cut out the used text", because by the time you get to the point where you want to do that, you've already iterated past the entire key. If you just pick up where you left off, you'll begin parsing the next Morse letter on the next loop iteration anyway.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • decoded_text += decoding_dict['/'] This line will generate an error. There's no key called '/' in decoding_dict. – Sharad Aug 01 '16 at 06:02
0

Assuming space ' ' is a separator in the input you specify, you may use this:

decoding_dict = {'...' : 's' , '---' : 'o'}
my_text = '... --- ...'
print(''.join(list(map(lambda x: decoding_dict.get(x, None), 

Output:


sos

As for the code above, there are couple of issues:

  • modifying 'text' while iterating over it
  • checking if text == '', which never happens. Hence, the result is never printed.

Try this:

def decode(text):
    text += ' '
    #I have it set up to trigger when there's a space, hence this.
    global key
    global decoded_text
    #I thought maybe this would fix it, it didn't. :(
    key = ''
    decoded_text = ''
    for i in text:
        if i == '.':
            key += i  #This adds a '.' to the key to reference later.
            continue
        elif i == '-':
            key += i   #See above comment.
            continue
        elif i == ' ':
            decoded_text += decoding_dict[key]
            key = ''   #Calls the value of the key, cuts out the used text, and resets key.
            continue
        elif i == '/':
            decoded_text += decoding_dict['/']
            continue #In morse code, a '/' is a ' ' and that's in the dict.
        else:
            print("Error, please try again.")
            break
    print("Result: " + decoded_text)

call: decode(my_text) Output:


Result: sos
Sharad
  • 9,282
  • 3
  • 19
  • 36
  • @JustinSon: You could include a check in the `if key == ' '` block that checks if the key is blank and if so just does `continue`. – BrenBarn Aug 01 '16 at 06:29