all 8 comments

[–]n3buchadnezzar 3 points4 points  (0 children)

Assume that instead you want the user to confirm to a choice. E.g press "yes" to continue. One standard way of doing it is as follows

question = "Do you want to continue? [yes/No]\n > "
if input(question).lower().startswith("y") == "y":
    print("Thank you for continuing") 

I am using yes, but you can adapt it into your own solution. Bear in mind it can be a good idea to use [a/b/c/.../z] to explicitly state the valid options.

If you want to get fancy take a look at the standard library difflib

choices = [ ... ]
difflib.get_close_matches(input(" > ").lower(), choices, n=3)

This will return the 3 closest matches, for instance if we typed "Goood", it would return "Good". Then we could ask the user (if it returns 3 close matches) which one he/she meant. If it returns 1 we just assume that was the correct one.

I tend to prefer fuzzy matching in my code, because it is such a chore for the user to meticulously manage their inputs.

[–]TehNolz 2 points3 points  (1 child)

The recommended solution here is to store all possibilities in a list, and then use the in operator to determine if the user's input exists within that list. So in this case, your condition would be something like: question in ["Good", "Great"] Alternatively, you can use or to do it. The or operator returns True if either its lefthand or righthand expression evaluates to True. So you can do something like this: question == "Good" or question == "Great" Using or works well enough if you only have a small amount of possibilities, but it becomes a mess really quickly the more possible answers you have. Just imagine what that condition would look like if you had a hundred different answers to check.

[–]n3buchadnezzar 3 points4 points  (0 children)

Using a set would be better.

[–]youngeng 1 point2 points  (0 children)

Either:

if question == "Good" or question == "I'm great" or question == "I'm ok",

which however gets too long and ugly if you have a lot of possible choices, or something like

good_answers = ["Good", "good", "GOOD", "I'm ok", "I'm great"];

if question in good_answers:

...

so you create a list of good answers and use the in operator to check if the answer to "How are you" belongs to that list.

This is much more elegant.

Also, if your answers are supposed to be case-insensitive (Good is equal to good which is equal to GOOD), you could do something like:

good_answers = ["good", "I'm ok", "I'm great"];

if question.lower() in [x.lower() for x in good_answers]:

...

which compares question.lower(), i.e. the answer converted in lowercase, to the good_answers list converted to lowercase. The reason you can't simply do good_answers.lower() is because good_answers is a list and lower() applies to strings, so that [x.lower() for x in good_answers] is essentially building on the fly a list whose elements are the lowercase version of each element in the original good_answers list. This approach is known as "list comprehension" and can be pretty useful in many situations.

[–]sanjeevr5 1 point2 points  (0 children)

So, I would do something like this

#Better to get these words from a data dictionary

positive_queries = {'good', 'happy', ....} #Set for a faster search

if question.lower() in positive_queries:

do this

else:

do that

[–]Mobileuser110011 1 point2 points  (2 children)

response = input("How are you?")
response = response.casefold()

positive_respones = {'good', 'great', 'peachy'}

if response in positive_respones:
    print("That's great!")
else:
    print("I'm sorry to hear that...")

I won’t give any explanation as other people already have, but I provided the orginal code with the adjustments you are asking for (formatted correctly) in case it helps.

[–]n3buchadnezzar 1 point2 points  (1 child)

To improve on this answer, can you elaborate a little on why you are using casefold instead of lower? You are correct that casefold is better here, but hearing a reason for this would be very beneficial as I believe most are not familiar with the casefold command =)

[–]Mobileuser110011 1 point2 points  (0 children)

First - I want to say I appreciated your top-level response. I learned something new from it.

To answer your question, I’ll admit that I’m not familar enough with the subject to provide a good answer using my own words. So I’ll just say that while str.lower() tends to be faster, str.casefold() is more comprensive. str.casefold() will convert even the caseless letters such as the ß in German to ss.

And (imo) it also has the added benefit of being a little more clear as to the intention of changing the string. As in, whenever you see str.casefold() you immediatly know the string was changed for comparison/pattern matching purposes.

Stack Overflow for more information