可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Using inequality operators, I have to define a procedure weekend which takes a string as its input, and returns the boolean True if it's 'Saturday' or 'Sunday' and False otherwise.
Here is my code
def weekend(day):
if day != 'Saturday' or day != 'Sunday':
return False
else:
return True
This seemingly returns False to every day, I don't know why, logically it would work..o_o.. can anyone please explain I'm too noob :S
回答1:
Fixed version:
if day != 'Saturday' and day != 'Sunday'
Better version:
return day in ['Saturday', 'Sunday']
Why or
doesn't work:
When you use or
, your condition would read something like "if today is not Saturday or today is not Sunday". Now replace "today" by "Saturday":
If Saturday is not Saturday or Saturday is not Sunday
The statement "Saturday is not Saturday" is obviously false and "Saturday is not Sunday" is obviously true, so the entire statement becomes "if false or true", which is always true.
Replace "today" by any other day and you will find that the sentence always evaluates to one of these sentences, which are always true:
if True or False # day = Sunday
if False or True # day = Saturday
if True or True # any other day
回答2:
The best way to deal with this, use something like this:
return day.lower() in ['saturday','sunday']
回答3:
You mean and
def weekend(day):
if day != 'Saturday' and day != 'Sunday':
return False
else:
return True
or the clearer version (which just applies De Morgan to the above):
def weekend(day):
if day == 'Saturday' or day == 'Sunday':
return True
else:
return False
The day will always be different from one of both days.
回答4:
Tip for the future: think through your code as if you were the computer in excruciating detail. For example, I would literally have this conversation with myself:
Hmm, when day = 'Saturday'
, the code is returning False
even though I think it shouldn't. Let's see what's going on line-by-line.
def weekend(day):
- Okay that seems good from now on I'll replace
day
with 'Saturday'
anytime I see it...
if day != 'Saturday' or day != 'Sunday':
- Okay so I'll mentally translate this to
if 'Saturday' != 'Saturday' or 'Saturday' != 'Sunday':
.
- Now I'll simplify it by evaluating the comparisons.
'Saturday' != 'Saturday'
becomes False
'Saturday' != 'Sunday':
becomes True
- Plugging those in, I see that the
if
statement is saying if False or True
, which is the same as if True
. So that means that day = Saturday
leads to a return value of False
.
Aha, so now I see what was wrong with the day = 'Saturday'
case; the day != 'Sunday'
condition meant that the if
evaluated to True
.
So while the code below would return True
for day = 'Saturday'
,
def weekend(day):
if day != 'Saturday':
return False
else:
return True
and this code would work for day = 'Sunday'
,
def weekend(day):
if day != 'Sunday':
return False
else:
return True
the two cannot be combined with an or
.
So try to talk to yourself like that in the future- it's super useful for debugging, especially when there is confusing boolean logic.
(For the record, I think that return day.lower() in ['saturday','sunday']
is the best way to approach this.)
回答5:
def weekend(day):
# your code here
if day == 'Saturday' or day == 'Sunday':
return True
else:
return False
回答6:
I wrote this answer for Can not get “while” statement to progress, but it was marked as a duplicate right before I submitted it. And it is an exact logical duplicate (x != foo or y != bar
), so I'm posting this here in hopes that my answer might help somebody.
The answer is reproduced verbatim.
Your problem is here:
while username != logindata.user1 or username != logindata.user2:
...
while password != logindata.passw1 or password != logindata.passw2:
The username loop in English is something like, "Keep looping if the provided username
is either not equal to user1
, or not equal to user2
." Unless user1
and user2
are the same, no string will ever let that evaluate to False
. If 'username' is equal to user1
, it cannot be equal to user2
(again, assuming user1 != user2
, which is the case here).
The quick fix is to change the or
to and
. That way, you're checking whether username
is not either of the available options. A better way to write that would be:
while not (username == logindata.user1 or username == logindata.user2):
But I would say that the correct way to write it, given what you're trying to do, is this:
while username not in [logindata.user1, logindata.user2]:
In English, something like, "Keep looping while the username is not in this list of usernames."
P.S. I was going to use a set instead of a list, for pedantic correctness, but it really doesn't matter for this, so I figured a list would be easier for a beginner. Just mentioning it before someone else does :).