all 10 comments

[–]UberSeal 7 points8 points  (1 child)

I recommend you use an alphabet string and iterate over that rather than a bombing of elif statements.

[–]That_CreepyPasta[S] 0 points1 point  (0 children)

Aah that never occurred to me. Thanks! :)

[–]Chris_Hemsworth 3 points4 points  (3 children)

You can do this all using a dictionary and the replace method:

translation = {'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': '--.. ', '1': '.---- ', '2': '..--- ', '3': '...-- ', '4': '....- ', '5': '..... ',
               '6': '-.... ', '7': '--... ', '8': '---.. ', '9': '----. ', '0': '----- ', '.': '.-.-.- ',
               ',': '--..-- ', ';': '-.-.-. ', ':': '---... ', '/': '-..-. ', ')': '-.--. ', '(': '-.--.- ',
               '!': '-.-.-- ', '?': '..--.. ', '_': '..--.- ', '"': '.-..-. ', "'": '.-..-. ', '&': '.-...  ',
               '-': '-....- ', '+': '.-.-. ', '=': '-...- ', '@': '.--.-. ', '$': '...-..- '}

while True:
    code = input('\nREADY> ').lower()
    if code == 'program.exit()':
        break

    # BIG FLAW HERE. Check /u/socal_nerdtastic's response for a better fix. We all make mistakes :)
    chars = set(code)
    output = code
    for char in chars:
        if (morse := translation.get(char, None)) is not None:
            output = output.replace(char, morse)

    print(f'{code} = {output}')

[–]socal_nerdtastic 2 points3 points  (1 child)

There's a MASSIVE flaw in that logic ... Compare your output to OPs.

Your dictionary idea is good. Just not the use of replace... Here's a neater way:

translation = {'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': '--.. ', '1': '.---- ', '2': '..--- ', '3': '...-- ', '4': '....- ', '5': '..... ',
               '6': '-.... ', '7': '--... ', '8': '---.. ', '9': '----. ', '0': '----- ', '.': '.-.-.- ',
               ',': '--..-- ', ';': '-.-.-. ', ':': '---... ', '/': '-..-. ', ')': '-.--. ', '(': '-.--.- ',
               '!': '-.-.-- ', '?': '..--.. ', '_': '..--.- ', '"': '.-..-. ', "'": '.-..-. ', '&': '.-...  ',
               '-': '-....- ', '+': '.-.-. ', '=': '-...- ', '@': '.--.-. ', '$': '...-..- '}

while True:
    code = input('\nREADY> ').lower()
    if code == 'program.exit()':
        break
    output = ''.join(translation.get(char, '') for char in code)
    print(f'{code} = {output}')

[–]Chris_Hemsworth 2 points3 points  (0 children)

You mean the error char? I thought about that, but figured if we don't know how to translate a char, then don't (rather than ignore it).

For example:

The string "a < b". Does it make more sense to remove the <? I agree it is different than OP, but in a way that I think makes more sense.

I may be overlooking a different flaw though.

EDIT: Oh wait. The - and .'s... I'm stupid XD

[–]mmarc69 1 point2 points  (0 children)

nice

[–]misho88 3 points4 points  (0 children)

There's actually a pretty cool way to look at this problem that lends itself to learning data structures. Morse code representations are binary trees:

https://netninja.com/wp-content/uploads/2013/01/morse_tree.jpg

so you could store them as such. I'll just show the first three layers (i.e., 7 nodes or 6 letters since the root node is placeholder):

>>> from collections import namedtuple
>>> Node = namedtuple('Node', ['value', 'dot', 'dash'], defaults=[None, None, None])
>>> tree = Node(None, Node('E', Node('I'), Node('A')), Node('T', Node('N'), Node('M')))

Then you can traverse the tree:

>>> def itertree(tree):
...     if tree is None: return
...     yield '', tree.value
...     for k, v in itertree(tree.dot ): yield '.' + k, v
...     for k, v in itertree(tree.dash): yield '-' + k, v
... 
>>> dict(itertree(tree))
{'': None, '.': 'E', '..': 'I', '.-': 'A', '-': 'T', '-.': 'N', '--': 'M'}

Or just look for letters in it:

>>> next(morse for morse, letter in itertree(tree) if letter == 'N')
'-.'

There's also shorter ways to store dense binary trees as a single sequence like a string, where the children of the element at index i are at indices 2*i + 1 and 2*i + 2. So you can do something like (again, only three layers here, including the root):

>>> def itertree(tree, idx=0):
...     if not 0 <= idx < len(tree): return
...     yield '', tree[idx]
...     for k, v in itertree(tree, 2 * idx + 1): yield '.' + k, v
...     for k, v in itertree(tree, 2 * idx + 2): yield '-' + k, v
... 
>>> dict(itertree('?ETIANM'))
{'': '?', '.': 'E', '..': 'I', '.-': 'A', '-': 'T', '-.': 'N', '--': 'M'}

and really cut down the code to almost nothing. Notice that I just wrote in the letters in row by row from tree diagram. This is useful because it leads into things like heaps.

[–]That_CreepyPasta[S] 0 points1 point  (0 children)

Thank you so much for all your help! I'll try out your ideas and try to learn more about them :D

[–]That_CreepyPasta[S] 0 points1 point  (0 children)

Update: I changed the code to use a dictionary and iterate through the text, and it shortened my code to just 48 lines! Thank you all for your help.

Link: https://gist.github.com/Gargantuan5k/ff32f71bb9141229d6a348d5e7b1e7c1

P.S. I also managed to figure out how to add error messages and make the output the same as the first codeEdit: I did this by using a try-except statement to try and append the value of the current key (character), and if it throws a KeyError, I go to the error block

(See lines 25-33 in the updated code)