Python: error de operadores de desigualdad booleana simple

Usando operadores de desigualdad, tengo que definir un fin de semana de procedimiento que toma una cadena como su entrada, y devuelve el verdadero booleano si es ‘sábado’ o ‘domingo’ y Falso de lo contrario.

Aqui esta mi codigo

def weekend(day): if day != 'Saturday' or day != 'Sunday': return False else: return True 

Esto aparentemente devuelve False a todos los días, no sé por qué, lógicamente funcionaría … o_o .. ¿alguien puede explicar que soy demasiado noob: S

Versión fija:

 if day != 'Saturday' and day != 'Sunday' 

Mejor versión:

 return day in ['Saturday', 'Sunday'] 

¿Por qué or no funciona?

Cuando usas or , tu condición leería algo así como “si hoy no es sábado o hoy no es domingo”. Ahora reemplaza “hoy” por “sábado”:

Si el sábado no es sábado o el sábado no es domingo

La statement “Sábado no es sábado” es obviamente falsa y “Sábado no es domingo” es obviamente verdadera, por lo que toda la statement se convierte en “Si es falsa o verdadera”, lo que siempre es cierto.

Reemplace “hoy” por cualquier otro día y encontrará que la oración siempre se evalúa en una de estas oraciones, que siempre son verdaderas:

 if True or False # day = Sunday if False or True # day = Saturday if True or True # any other day 

La mejor manera de lidiar con esto, usa algo como esto:

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

Quieres decir and

 def weekend(day): if day != 'Saturday' and day != 'Sunday': return False else: return True 

o la versión más clara (que solo aplica De Morgan a la anterior):

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

El día siempre será diferente de uno de los dos días.

Sugerencia para el futuro: piense en su código como si fuera la computadora con un detalle insoportable . Por ejemplo, literalmente tendría esta conversación conmigo mismo:

Hmm, cuando day = 'Saturday' , el código está devolviendo False , aunque creo que no debería. Vamos a ver qué pasa en línea por línea.

def weekend(day):

  • Bueno, eso parece bueno de ahora en adelante. Reemplazaré el day con 'Saturday' cualquier momento que lo vea …

if day != 'Saturday' or day != 'Sunday':

  • Está bien, así que lo traduciré mentalmente if 'Saturday' != 'Saturday' or 'Saturday' != 'Sunday':
  • Ahora lo simplificaré evaluando las comparaciones.
    • 'Saturday' != 'Saturday' vuelve False
    • 'Saturday' != 'Sunday': convierte en True
  • Al enchufarlos, veo que la instrucción if dice if False or True , que es lo mismo que if True . Eso significa que ese day = Saturday lleva a un valor de retorno de False .

Ajá, así que ahora veo lo que estaba mal en el caso del day = 'Saturday' ; la condición del day != 'Sunday' significaba que if evaluaba como True .

Entonces, mientras que el siguiente código devolvería True para el day = 'Saturday' ,

 def weekend(day): if day != 'Saturday': return False else: return True 

y este código funcionaría para el day = 'Sunday' ,

 def weekend(day): if day != 'Sunday': return False else: return True 

los dos no se pueden combinar con un or .

Así que trata de hablarte así en el futuro: es muy útil para la depuración, especialmente cuando hay una lógica booleana confusa.

(Para que return day.lower() in ['saturday','sunday'] constancia, creo que return day.lower() in ['saturday','sunday'] es la mejor manera de abordar esto.)

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

Escribí esta respuesta para No se puede obtener la statement de “while” , pero se marcó como un duplicado justo antes de enviarla. Y es un duplicado lógico exacto ( x != foo or y != bar ), así que estoy publicando esto aquí con la esperanza de que mi respuesta pueda ayudar a alguien.

La respuesta se reproduce textualmente.


Su problema está aquí:

 while username != logindata.user1 or username != logindata.user2: ... while password != logindata.passw1 or password != logindata.passw2: 

El bucle de nombre de usuario en inglés es algo así como “Mantener bucle si el username proporcionado no es igual a user1 , o no es igual a user2 “. A menos que user1 y user2 sean iguales, ninguna cadena permitirá que se evalúe como False . Si ‘username’ es igual a user1 , no puede ser igual a user2 (de nuevo, asumiendo que user1 != user2 , que es el caso aquí).

La solución rápida es cambiar el or para and . De esa forma, verificará si el username no es una de las opciones disponibles. Una mejor manera de escribir sería:

 while not (username == logindata.user1 or username == logindata.user2): 

Pero diría que la forma correcta de escribirlo, dado lo que intentas hacer, es esta:

 while username not in [logindata.user1, logindata.user2]: 

En inglés, algo así como, “Manténgase en bucle mientras el nombre de usuario no esté en esta lista de nombres de usuario”.

PD: iba a usar un conjunto en lugar de una lista, para una corrección pedante, pero realmente no importa para esto, así que pensé que una lista sería más fácil para un principiante. Solo mencionándolo antes de que alguien más lo haga :).