0

I am working on a project that at one point will ask the user a yes/no question. I currently use this code to handle such questions:

def yn():
    global finalchoice
    choice=str(raw_input("Y/N: "))
    if choice == "Y":
        finalchoice="true"
    elif choice == "y":
        finalchoice="true"
    elif choice == "N":
        finalchoice="false"
    elif choice == "n":
        finalchoice="false"
    else:
        yn()
    pass

but this seems to be quite inefficient, specifically where I have to check for both "Y" and "y" or "N" and "n" separately. I've tried:

if choice == "Y" or "y":
    finalchoice="true"

Unfortunately, all this does is ignore the 'else' command and will pass whatever I give it.

Any tips?

Hannes Ovrén
  • 21,229
  • 9
  • 65
  • 75
ExplodingKittens
  • 141
  • 1
  • 2
  • 10
  • You can convert you input into lower case so even if user inputs upper-case if will convert it into lower case and you can use 'y' or 'n' in your if case. 'choice=str.lower(raw_input("Y/N: "))' – Tanveer Alam Apr 24 '14 at 07:12
  • @Aशwiniचhaudhary this question is definitely close, but Sudipta gave the answer I was really looking for. – ExplodingKittens Apr 24 '14 at 07:15
  • 1
    @TanveerAlam also offered a great solution. Thanks to the both of you! – ExplodingKittens Apr 24 '14 at 07:16
  • 1
    @Sil why use `"true"` and not `True`? Also, you could `return` instead of using `global`. – jonrsharpe Apr 24 '14 at 07:17
  • @jonrsharpe because I want to leave "finalchoice" as a string so that I can reuse it in the future. I don't want it to get set as a Boolean variable. – ExplodingKittens Apr 24 '14 at 07:18
  • @Sil Kindly close the question by [accepting](http://stackoverflow.com/help/accepted-answer) the answer if it worked for you. – Sudipta Apr 24 '14 at 07:21
  • 1
    @Sil that doesn't make sense, how is a Boolean *not* reusable? If you need a string representation later, `str(True).lower() == "true"`. – jonrsharpe Apr 24 '14 at 07:24
  • @jonrsharpe I plan on using it for more than just "true" or "false" in the future is what I mean. If I try to assign a string to a Boolean, then I'll get an error. – ExplodingKittens Apr 24 '14 at 07:34
  • @Sil what do you mean "assign a string to a Boolean"? Python is dynamically typed; if you later do `finalchoice = "foo"` that's fine, or you can use the existing value in the new string: `finalchoice = "value was {0}.".format(finalchoice)` – jonrsharpe Apr 24 '14 at 07:36

2 Answers2

6

if choice == "Y" or "y": is not right! It will always evaluate to True.

It essentially is (choice == "Y") or ("y"). And the latter is True because any non empty string in python logically evaluates to boolean True.

You should be doing:

if choice in ["Y","y"]:

Or,

if choice == "Y" or choice == "y":

Or you can use:

if choice.lower() == "y":
    finalchoice="true"
Sudipta
  • 4,773
  • 2
  • 27
  • 42
1

To add to @Sudipta's answer, one way would be to remove the case AND just take the first letter:

if choice.lower().startswith("y"):
    finalchoice="true"
philshem
  • 24,761
  • 8
  • 61
  • 127