Search code examples
pythondictionarysyntax-erroremoji

Noob with a syntax error in dictionary (python)


I am trying to learn Python following the tutorial from Programming with Mosh.

I have created a program that starts up and greets me and then asks me to select an item on a list. Each list item is a "sub-program" that the tutorial covers. So I have two sub-programs in my program:

  • A chat translator that should return text and, via a dictionary, convert :) and :( to emojis
  • Then also a square calculator.

The problem I am facing is that my chat translator runs into a syntax error in the dictionary. This is where the error happens, at the first quotation mark in line 2 of the dictionary:

C:\Users\smelt\PycharmProjects\HelloWorld\venv\Scripts\python.exe C:/Users/smelt/PycharmProjects/HelloWorld/venv/app.py
  File "C:\Users\smelt\PycharmProjects\HelloWorld\venv\app.py", line 41
    ":(": emoji.emojize(":frowning_face:")
    ^
SyntaxError: invalid syntax

Part of the code the error happens in:

def emoji_converter(message):
    words = message.split(" ")
    emojis = {
        ":)": emoji.emojize(":smiling_face:"),
        ":(": emoji.emojize(":frowning_face:")
    }
    output = ""
    for word in words:
        output += emojis.get(word, word) + " "
    return output

This is my entire code:

first_name = "Henrik"
last_name = "Skaaning"
program_on = True
calculator_on = False
emoji_converter_on = False

def greet_user(first_name, last_name):
    # Standard greeting to user
        print(f"""Hi {first_name} {last_name}!
Welcome back!
""")

if program_on:
    while program_on:
        greet_user(first_name, last_name)
        selection = input(f"""This is Training program for Henrik Skaaning.
please enter a number to select a program to run
    1: Emoji converter
    2: Square calculator
enter "quit" to quit program...
selection> """)

        if selection == "1":
            emoji_converter_on = True
            print(f'Emoji converter on')

            while emoji_converter_on:
                import emoji

                def emoji_converter(message):
                    words = message.split(" ")
                    emojis = {
                        ":)": emoji.emojize(":smiling_face:"),
                        ":(": emoji.emojize(":frowning_face:")
                    }
                    output = ""
                    for word in words:
                        output += emojis.get(word, word) + " "
                    return output


                message = input("message> ")
                if message != "help":
                    if message != "quit":
                        print(emoji_converter(message))

                if message == "help":
                    print(f"""This is a simple emoji converter developed by Henrik Skaaning. 
Type a text in the command line with an emoji to return the text and emoji.
Type "help" in the command line to return the help-menu.  
Type "quit" in the command line to quit the application. """)

                if message == "quit":
                    emoji_converter_on = False
                    print(f'Emoji converter shutting off')

        if selection == "2":
            calculator_on = True
            print(f'Square calculator on')

        while calculator_on:

            def square(number):
                return int(number) * int(number)


            number = input("commandline> ")
            if number == "quit":
                program_on = False
                calculator_on = False
                print(f'Executing')
            if number != "quit":
                if number != "help":
                    if number.isnumeric() != True:
                        print(f"Sorry! That isnt a command i understand")
            if number == "help":
                print(f"""This is a simple square calculator developed by Henrik Skaaning. 
Type a number in the command line to return the square of that number
Type "help" in the command line to return the help-menu.  
Type "quit" in the command line to quit the application. """)

            if number.isnumeric():
                result = square(number)
                print(f' The result is {result}')

if program_on == False:
    print(f'Program shut down')

print(f'Done...')

Solution

  • While it is possible to define a function within another function, and sometimes using a closure makes things easier, this code has a really long mainline with a function defined within a while loop. This code would be better and easier to understand if it was written with the functions separated. Otherwise, as you now know, it can be hard to debug.

    The actual problem is that you have confused the syntax for a Python dict and JSON. A dict requires symbol / value pairs, while JSON requires string / value pairs.

    Below is a reorganized program for you. The bug was not corrected.

    first_name = "Henrik"
    last_name = "Skaaning"
    program_on = True
    calculator_on = False
    emoji_converter_on = False
    
    def emoji_converter(message):
        words = message.split(" ")
        emojis = {
            ":)": emoji.emojize(":smiling_face:"),
            ":(": emoji.emojize(":frowning_face:")
        }
        output = ""
        for word in words:
            output += emojis.get(word, word) + " "
        return output
    
    def greet_user(first_name, last_name):
        # Standard greeting to user
            print(f"""Hi {first_name} {last_name}!
    Welcome back!
    """)
    
    
    if program_on:
        while program_on:
            greet_user(first_name, last_name)
            selection = input(f"""This is Training program for Henrik Skaaning.
    please enter a number to select a program to run
        1: Emoji converter
        2: Square calculator
    enter "quit" to quit program...
    selection> """)
    
            if selection == "1":
                emoji_converter_on = True
                print(f'Emoji converter on')
    
                while emoji_converter_on:
                    import emoji
    
                    message = input("message> ")
                    if message != "help":
                        if message != "quit":
                            print(emoji_converter(message))
    
                    if message == "help":
                        print(f"""This is a simple emoji converter developed by Henrik Skaaning.
    Type a text in the command line with an emoji to return the text and emoji.
    Type "help" in the command line to return the help-menu.
    Type "quit" in the command line to quit the application. """)
    
                    if message == "quit":
                        emoji_converter_on = False
                        print(f'Emoji converter shutting off')
    
            if selection == "2":
                calculator_on = True
                print(f'Square calculator on')
    
            while calculator_on:
    
                def square(number):
                    return int(number) * int(number)
    
    
                number = input("commandline> ")
                if number == "quit":
                    program_on = False
                    calculator_on = False
                    print(f'Executing')
                if number != "quit":
                    if number != "help":
                        if number.isnumeric() != True:
                            print(f"Sorry! That isnt a command i understand")
                if number == "help":
                    print(f"""This is a simple square calculator developed by Henrik Skaaning.
    Type a number in the command line to return the square of that number
    Type "help" in the command line to return the help-menu.
    Type "quit" in the command line to quit the application. """)
    
                if number.isnumeric():
                    result = square(number)
                    print(f' The result is {result}')
    
    if program_on == False:
        print(f'Program shut down')
    
    print(f'Done...')
    

    Now that you know you need a symbol instead of strings like ":)" and ":(", can you fix it yourself?

    Hint: use string substitution instead of a dict. Convert all ":)" strings to ":smiling_face:", and ":(" strings to ":frowning_face:", like:

    message.replace(":)", ":smiling_face:").replace(":(", ":frowning_face:")
    

    The corrected program should be noticeably shorter.