0

I am new at coding and trying to make a rock, scissors paper game but according to the following code, even if I type "rock" for example input goes into first condition and give me "invalid input" output which should not happen if I am writing the code correctly, so where is my mistake ? Thanks in advance

while True:
        u1 = input("do yo want to choose rock, paper or scissors?")
        u2 = input("do you want to choose rock, paper or scissors?")
        if u1 != ('quit' or 'scissors' or 'rock' or 'paper'):
                print("Invalid input! You have not entered rock, paper or scissors, try again.\n")
        elif u2 != ('quit' or 'scissors' or 'rock' or 'paper'):
                print("Invalid input! You have not entered rock, paper or scissors, try again.\n")
        elif u1 == 'quit' or u2 == 'quit':
                break
        elif u1 == u2:
                print("It's a tie!\n")
        elif u1 == 'rock':
                if u2 == 'scissors':
                    print("Rock wins!\n")
                else:
                    print("Paper wins!\n")
        elif u1 == 'scissors':
                if u2 == 'paper':
                    print("Scissors win!\n")
                else:
                    print("Rock wins!\n")
        elif u1 == 'paper':
                if u2 == 'rock':
                    print("Paper wins!\n")
                else:
                    print('Scissors wins!\n'        )
ymn
  • 1
  • 2
  • 1
    `('quit' or 'scissors' or 'rock' or 'paper')` this is evaluating to `quit` and so `u1 != 'quit'` gives `True` and enters your condition. You should use `in` and a list of words. – palvarez Jul 26 '19 at 15:10
  • Possible duplicate of [How to test multiple variables against a value?](https://stackoverflow.com/questions/15112125/how-to-test-multiple-variables-against-a-value) – inspectorG4dget Jul 26 '19 at 15:13

2 Answers2

1

You misunderstand how Python's or works.

u1 != ('quit' or 'rock') is the same as u1 != 'quit'. This is because or works with the boolean value of a object, and any nonempty string is considered true. So 'quit' or 'rock' equals 'quit'.

If you want to check like that, it is better to either use a list or set and check its presence using in.

# Using a set
answers = {'quit', 'rock', 'paper', 'scissors'}
while True:
    u1 = ...
    u2 = ...
    if u1 not in answers:
        print('Invalid input:', u1)
    if u2 not in answers:
        print('Invalid input:', u2)
Edward Minnix
  • 2,889
  • 1
  • 13
  • 26
  • I still do not understand maybe because english is not my native language, for example if I say " come here if you are not scissors or paper or rock or banana " so if you are one of them you would not go but if you are then you would go, so isnt it the same thing with the line of code, if my input is not one of the 4 objects then condition must be satisfied and computer read the code inside this condition – ymn Jul 26 '19 at 21:06
  • @ymn it is a common misconception even among English speakers. In my intro to CS class a bunch of people got tripped on it. `or` is like the mathematical operator. `x or y` is the same thing as `x if x else y`. According to how strings work, `'quit'` is considered true. So the computer sees `'quit' if 'quit' else ...` and the whole expression is equal to `'quit'`. So `x == (y or z)` means `x == (y if y else z)`, not `x == y or x == z` – Edward Minnix Jul 26 '19 at 21:26
  • Alright, thank you, I will think about it more and will try to grasp it. – ymn Jul 26 '19 at 22:46
0

Your using an Or when you should be using an And. Or will return true if any of the conditions is met, whereas And will only return true if all of the conditions is met. Which is what you want in this case, so that only when u1 and u2 input is not equal to 'rock' And 'paper' And 'scissors' And 'quit' is the input invalid. With the Or, even if your input is 'rock', the statement still evaluates to true because 'rock' is not equal to 'paper' Or 'scissors' Or 'quit'. Try using these two statements for your if test instead.

if (u1 != 'quit') and (u1 != 'scissors') and (u1 != 'rock') and (u1 != 'paper'):
elif (u2 != 'quit') and (u2 != 'scissors') and (u2 != 'rock') and (u2 != 'paper'):
Luke
  • 838
  • 7
  • 17