1 > 0 == True -> False

T

Thibault Langlois

Hello,

$ python
Python 2.7.4 (default, Sep 26 2013, 03:20:26)
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
What am I missing here ?

T.
 
J

Jussi Piitulainen

Thibault said:
Hello,

$ python
Python 2.7.4 (default, Sep 26 2013, 03:20:26)
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
What am I missing here ?

One or both of the following:
True

Or the fact that (1 > 0 == True) means ((1 > 0) and (0 == True)),
where each expression in such a chain is evaluated once, though in
this case it really does not matter since 0 is a literal.

Hm, I don't know if the evaluation short-circuits. I think not, but
I've never needed to know, and I don't need to know now.
 
P

Peter Otten

Jussi said:
Thibault said:
Hello,

$ python
Python 2.7.4 (default, Sep 26 2013, 03:20:26)
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
1 > 0 == True False
(1 > 0) == True True
1 > (0 == True) True

What am I missing here ?

One or both of the following:
True

Or the fact that (1 > 0 == True) means ((1 > 0) and (0 == True)),
where each expression in such a chain is evaluated once, though in
this case it really does not matter since 0 is a literal.

Hm, I don't know if the evaluation short-circuits. I think not, but
I've never needed to know, and I don't need to know now.

It is easy to check though:
.... print("zero")
.... return 0
........ print("one")
.... return 1
........ print("true")
.... return True
....
one
zero
true
False
zero
one
False

So yes, evaluation does short-curcuit.
 
J

Jussi Piitulainen

Peter said:
Jussi said:
Thibault said:
Hello,

$ python
Python 2.7.4 (default, Sep 26 2013, 03:20:26)
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
1 > 0 == True
False
(1 > 0) == True
True
1 > (0 == True)
True


What am I missing here ?

One or both of the following:
0 == True False
True and False False
1 > 0
True

Or the fact that (1 > 0 == True) means ((1 > 0) and (0 == True)),
where each expression in such a chain is evaluated once, though in
this case it really does not matter since 0 is a literal.

Hm, I don't know if the evaluation short-circuits. I think not, but
I've never needed to know, and I don't need to know now.

It is easy to check though:
... print("zero")
... return 0
...... print("one")
... return 1
...... print("true")
... return True
...
one
zero
true
False
zero
one
False

So yes, evaluation does short-curcuit.

Now I'm experiencing a mild form of information overload. Thanks
anyway :) My guess was wrong.

Now that I think of it, I've implemented a parser and evaluator once
with this kind of chaining, and it may well have short-circuited.
 
D

Dave Angel

Thibault Langlois said:
Hello,

$ python
Python 2.7.4 (default, Sep 26 2013, 03:20:26)
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
What am I missing here ?

T.

You tell us. You supply only half the question, what it does,
without saying what you expected or needed.

I expect you're either confused about comparison chaining or about
what happens when you compare objects of different types.


Doing an ordered comparison between two types is undefined by
default, and not guaranteed to even give the same result between
builds. So the following may give different results on your
2.7.4 than on mine.
5 < "abc"

Python 3 fixes that by throwing an exception. TypeError:
unorderable types

This should solve it, since the first and third expression would
seem to be undefined. Unfortunately there's yet another wrinkle.


For hysterical reasons, True and False are instances of class
bool, which is derived from int. So for comparison purposes
False==0 and True==1. But in my opinion, you should never take
advantage of this, except when entering obfuscation
contests.
 
T

Thibault Langlois

Thibault Langlois said:
Hello,

$ python
Python 2.7.4 (default, Sep 26 2013, 03:20:26)
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.




What am I missing here ?



You tell us. You supply only half the question, what it does,

without saying what you expected or needed.



I expect you're either confused about comparison chaining or about

what happens when you compare objects of different types.





Doing an ordered comparison between two types is undefined by

default, and not guaranteed to even give the same result between

builds. So the following may give different results on your

2.7.4 than on mine.

5 < "abc"



Python 3 fixes that by throwing an exception. TypeError:

unorderable types



This should solve it, since the first and third expression would

seem to be undefined. Unfortunately there's yet another wrinkle.





For hysterical reasons, True and False are instances of class

bool, which is derived from int. So for comparison purposes

False==0 and True==1. But in my opinion, you should never take

advantage of this, except when entering obfuscation

contests.

