why do these pieces of code not work when I put or?

2

I made a program of stone paper and scissors. Everything works well (except when I want to add the option of 'scissors' or 'scissors' as an answer) I want you to accept both options as an input.

#(esta es una version simplificada de mi codigo,para ahorrarles tiempo)
#1 == piedra, 2 == papel, 3==tijera    

pc_juega = 3

usuario_juega = 'tijera'


if pc_juega == 1 and usuario_juega.lower() == 'tijeras' or 'tijera':
  print('La computadora gana! roca le gana a las tijeras!! ')
elif pc_juega == 2 and usuario_juega.lower() == 'tijeras' or 'tijera':
  print('Tu ganas! la tijeras le ganan al papel!! ')
elif pc_juega == 3 and usuario_juega.lower() == 'tijeras' or 'tijera':
  print('empate con tijeras') 
else:
  print('movimiento invalido')

#output:

La computadora gana! roca le gana a las tijeras!! 

(the output should be equal.) I would not like to stay with that doubt so I will be very grateful for any answer you give me.

    
asked by juan 14.10.2018 в 21:53
source

1 answer

3

The expression:

if cadena == "esto" or "aquello":

It does not work as expected. That is, it does not result in True when the string takes one of those two values. On the contrary, it is evaluated by Python as if you had written:

if (cadena == "esto") or "aquello":

This expression is a boolean composition that is True if what is on the left of or is True (and in that case Python does not even evaluate what is on the right) or if what there is on the left is False and what is on the right is True .

Specifically. If cadena has the value "esto" , the left side of or is True and therefore the whole expression would be True .

But if cadena is worth "xyzzy" , then the left side of or is False , so python will evaluate the right side, to find the expression "aquello" , which is not an expression Boolean, but a string.

When python finds a string where it expected a Boolean expression, it will consider the string as False if it is the empty string ( "" ) and True in any other case. In this example, since "aquello" is not the empty string, consider the right side of or as True . And therefore the whole expression is True .

In short, that expression turns out to be always True , so it will not work as expected.

This other expression does what you want:

if cadena == "esto" or cadena == "aquello":

You could also change it for this other one, more compact (especially when cadena is a longer expression, because you do not need to repeat it):

if cadena in ["esto", "aquello"]:

In your particular case, since you use it to admit both "scissors" and "scissors", you still have another option:

if usuario_juega.lower().startswith("tijera"):

Although, of course, I would also admit things like "scissors," etc.

Update

In reality, your expression is more complex and has another error:

if pc_juega == 1 and usuario_juega.lower() == 'tijeras' or 'tijera':

the expression has both and and or . In the% share% share the problem I explained above occurs. But what about the or ? Why does this branch enter the and if if was 3?

It happens that the pc_juega has more precedence than the and . That is, it is evaluated first. For Python, your line equals:

if (pc_juega == 1 and (usuario_juega.lower()=='tijeras') or 'tijera':

Start by looking at or and quit that no. Therefore everything in parentheses results in pc_juega==1 . By doing False of that or with the string False the result is 'tijera' as explained above ( True is not an empty string).

You should have set parentheses to force the 'tijera' to be evaluated first. This would be the correct way:

if pc_juega==1 and (usuario_juega.lower()=="tijeras" 
                    or usuario_juega.lower() == "tijera"):

Or shorter:

if pc_juega == 1 and usuario_juega.lower() in ["tijera", "tijeras"]:

This variant does not require parentheses because or has more precedence than in .

    
answered by 14.10.2018 / 22:07
source