Domanda

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... Can anyone please explain?

È stato utile?

Soluzione

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

Altri suggerimenti

The best way to deal with this, use something like this:

return day.lower() in ['saturday','sunday']

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.

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.)

def weekend(day):
    # your code here
    if day == 'Saturday' or day == 'Sunday':
        return True
    else:
        return False

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 :).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top