You are right. I should have given some context.
I am looking at this from the perspective of the teacher that has to explain idiosyncrasies of the language to inexperienced students.
There are two aspects in this example.
1. the equivalence of True/False with integers 1/0 which have pro and cons.
2. the chaining rules of operators. I agree that it may make sense in some cases like x > y > z but when operators are mixed it leads to counter intuitive cases as the one I pointed out.

The recommendations to student are 1) do not assume True == 1 and do not use operator chaining.
 
C

Chris Angelico

The recommendations to student are 1) do not assume True == 1 and do not use operator chaining.

Not "do not use", but "do not misuse". Python's operator chaining is
awesome for bounds checking:

if 3 < x < 20:
print("x is between 3 and 20, exclusive")

You can even, since it short-circuits, do crazy stuff like:

x = random.randrange(30)
if int(input("Min: ")) < x < int(input("Max: ")):
print("It's within those bounds.")

It won't ask for a maximum if it's already failed to be within the
minimum. (Okay, don't do this one. Not good code. Heh.)

But don't use operator chaining when you don't mean it to behave that
way. That's all!

ChrisA
 
R

Roy Smith

Thibault Langlois said:
You are right. I should have given some context.
I am looking at this from the perspective of the teacher that has to explain
idiosyncrasies of the language to inexperienced students.
There are two aspects in this example.
1. the equivalence of True/False with integers 1/0 which have pro and cons.
2. the chaining rules of operators. I agree that it may make sense in some
cases like x > y > z but when operators are mixed it leads to counter
intuitive cases as the one I pointed out.

The recommendations to student are 1) do not assume True == 1 and do not use
operator chaining.

Better than that, do what I do.

1) Assume that you don't have the full operator precedence table
memorized and just parenthesize everything.

2) In cases where the expression is so simple, you couldn't possibly be
wrong, see rule #1.
 
C

Chris Angelico

Better than that, do what I do.

1) Assume that you don't have the full operator precedence table
memorized and just parenthesize everything.

Or:

1a) Assume that you don't have the full operator precedence table
memorized and just look it up, for whichever language you're working
with today. :)

Usually the precedence table will also remind me of operator chaining,
and whether the integer division and modulo operators are backward
(compare REXX and Python with their % and // operators), and anything
else that needs concern.

ChrisA
 
D

Devin Jeanpierre

1) Assume that you don't have the full operator precedence table
memorized and just parenthesize everything.

2) In cases where the expression is so simple, you couldn't possibly be
wrong, see rule #1.

Also, assume you don't have the function definition syntax memorized,
and just define functions. And assume you don't know Python, so just
hire someone else to write your code instead.

-- Devin
 
T

Thibault Langlois

Better than that, do what I do.



1) Assume that you don't have the full operator precedence table

memorized and just parenthesize everything.



2) In cases where the expression is so simple, you couldn't possibly be

wrong, see rule #1.

Agreed !
 
R

Roy Smith

Chris Angelico said:
Or:

1a) Assume that you don't have the full operator precedence table
memorized and just look it up, for whichever language you're working
with today. :)

It's faster to just stick in some extra parens. Not to mention that it
makes the code more clear for everybody reading it later.

Operator precedence is a tricky thing. In part, because it's somewhat
arbitrary, and in part because it changes from language to language.
Using "extra" parens to make my meaning clear (to both the compiler and
other humans who read the code in the future) is a simple technique
which works in all languages.
 
J

Jussi Piitulainen

Roy said:
Better than that, do what I do.

1) Assume that you don't have the full operator precedence table
memorized and just parenthesize everything.

2) In cases where the expression is so simple, you couldn't possibly
be wrong, see rule #1.

There's nothing to parenthesize in x <= y < z = w, unless you mean
something rather weird that is not equivalent anyway (and may not be
compatible with avoiding assumptions like True == 1).

There's not much to remember: the comparison operators are a
semantically coherent class (as far as I can see) and have the same
precedence level somewhere between proper operators (let's call them
that) and and and or and if else[1]. Ok, I'm not quite sure how the
two branches of a conditional expression combine. Rather than find
out, use parentheses, yes:

(x + 1) if c else x == x + (1 if c else 0) == x + bool(c)

I agree about using parentheses when in doubt, but there is some room
here for more education and less doubt. Python gets these right.

[1] Sorry...
 
C

