Trouble with code:

def English():
    words = ["The", "Hello", "And", "Goodbye", "Bye", "Good morning"]
    print(f'Avalible words: {words}')

    var = input("What word are you looking for? ").title()

    def translate():

        if var == "The" :
            print(f'The German word for {var} is "Der, Die, Das"')
        
        elif var == "Hello" :
            print(f'The German word for {var} is "Hallo"')

        elif var == "And" :
            print(f'The German word for {var} is "Und"')

        elif var == "Bye" :
            print(f'The German word for {var} is "TschĂĽss"')
        
        elif var == "Good Morning" or "Goodmorning" :
            print(f'The German word for {var} is "Guten Morgen"')

        elif var == "Goodbye" or "Good Bye" :
            print(f'The German word for {var} is "Auf Wiedersehen"')
        

        else :
            print ('Error!')

    translate()


English()

The above code works fine up until “Good Morning” and “Goodbye”… They seem to read them as the same word and the translation comes out wrong.
Would love some advice / help of some more experienced programmers than me, Thanks
:raised_hands: :raised_hands:

I won’t comment on the organization of the rest of the code but just point out an error.

You used OR wrong.

        elif var == "Goodbye" or "Good Bye" :
            print(f'The German word for {var} is "Auf Wiedersehen"')

You meant more like this:

        elif (var == "Goodbye" or var == "Good Bye") :
            print(f'The German word for {var} is "Auf Wiedersehen"')

The problem is your code evaluates to if

Condition or True

Anything considered “truthy” is evaluated to be equivalent to True/False and a non-empty character string like “Good Bye” is considered True.

Because of your nested series of if/elif/elif/…/else you stop as soon as anything is True so nothing below there is reached.

Your code is a start and there are many other ways some people would implement it.

1 Like

Hi,

you can also use a tuple for your conditional statement argument, as in:

elif var in ("Good Morning", "Goodmorning"):

Here, the keyword in is used and determines if the test variable var equals any of the values within the tuple (or list).

2 Likes

Thanks, this fixed the issue.

Does this way work better than the above method??
Or is it just personal preference?

There really is no difference in performance … more to do with preference.
Note that when you have multiple or choices, the in keyword simplifies it since there is less to type. As a simple test, try testing a case scenario where you have 4 different choices and implement the choice using both methods. It should become clear.

Also, if you have a tuple (or list) of values, you can just write the variable name instead of writing one by one in the conditional statement … which can simplify it further.

2 Likes

For the simple case here where a question is asked once, how fast it works is often not important.

A bigger gap is whether to use regular expressions to encapsulate sometimes complex possibilities.

In this case, you wanted to match several similar possibilities:

Good Morning

Goodmorning

The main differences are an optional space and capitalization of the M in morning. But, what if you wanted to accept the above in all upper case or all lower case or many other combinations and perhaps even with spaces before or after or more in between or accept tabs or ignore something like underscores as in Good_Morning. You can imagine quite a few scenarions including making good morn acceptable.

For some such cases, although standard python functions like converting it to all lower case, can be used, regular expressions are very useful as you can ask to match optional whitespace, then the letters in either case for G o o d then optional whitespace and so on.

But that tends to come with a cost as underneath it all, a little machine is built that traverses your text and has lots of hidden activities like if statements or some kinds of recursion. Yet, it can be fast enough as it can very tersely allow fairly complicated analyses.

If there is a class being taken that wants to exercise what you have been learning, of course, using somewhat more advanced language features is not yet the right choice.

But just imagine if your task was not to translate this set of words from English to German, but to accept a larger set of phrases not just from English but French and Spanish and Italian and Hungarian and Russian and in all cases produce the same output telling you how to do it in German. Paul’s solution of asking for phrases in (tuple items) might work fine, if you have UNICODE, but would not easily deal with issues like optional spaces or upper/lower case. The regular expression allows you to say something like “(pattern1)|(pattern2)|pattern3)” and even be able to know which one matched. There is the usual tradeoff as in a good programmer can be highly productive in how they state the problem and the spaghetti code generated need not be seen and may work slower and yet do more.

As a rule, the implementation of some things matters. You can build your own function that takes a tuple and the input as arguments and does a loop over the contents of the tuple and returns if it matches anything. This is a very general solution that works for one or a dozen or millions of entries. Sometimes it finds and exits quickly and sometimes it may search to the end and perhaps not find it. For just two items , it likely is slower than just doing your own two comparisons and note python sometimes is optimized so that A or B returns True as soon as A is true and skips evaluating B. The speed depends on whether you have A, or B or neither.

But back to your original question, I think you can see what went wrong as any intuition that you can use the “or” verb this way is not quite right.

I have adjusted your translate() function. Please look at it carefully.

    def translate():

        if var == "The" :
            print(f'The German word for {var} is "Der, Die, Das"')
        
        elsif var == "Hello" :
            print(f'The German word for {var} is "Hallo"')

        elsif var == "And" :
            print(f'The German word for {var} is "Und"')

        elsif var == "Bye" :
            print(f'The German word for {var} is "TschĂĽss"')
        
        elsif (var == "Good Morning") or (var == "Goodmorning") :
            print(f'The German word for {var} is "Guten Morgen"')

        elsif (var == "Goodbye") or (var == "Good Bye") :
            print(f'The German word for {var} is "Auf Wiedersehen"')

        else :
            print ('Error!')

Here is an alternate method if you wish to add words to the words database without having to update or increase the underlying word lookup/selection script:

words = {'The': "Der, Die, Das", 'Hello': "Hallo", 'And': "Und",
           'Bye': "TschĂĽss", 'Goodbye': 'Auf Wiedersehen', 'Good Bye': 'Auf Wiedersehen',
           'Good Morning': 'Guten Morgen', 'Goodmorning': 'Guten Morgen'}

var = input('What word are you looking for? ').title()

try:
    print(f"The German word for '{var}' is '{words[var]}'.")

except KeyError:
    print('Word not in list for translation.  Try again.')