Python testing whether a string is one of a certain set of values
I'm learning python on codecademy and my current task is this:
Write a function, shut_down, that takes one parameter (you can use anything you like; in this case, we'd use s for string). The shut_down function should return "Shutting down..." when it gets "Yes", "yes", or "YES" as an argument, and "Shutdown aborted!" when it gets "No", "no", or "NO".
If it gets anything other than those inputs, the function should return "Sorry, I didn't understand you."
Seemed easy to me but somehow I still can't do it.
My code I made to test the function:
def shut_down(s):
if s == "Yes" or s == "yes" or s == "YES":
return "Shutting down..."
elif s == "No" or "no" or "NO":
return "Shutdown aborted!"
else:
return "Sorry, I didn't understand you."
i = input("Do you want to shutdown?")
print(i) #was to test the input
print(shut_down(i)) #never returns "Sorry, I didn't understand you"
It works fine for the no's and yes', but somehow if I put a space before any yes or even if I just type in "a" it prints "Shutdown aborted!" although it should print "Sorry, I didn't understand you".
What am I doing wrong?
Solution 1:
You forgot to write s == "no"
in your first elif:
def shut_down(s):
if s == "Yes" or s == "yes" or s == "YES":
return "Shutting down..."
elif s == "No" or "no" or "NO": # you forgot the s== in this line
return "Shutdown aborted!"
else:
return "Sorry, I didn't understand you."
Do this:
def shut_down(s):
if s == "Yes" or s == "yes" or s == "YES":
return "Shutting down..."
elif s == "No" or s == "no" or s == "NO": # fixed it
return "Shutdown aborted!"
else:
return "Sorry, I didn't understand you."
This is because:
elif s == "No" or "no" or "NO": #<---this
elif s == "No" or True or True: #<---is the same as this
Since this is the accepted answer I'll elaborate to include standard practices: The convention for comparing strings regardless of capitalization (equalsIgnoreCase) is to use .lower()
like this
elif s.lower() == "no":
Solution 2:
Instead of checking for different combinations of capitalization you could uses the lower
function to return a copy of s
in lowercase and compare against that.
def shut_down(s):
if s.lower() == "yes":
return "Shutting down..."
elif s.lower() == "no":
return "Shutdown aborted!"
else:
return "Sorry, I didn't understand you."
This is much cleaner and easier to debug. Alternatively you could use upper
also and compare against "YES"
and "NO"
.
If this doesn't help because of matching cases like nO
then I'd go with the in
statement:
def shut_down(s):
if s in ("yes","Yes","YES"):
return "Shutting down..."
elif s in ("no","No","NO"):
return "Shutdown aborted!"
else:
return "Sorry, I didn't understand you."
Solution 3:
Python evaluates non empty strings to be True
, so your elif
condition is always evaluated to True
.
>>> bool('No')
True
>>> bool('NO')
True
Doing a boolean or
with a True
value would always return True
, so it never reaches the else
condition and gets stuck on the elif
one.
You need to test the conditions using.
elif choice == 'no' or choice == 'NO' or choice == 'No':
EDIT - As glglgl pointed out in the comment, ==
binds harder than or
, so your condition gets evaluated as (s == 'No') or 'no' or 'NO'
and not s == ('No' or 'no' or 'NO')
, in which case you would have gotten to the else
part even for a user input of 'NO'
.