Chris Angelico

It's faster to just stick in some extra parens. Not to mention that it
makes the code more clear for everybody reading it later.

That won't protect you from getting modulo and truncating-division mixed up. :)
Operator precedence is a tricky thing. In part, because it's somewhat
arbitrary, and in part because it changes from language to language.
Using "extra" parens to make my meaning clear (to both the compiler and
other humans who read the code in the future) is a simple technique
which works in all languages.

It's not arbitrary, but there are differences from language to
language. Yes, parens can help, but I would strongly advocate NOT
using them where it's utterly unambiguous:

x = (2*3)+4 # Pointless!

Whether your language works with * before + (the sane way, doing what
we expect from algebra) or purely left to right (the insane way, but
some languages do do that), the parens are superfluous. Don't use 'em!

But if you work with both PHP and any other language that has a ?:
operator, parenthesizing any nesting of them will avoid a PHP
stupidity. Not that that's really any sort of argument here, though.

ChrisA
 
S

Steven D'Aprano

1) Assume that you don't have the full operator precedence table
memorized and just parenthesize everything.

Oh really? Do you actually write stuff like this?

b = ((2*a) + 1)
if (b >= (-1)):
...


I would hope not.

2) In cases where the expression is so simple, you couldn't possibly be
wrong, see rule #1.


Or, you can avoid superstitious responses *wink*

(1) Learn the operator precedences to the best of your ability. It's
not hard, most of it works just like the precedences you're used
to from maths class (remember that?) or in the most intuitively
useful way.

E.g. `1 + x == 2` does the useful thing of calculating 1 + x
before testing for equality, rather than the stupid thing of
calculating x == 2 first then adding it to 1.

(2) When in doubt, use parentheses.

(3) When the expression is complex, a few extra parentheses can
help make it easier to understand. "Seven, plus or minus two"
is (roughly) the number of distinct items the human short-
term memory can hold. Grouping terms together can help reduce
the distinct number of items the reader needs to keep in
short-term memory.

E.g. `x+1 > 0 and y >= 5` is potentially as many as 9 distinct
items to keep in short-term memory. But bracketing some terms
as in `(x+1 > 0) and (y >= 5)` can reduce that down to as few
as two items.

(4) But too many parens obscure the meaning of the expression too. Aim
for a good balance, neither too few nor too many. Your judgement
of the right number of parens is a skill, which will come with
experience.
 
R

Rustom Mody

Oh really? Do you actually write stuff like this?
b = ((2*a) + 1)
if (b >= (-1)):
...
I would hope not.
Or, you can avoid superstitious responses *wink*
(1) Learn the operator precedences to the best of your ability. It's
not hard, most of it works just like the precedences you're used
to from maths class (remember that?) or in the most intuitively
useful way.
E.g. `1 + x == 2` does the useful thing of calculating 1 + x
before testing for equality, rather than the stupid thing of
calculating x == 2 first then adding it to 1.
(2) When in doubt, use parentheses.
(3) When the expression is complex, a few extra parentheses can
help make it easier to understand. "Seven, plus or minus two"
is (roughly) the number of distinct items the human short-
term memory can hold. Grouping terms together can help reduce
the distinct number of items the reader needs to keep in
short-term memory.
E.g. `x+1 > 0 and y >= 5` is potentially as many as 9 distinct
items to keep in short-term memory. But bracketing some terms
as in `(x+1 > 0) and (y >= 5)` can reduce that down to as few
as two items.
(4) But too many parens obscure the meaning of the expression too. Aim
for a good balance, neither too few nor too many. Your judgement
of the right number of parens is a skill, which will come with
experience.



(5) use APL -- all ordinary operators group right to left and at the same
precedence level
 
R

Roy Smith

There's nothing to parenthesize in x <= y < z = w
Hmm....
File "<stdin>", line 1
SyntaxError: can't assign to comparison

I don't think any number of parentheses will help that :)
 
R

Roy Smith

Oh really? Do you actually write stuff like this?

b = ((2*a) + 1)

Well, OK, I exaggerated a bit. Multiplication binds stronger than addition in any language I've ever used, so I assume I know that one. But not much beyond that.
if (b >= (-1)):

No, I wouldn't use either set of parens their either. But, if I have any doubt at all, I rather than look it up, I just put parens. And my threshold for doubt is pretty low.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top