1

I try to understand why I get unreasonable result from the following if:

def print_if_neg (a,b):   
    if a < 0 != b < 0:
        print "Only One Neg"
    else:
        print "0 or 2"

print_if_neg(1,1)
print_if_neg(-1,1)
print_if_neg (1,-1)
print_if_neg(-1,-1)

I get 3 times 0 or 2 and then last one Only One Neg.
What is the order of this complicated condition?

I've tried this:

if (a < 0) != (b < 0):

and it's ok but I'm trying to understand why above doesn't work.

Robert
  • 33,429
  • 8
  • 90
  • 94
yzahavi
  • 45
  • 2

5 Answers5

1

You need parentheses due to operator precedence

def print_if_neg (a,b):   
    if (a < 0) != (b < 0):
        print "Only One Neg"
    else:
        print "0 or 2"
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
1

As CoryKramer pointed out, the operator precedence is making the difference.

Your code is equivalent to this:

def print_if_neg (a,b):   
    if a < (0 != b) < 0:
        print "Only One Neg"
    else:
        print "0 or 2"

Because != has higher precedence than < by language definition.

So, use () to force the precedence that you need:

def print_if_neg (a,b):   
    if (a < 0) != (b < 0):
        print "Only One Neg"
    else:
        print "0 or 2"

Also, FYI you are coding the xor operator.

Robert
  • 33,429
  • 8
  • 90
  • 94
1

Due to operator precedence you need to place the two conditions in parentheses for your expected results. Otherwise the comparison operators are solved, checking for 0 != b in your code, which is not what you expect.

def print_if_neg (a,b):
    if (a < 0) != (b < 0):
        print ("Only One Neg")
    else:
        print ("0 or 2")

print_if_neg(1,1)
print_if_neg(-1,1)
print_if_neg (1,-1)
print_if_neg(-1,-1)

Note that all comparison operators have the same precedence and comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y AND y <= z

Nabeel M.
  • 25
  • 1
  • 8
0

This is because condition a < 0 != b < 0 means a < 0 AND 0 != b AND b < 0 First of all when a >= 0 first condition evaluates to False and so nothing else gets evaluated. Then, if a is <0 but b=1 last condition in the chain is False. Therefore your chained condition is False 3 out of 4 times.

This is well explained in section 6.10 of Python documentation.

AGN Gazer
  • 8,025
  • 2
  • 27
  • 45
0

From this, you could make it more readable imo:

from operator import xor
def print_if_neg (a, b):   
    if xor(a < 0, b < 0):
        print "Only One Neg"
    else:
        print "0 or 2"
Raf
  • 1,628
  • 3
  • 21
  • 40