-1

In this scenario, if x or y is not input then it's to rerun for proper input. Why does 'and' work in this scenario instead of 'or'?

    while var != 'x' and var != 'y':
        var = input("x or y ")

The above code functions as intended while the code below doesn't.

    while var != 'x' or var != 'y':
        var = input("x or y ")

Can someone please explain? If I'm understanding this correctly, if var does not receive an input of x or y then it's to rerun. When tested, it gets stuck on the input loop regardless if I input x or y. While the and version works fine.

Cire4
  • 33
  • 4

4 Answers4

4

Using or will always be true, since you're only entering one letter. So if one of the two conditions is false, the other one is true, and so you're stuck in the infinite loop, no matter which letters you enter.

Amin
  • 908
  • 1
  • 11
  • 23
3

Note that the following are equivalent:

var != 'x' or var != 'y'
not (var == 'x' and var == 'y')

It may be easier to see in the second form that it always evaluates to True.

Robert Price
  • 611
  • 4
  • 11
2

var != 'x' and var != 'y' should be true if var not in ['x','y'] (or as long as var is neither x nor y) .

var != 'x' or var !='y' is true only if var is not x or var is not y ... since it cannot be both x and y simultaneously this statement will always be true

except for something silly like the following case

class Test:
   def __ne__(self,other):
       return False

here is a truth table that further helps explain why its always true

cond1 = var !='x'   # T if var is anything but x, F if var is x

cond2 = var != 'y'  # T if var is anything but y, F if var is y

| cond1 | cond2 | cond1 ^ cond2 | value of var
+-------+-------+---------------+-------------
|  T    |  F    |   T           |  y
|  F    |  T    |   T           |  x
|  T    |  T    |   T           |  a
|  F    |  F    |   F           |  var = x && var = Y => IMPOSSIBLE
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
0

In your code, you want to break out of your loop if the user enters either x or y. You could write that condition (when you want to quit) as var == 'x' or var == 'y'. But you're testing the values in a while loop, which will keep on looping if its condition true. You stop looping if the condition is false. So you'd need to negate the condition. You could use not (var == 'x' or var == 'y').

The version in your working code is just a more concise way of checking the same thing. By DeMorgan's laws, the negation of an disjunction (an or expression) is the conjunction of the negations (an and expression with negations within it). A way of writing that symbolically is: not (A or B) = not A and not B

In Python code, we can take an extra step of combining not and == into !=. But it could work without that, if you needed it to. These three loops would all work for you:

  1. while not (var == 'x' or var == 'y'):
  2. while not var == 'x' and not var == 'y':
  3. while var != 'x' and var != 'y':

Pick whichever one seems most expressive to you. I'd probably prefer the third. Or I'd rewrite the condition as var not in ['x', 'y'], to avoid the repetition of var == outright.

Blckknght
  • 100,903
  • 11
  • 120
  • 169