Syber
Syber

Reputation: 451

Validating the value of several variables

What I am after: The user is allowed to input only 0 or 1 (for a total of 4 variables). If the user inputs for example 2, 1, 1, 0 it should throw an error saying Only 0 and 1 allowed.

What I've tried so far:

if (firstBinary != 0 or firstBinary != 1 and secondBinary != 0
      or secondBinary != 1 and thirdBinary != 0 or thirdBinary != 1
      and forthBinary != 0 or forthBinary != 1):
    print('Only 0 and 1 allowed')
else:
    print('binary to base 10: result)

Problem: When I use such a statement, I get either the result even when I input for example 5, or I get 'only 0 and 1 allowed' even though I wrote all 1 or 0.


I found this which seemed to be what I was after, but it is still not working like I want it to:

if 0 in {firstBinary, secondBinary, thirdBinary, forthBinary} or 1 in \
    {firstBinary, secondBinary, thirdBinary, forthBinary}:
    print("Your result for binary to Base 10: ", allBinaries)
else:
    print('Only 0 and 1 allowed')

This code basically gives me the same result as what I get with the first code sample.

Upvotes: 3

Views: 118

Answers (4)

dmitry_romanov
dmitry_romanov

Reputation: 5425

values = [firstBinary, secondBinary, thirdBinary]
if set(values) - set([0, 1]):
    print "Only 0 or 1, please"

Upvotes: 0

Dartmouth
Dartmouth

Reputation: 1089

This is due to the operator precedence in python. The or operator is of higher precedence than the and operator, the list looks like this:

  1. or
  2. and
  3. not
  4. !=, ==

(Source: https://docs.python.org/3/reference/expressions.html#operator-precedence)

So, python interprets your expression like this (the brackets are to clarify what is going on):

if (firstBinary != 0 or (firstBinary != 1 and secondBinary != 0 or (secondBinary != 1 and \
thirdBinary != 0 or (thirdBinary != 1 and forthBinary != 0 or (forthBinary != 1)))))

Which results in a different logic than what you want. There are 2 possible solutions to this, the first one is to add brackets to make the expression unambiguous. This is quite tedious and long-winded:

if ((firstBinary != 0 or firstBinary != 1) and (secondBinary != 0 or secondBinary != 1) and \
(thirdBinary != 0 or thirdBinary != 1) and (forthBinary != 0 or forthBinary != 1))

The other approach is to use the in-built all function:

vars = [firstBinary, secondBinary, thirdBinary, fourthBinary]
if not all(0 <= x <= 1 for x in vars):
    print("Only 0 or 1 allowed")

Upvotes: 3

perreal
perreal

Reputation: 98088

Use any:

v1, v2, v3, v4 = 0, 1, 1, 2

if any(x not in [0, 1] for x in [v1, v2, v3, v4]):
    print "bad"

of course, if you use a list it will look even better

inputs = [1, 1, 0 , 2]

if any(x not in [0, 1] for x in inputs):
    print "bad"

Upvotes: 6

bgporter
bgporter

Reputation: 36554

I'd break it down into the two parts that you're trying to solve:

Is a particular piece of input valid? Are all the pieces of input taken together valid?

>>> okay = [0,1,1,0]
>>> bad = [0,1,2,3]

>>> def validateBit(b):
...    return b in (0, 1)

>>> def checkInput(vals):
...    return all(validateBit(b) for b in vals)
...
>>> checkInput(okay)
True
>>> checkInput(bad)
False
>>>

Upvotes: 1

Related Questions