By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,058 Members | 1,217 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,058 IT Pros & Developers. It's quick & easy.

True inconsistency in Python

P: n/a
There seems to be an inconsistency here:

Python 2.3.2 (#1, Oct 3 2003, 19:04:58)
[GCC 3.2 20020903 (Red Hat Linux 8.0 3.2-7)] on linux2
1 == True True 3 == True False if 1: print "true" ....
true if 3: print "true" ....
true
0 == False True -1 == False False -1 == True False if -1: print "true" ....
true if -2: print "true" ....
true
if None: .... print "hello"
.... x = None
x == None True x == True False x == False False x <> True True x <> False True None == True False None == False

False
Historically Python has allowed <> 0 to equal true in evaluations. Now
<> 0 still evaluates to true in evaluations. However it doesn't equal
True. They are not interchangable. (Same with empty lists, etc.)
Assuming the old behavior is desired, programmers need to be careful
not to compare a variable with True as in:

if var == True: # only works if var is 1
blah

' Must use:

if var: # works if var is not 0
blah

Is this inconsistency going to be resolved in the future?

How? (Will <>0 == True or will <>0 <> true or will it be resolved some
other way that I'm too opaque to see? :-)

It seems that maybe Python should throw a warning (perhaps if a flag is
set) any time it bumps into code comparing a variable to True or False.
It's pretty subtle and would easily throw a newbie.

Of course, according to the above logic, if 1 == true and 2 == true,
then 1 == 2! Thankfully this doesn't work in Python. Python is magic.
I love the magic but it creates some interesting inconsistencies.

Scott
Jul 18 '05 #1
Share this Question
Share on Google+
46 Replies


P: n/a
Scott Chapman wrote:
Historically Python has allowed <> 0 to equal true in evaluations.
Now
<> 0 still evaluates to true in evaluations. However it doesn't equal
True. They are not interchangable. (Same with empty lists, etc.)


That's because the proper way to test for truth does not use the True
value at all. It is this:

if x:
...

not this:

if x == True:
...

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ Life is a predicament which precedes death.
\__/ Henry James
Jul 18 '05 #2

P: n/a
Scott Chapman wrote:

if var == True: # only works if var is 1
blah

' Must use:

if var: # works if var is not 0
blah


Just because something isn't True doesn't mean it isn't true.

David

Jul 18 '05 #3

P: n/a
On Wed, 12 Nov 2003 19:42:27 -0800, Scott Chapman wrote:
There seems to be an inconsistency here:


Yes. The inconsistency is in expecting all Boolean truths to be the
same value.

The object True will evaluate as a Boolean truth. The object False will
not evaluate as a Boolean truth. This doesn't mean that there are no
other values that will or won't evaluate as Boolean truth.

You many want to read the PEP that led to the creation of the 'bool'
type (and True and False objects):

<http://www.python.org/peps/pep-0285.html>

In short: Testing the Boolean truth of an expression is done with 'if',
not with value-comparison operators.

--
\ "bash awk grep perl sed, df du, du-du du-du, vi troff su fsck |
`\ rm * halt LART LART LART!" -- The Swedish BOFH, |
_o__) alt.sysadmin.recovery |
Ben Finney <http://bignose.squidly.org/>
Jul 18 '05 #4

P: n/a
On Wed, 12 Nov 2003 19:42:27 -0800, Scott Chapman
<sc********@mischko.com> wrote:

Historically Python has allowed <> 0 to equal true in evaluations. Now
<> 0 still evaluates to true in evaluations. However it doesn't equal
True.


a = (2 != 0)
a == True

True

Seems to work for me. Am I missing something?

The only thing that surprises me in all of this is the "if var:"
evaluating to true for numbers other than 1. That's new to me, I
would have expected an exception in that case. But it still makes
since if I look at it as a shortcut for "if (var != 0):". This
only proves I'm still relatively new to Python I think.

_Ron Adam
Jul 18 '05 #5

P: n/a
On Thu, 13 Nov 2003 06:26:09 GMT, Ron Adam wrote:
The only thing that surprises me in all of this is the "if var:"
evaluating to true for numbers other than 1. That's new to me, I
would have expected an exception in that case.


Python has only recently gained a Boolean type ('bool').

<http://www.python.org/peps/pep-0285.html>

Before that, Boolean logic was done with integer values. Zero equated
to Boolean false, non-zero equated to Boolean true; and the default
Boolean true value was simply the integer 1.

This conflation of types is confusing, and (like many other languages)
Python has now "grown a Boolean type" to distinguish integer 0 and 1
from Boolean False and True. However, the previous behaviour is still
supported -- for how long, I don't know.

--
\ "Injustice is relatively easy to bear; what stings is justice." |
`\ -- Henry L. Mencken |
_o__) |
Ben Finney <http://bignose.squidly.org/>
Jul 18 '05 #6

P: n/a
On 13 Nov 2003 17:08:13 +1050, Ben Finney
<bi****************@and-benfinney-does-too.id.au> wrote:
On Thu, 13 Nov 2003 06:26:09 GMT, Ron Adam wrote:
The only thing that surprises me in all of this is the "if var:"
evaluating to true for numbers other than 1. That's new to me, I
would have expected an exception in that case.


Python has only recently gained a Boolean type ('bool').

<http://www.python.org/peps/pep-0285.html>

Before that, Boolean logic was done with integer values. Zero equated
to Boolean false, non-zero equated to Boolean true; and the default
Boolean true value was simply the integer 1.

This conflation of types is confusing, and (like many other languages)
Python has now "grown a Boolean type" to distinguish integer 0 and 1
from Boolean False and True. However, the previous behaviour is still
supported -- for how long, I don't know.


That's good to know. I've always explicitly defined my bool values as
0 and 1 so it's never been a problem.

Thanks for the PEP link, it was informative.

_Ron Adam
Jul 18 '05 #7

P: n/a
Ron Adam:
The only thing that surprises me in all of this is the
"if var:" evaluating to true for numbers other than 1.
That's new to me, I would have expected an
exception in that case. But it still makes since if I
look at it as a shortcut for "if (var != 0):". This only
proves I'm still relatively new to Python I think.


It's handy, and natural in many real life situations, to treat any nonzero
value as "true". For example:

Do you have any money in your wallet?

Do you have children?

I could ask how much money or how many children you have, but if I just ask
the yes-or-no question, you'll naturally answer "yes" for any nonzero value.

Of course, if you have children, you won't have money, but that's a separate
problem...

-Mike
Jul 18 '05 #8

P: n/a
Scott Chapman wrote:

if var == True: # only works if var is 1
blah

' Must use:

if var: # works if var is not 0
blah


there's the equivalent, and more explicit :

if bool(var)==True : blah

Jul 18 '05 #9

P: n/a
On Wed, 12 Nov 2003 21:21:03 -0800, Erik Max Francis <ma*@alcyone.com>
wrote:
Scott Chapman wrote:
Historically Python has allowed <> 0 to equal true in evaluations.
Now
<> 0 still evaluates to true in evaluations. However it doesn't equal
True. They are not interchangable. (Same with empty lists, etc.)


That's because the proper way to test for truth does not use the True
value at all. It is this:

if x:
...

not this:

if x == True:
...

Sort of like (stretchy) saying that if these are both True:
"a snake is green"
"a pearl is white"
that they are the same as each other.
They are both true, yet unrelated. You can say:
if "a snake is green": print 1
if "a pearl is white": print 2
and the prints would happen, but if you said
if "a snake is green" == "a pearl is white": print 3
the print would not happen.

--dang
Jul 18 '05 #10

P: n/a
Borcis wrote:
Scott Chapman wrote:

if var == True: # only works if var is 1
blah

' Must use:

if var: # works if var is not 0
blah


there's the equivalent, and more explicit :

if bool(var)==True : blah


Why stop there? If adding one useless and redundant check is
better, surely having more will be merrier and merrier...:

if ( bool(var) == True) == True: doubleblah

oh wait, we should add ANOTHER level of uselessness...:

if (( bool(var) == True) == True) == True: tripleblah

oh wait...
"if var:" is the Pythonic way. You could argue that each
level of "== True" makes it ``more explicit'', but I just
consider them all equally silly in their utter redundancy.

[[ we TOLD Guido people would start on this absurd path, when
he added bool, True, and False, but he wouldn't listen...
]]
Alex

Jul 18 '05 #11

P: n/a
Ben Finney wrote:
...
This conflation of types is confusing, and (like many other languages)
Python has now "grown a Boolean type" to distinguish integer 0 and 1
from Boolean False and True. However, the previous behaviour is still
supported -- for how long, I don't know.


I've never heard of any plans (not even for the totally mythical
"Python 3000") to remove or even deprecate Python's extremely useful
and practical feature that:
-- any value can be used as a true-or-false condition,
-- zero numbers, empty containers, and user-coded objects defining
__nonzero__ (or else __len__) and returning 0 are taken as false,
-- all other values are taken as true.
Alex

Jul 18 '05 #12

P: n/a
Ben Finney
You many want to read the PEP that led to the creation of the 'bool'
type (and True and False objects):


.... or vise versa

Emile van Sebille
em***@fenx.com
Jul 18 '05 #13

P: n/a
Scott Chapman wrote:
...
It seems that maybe Python should throw a warning (perhaps if a flag is
set) any time it bumps into code comparing a variable to True or False.


It's a bit hard to do it just for variables, but doing it for _any_
comparison would _almost_ be reasonable -- testing if something
"== True" is hardly ever sensible. Unfortunately "a == b" CAN
be perfectly sensible and either or both of the variables MIGHT
just happen to be set to True.

However, this looks to me like a good suggestion for PyChecker
and the like, which should be able to catch and flag the actual
explicit use or the constant True in code involving == or != ...
Alex

Jul 18 '05 #14

P: n/a
Alex Martelli wrote:
(about x vs. bool(x))
[[ we TOLD Guido people would start on this absurd path, when
he added bool, True, and False, but he wouldn't listen...
]]


What do double square brackets mean?

(btw, I _do_ use bool ocasionally: I implemented an anytrue() function
using sum([bool(i) for i in L]), is this wrong?)

Gerrit.

--
128. If a man take a woman to wife, but have no intercourse with her,
this woman is no wife to him.
-- 1780 BC, Hammurabi, Code of Law
--
Asperger Syndroom - een persoonlijke benadering:
http://people.nl.linux.org/~gerrit/
Kom in verzet tegen dit kabinet:
http://www.sp.nl/

Jul 18 '05 #15

P: n/a
Borcis wrote:
there's the equivalent, and more explicit :

if bool(var)==True : blah


The explicitness here does not gain you anything. In a truth context,
x, bool(x), and bool(x) == True are all precisely identical. There is
absolutely no value gained by writing bool(x) == True instead of just x.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ The golden rule is that there are no golden rules. -- George
Bernard Shaw
Jul 18 '05 #16

P: n/a
On Thu, 13 Nov 2003 00:19:31 -0800, "Michael Geary"
<Mi**@DeleteThis.Geary.com> wrote:
Ron Adam:
The only thing that surprises me in all of this is the
"if var:" evaluating to true for numbers other than 1.
That's new to me, I would have expected an
exception in that case. But it still makes since if I
look at it as a shortcut for "if (var != 0):". This only
proves I'm still relatively new to Python I think.


It's handy, and natural in many real life situations, to treat any nonzero
value as "true". For example:

Do you have any money in your wallet?

Do you have children?

I could ask how much money or how many children you have, but if I just ask
the yes-or-no question, you'll naturally answer "yes" for any nonzero value.

Of course, if you have children, you won't have money, but that's a separate
problem...

-Mike


That makes since, Thanks for clarifying this.

I learned boolean logic as part of a computer tech degree back in
early 80's. Binary logic circuits use only 0 and 1. So it's the way
I think when dealing with bool type.

_Ron Adam

Jul 18 '05 #17

P: n/a
Gerrit Holl <ge****@nl.linux.org> wrote in message news:<ma************************************@pytho n.org>...

(btw, I _do_ use bool ocasionally: I implemented an anytrue() function
using sum([bool(i) for i in L]), is this wrong?)

Gerrit.

--
128. If a man take a woman to wife, but have no intercourse with her,
this woman is no wife to him.
-- 1780 BC, Hammurabi, Code of Law


It does not shortcut, i.e. it creates the full list. For the rest, it
is a matter of personal opinion if this idea is considered cool or
an abuse of sum. I personally, will propend for the latter, but since
we don't have yet an anytrue function in the library, for the moment it
can be tolered). Just my 0.02 E.

Michele
Jul 18 '05 #18

P: n/a

"Ben Finney" <bi****************@and-benfinney-does-too.id.au> wrote
in message news:sl*******************************@iris.polar. local...
This conflation of types is confusing,
but very useful
and (like many other languages)
Python has now "grown a Boolean type" to distinguish integer 0 and 1
from Boolean False and True. However, the previous behaviour is still supported -- for how long, I don't know.


When bool was introduced, Guido promised that is would always remain a
subtype of int. Crippling usefulness in the name of mathematical
purity is not on the table.

Terry J. Reedy
Jul 18 '05 #19

P: n/a

"Scott Chapman" <sc********@mischko.com> wrote in message
news:ma************************************@python .org...
There seems to be an inconsistency here:


In regard to logic, the current Python implementation acts just as
specified in the manaul, which is written as intended. This is the
only consistency relevant to Python.

In math, an inconsistent set of premises is one from which one can
derive both true and false. Python as delivered has no such
inconsistency in that sense either. bool(object) is either True or
False for every Python object except possibly for instances of a user
class with the appropriate special method mangled either by accident
or perverse intention.

In static math, x = x+1 is read as x == x+1, which is usually false.
But programming is not mathematics.

If you merely meant "Python is not consistent with my expectations"
then I suppose you are right. If that really bothers you, I suspect
you know the realistic remedy ;-).

Terry J. Reedy
Jul 18 '05 #20

P: n/a
Gerrit Holl wrote:
Alex Martelli wrote:
(about x vs. bool(x))
[[ we TOLD Guido people would start on this absurd path, when
he added bool, True, and False, but he wouldn't listen...
]]
What do double square brackets mean?


"Inline footnote" or the like;-). I do like to pep up my posts
despite the limitations of plain ascii...

(btw, I _do_ use bool ocasionally: I implemented an anytrue() function
using sum([bool(i) for i in L]), is this wrong?)
Not wrong, just potentially a bit slow for very large L's, but for
your applications you may not care. Compare:
[alex@lancelot tmp]$ timeit.py -c -s'xs=[0]*999' -s' def anytrue_sc(L):
for i in L:
if i: return True
else:
return False
def anytrue_ns(L):
return sum([ bool(i) for i in L ])
' 'anytrue_sc(xs)' 1000 loops, best of 3: 200 usec per loop

and the same with 'anytrue_ns(xs)' instead,

1000 loops, best of 3: 1.26e+03 usec per loop

while, also, with 'anytrue_sc([1]+xs]':

10000 loops, best of 3: 22 usec per loop

while with 'anytrue_ns([1]+xs]':

1000 loops, best of 3: 1.29e+03 usec per loop
So, on a 1000-long list, you may be slowing things down by 6 to
60 times, depending on where (if anywhere) the first true item
of L might be, by using the "clever" bool rather than the plain
good old loop-with-shortcircuit.

Now, for some people "one-liners" (which you could write the _ns
version as; the _sc version can't be less than 4 lines) are much
more important than speed or elementary-clarity. For those
people, I suggest an approach that's only a BIT slower than the
simplest and most obvious one:

[alex@lancelot tmp]$ timeit.py -c -s'xs=[0]*999' -s'import itertools as it import operator
def anytrue_it(L):
return list(it.islice(it.dropwhile(operator.not_, L),1))
' 'anytrue_it(xs)'

1000 loops, best of 3: 310 usec per loop

and with 'anytrue_it([1]+xs)', 28 usec per loop. Now, you have
bounded your performance loss to 30-50% when compared to the simplest
approach, and one can of course pull out all the stops...:

[alex@lancelot tmp]$ timeit.py -c -s'xs=[0]*999' -s'import itertools as it
import operator
def anytrue_it(L, slice=it.islice, drop=it.dropwhile, not_=operator.not_):
return list(slice(drop(not_, L),1))
' 'anytrue_it(xs)'
1000 loops, best of 3: 270 usec per loop

to reach a 35%-or-so max loss of performance in this case.

Plus, it's much cooler for the purpose of making your friends' heads
spin with admiration for your wizardry, of course;-).
Alex

Jul 18 '05 #21

P: n/a
Scott Chapman <sc********@mischko.com> wrote:

Historically Python has allowed <> 0 to equal true in evaluations. Now
<> 0 still evaluates to true in evaluations. However it doesn't equal
True. They are not interchangable. (Same with empty lists, etc.)
Python is certainly not the only language in which this occurs. Many are
the C programmers who have been burned by:

int SomeFunction();
...
if( SomeFunction == TRUE )
{
}

Visual Basic has exactly the same problem. Further, until very recently,
True in VB actually evaulated to -1, so even comparing to "1" would fail.

This should not be a surprise. Booleans should be thought of as enumerated
integral types.
Assuming the old behavior is desired, programmers need to be careful
not to compare a variable with True as in:

if var == True: # only works if var is 1
blah


Your statement is absolutely true. End of story.
--
- Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.
Jul 18 '05 #22

P: n/a
Tim Roberts wrote:
Python is certainly not the only language in which this occurs. Many
are
the C programmers who have been burned by:

int SomeFunction();
...
if( SomeFunction == TRUE )
{
}
I think you're getting burned by something else, there :-).
Visual Basic has exactly the same problem.
It's not a problem, explicitly comparison with a Boolean literal,
whether or not Booleans are not distinct types (Lisp, C89), are distinct
types with implicit conversion (C++, Python), or are distinct types in
which implicit conversions are disallowed (Java) is completely
superfluous. The proper way to test whether an expression is true is

if (expression)
...

What is the point of the explicit test with the true constant? What
about the result of _that_ comparison, shouldn't that be tested with
true as well -- ((expression == TRUE) == TRUE)? But what about _that_
result, shouldn't it be tested too?

Explicit comparison with the true constant (or false constant)
necessarily degenerates into complete uselessness.
Further, until very
recently,
True in VB actually evaulated to -1, so even comparing to "1" would
fail.


That's because in traditional BASIC, "true" is all-bits on. The true
constant wasn't 1 in the first place.
Assuming the old behavior is desired, programmers need to be careful
not to compare a variable with True as in:

if var == True: # only works if var is 1
blah


Your statement is absolutely true. End of story.


It's true in that that might cause a problem, but it's not true that
that's undesirable language behavior. It's programmer error -- in any
language that has a Boolean true (or false) literal.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ So little time, so little to do.
-- Oscar Levant
Jul 18 '05 #23

P: n/a
>Explicit comparison with the true constant (or false constant)
necessarily degenerates into complete uselessness.


(For those just joining us, this statement was made about all languages, not
just Python.)

I'm not so sure about that. In most languages (including Python), 'false' is
guaranteed to be only one value (usually zero), therefore comparing against it
poses no problem. I assume you're saying that doing so isn't problematic in any
way, it's just pointless.

Well, actually, some coding standards suggest you always compare against false.
This is so the code is slightly more clear, and "!= false" avoids the pitfall
that "== true" has. The problem of course is that some unwitting maintenance
programmer may decide that "== true" os more clear than "!= false", not
realizing it is wrong...which is why all maintenance programmers should read
programming standards. :) We can't program in baby C just for them, after all,
but we shouldn't make things unnecessarily difficult for them either, but I
think we have bigger things to worry about if a maintenance programmer fails to
understand such a simple concept after being told about it.

Now of course any idiot C (or C++, or Java) programmer knows that these two are
equivalent:

if(blah != false)
do_blah();

if(blah)
do_blah();

But if whatever goes in "blah" is really long (and often it is), you very
quickly see what is being compared: it's a straight boolean comparison, whereas
with the second you have to look at the whole thing, find no comparison
operator, and go, "oh, there's no explicit comparison so it's obviously an
implicit straight boolean comparison". This is especially valuable in really
long 'if' statements, such as one might want for an inverse parser (don't worry
if you don't know what one is). The idea is if you compare against 'false' all
the time, you won't forget it when it would actually give the code more
clarity.

One standard which suggests this is the one Steve Maguire proposes in the book
Writing Solid Code. This is probably the best book on C coding guidelines that
I've ever read, despite it being written by a Microsoft programmer. ;) Although
much of it is specific to C, a lot of the concepts apply to other languages,
including Python.

However, comparing against a boolean is discouraged in Python (but your
argument wasn't about Python specifically), so I wouldn't do it in Python: when
in Rome, do as the Romans do. Although, as a last thought, it should be
relatively easy to make it so that True returns '1' in any comparison except
against 0. A class would be able to do this easily by overriding __cmp__:

def true_class(bool):
def __cmp__(self, other):
if other:
return 1
else:
return 0

True = true_class()

(of course this class definition would be tweaked to make it a singleton)
I'm assuming there's a good reason for not doing it this way (or in an
equivalent fashion), though...what else might we add to this discussion?

- Kef

Jul 18 '05 #24

P: n/a
Tim Roberts fed this fish to the penguins on Sunday 16 November 2003
23:58 pm:

Visual Basic has exactly the same problem. Further, until very
recently, True in VB actually evaulated to -1, so even comparing to
"1" would fail.

This should not be a surprise. Booleans should be thought of as
enumerated integral types.
Then there is VMS, in which odd return codes would evaluate to true
and even return codes to false (odd codes being "info"/"success", even
codes being "error"/"warning"). ie; 1, 3, 5, ... are "true"; 0, 2, 4
.... are "false".

-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Bestiaria Home Page: http://www.beastie.dm.net/ <
Home Page: http://www.dm.net/~wulfraed/ <


Jul 18 '05 #25

P: n/a
On Mon, 17 Nov 2003 00:19:11 -0800, Erik Max Francis <ma*@alcyone.com>
wrote:
Tim Roberts wrote:
Python is certainly not the only language in which this occurs. Many
are
the C programmers who have been burned by:

int SomeFunction();
...
if( SomeFunction == TRUE )
{
}
I think you're getting burned by something else, there :-).
Visual Basic has exactly the same problem.


It's not a problem, explicitly comparison with a Boolean literal,
whether or not Booleans are not distinct types (Lisp, C89), are distinct
types with implicit conversion (C++, Python), or are distinct types in
which implicit conversions are disallowed (Java) is completely
superfluous. The proper way to test whether an expression is true is

if (expression)
...

To me the usefulness of using True and False is that it is defined to
values consistent with the programming language that you are using.
So using them to assign x = True, or x = False. insures that when I
do:

x = True
if x:
....

So I get consistent results for the language and platform I'm using
now and in the future. If down the road someone decided to make True
= 3, and False = -5, and they change the language so that any boolean
comparisons return 3 and -5 respectively, my use of True and False
will still work. If I tested for 1 or 0 using the 'if x:' method,
then my program will break.

x = 1
if x: # returned value undefined, x is not 3 or -5

So I do an explicit test 'if (x=1)' to make sure it will work even if
'True' gets redefined.

So we should either use explicit comparisons of values, or use only
True and False, but not mix them.


What is the point of the explicit test with the true constant? What
about the result of _that_ comparison, shouldn't that be tested with
true as well -- ((expression == TRUE) == TRUE)? But what about _that_
result, shouldn't it be tested too?

Explicit comparison with the true constant (or false constant)
necessarily degenerates into complete uselessness.
Further, until very
recently,
True in VB actually evaulated to -1, so even comparing to "1" would
fail.


That's because in traditional BASIC, "true" is all-bits on. The true
constant wasn't 1 in the first place.
>Assuming the old behavior is desired, programmers need to be careful
>not to compare a variable with True as in:
>
>if var == True: # only works if var is 1
> blah


Your statement is absolutely true. End of story.


It's true in that that might cause a problem, but it's not true that
that's undesirable language behavior. It's programmer error -- in any
language that has a Boolean true (or false) literal.

It looks to me that 'True' in python is a combination of the boolean
binary logic of 1 or 0, and as an "exists" test of 0 or not 0.

If python had an exists operator, you could do.

if x exists:
'do something'

This could serve two options also... does the object exist? or does
a value exist where the value is not equal to zero or None. There
would need to be a syntax difference between the two.

Using the 'if x:' form does this for values and is clear enough. So
using an 'exists()' function to check for the presence of an object
would be useful if there isn't a simple way to do it already. Right
now it you do this without first assigning a value to x you get:
if x: pass
Traceback (most recent call last):
File "<pyshell#2>", line 1, in -toplevel-
if x:
NameError: name 'x' is not defined


There is an os.path.exists() function for checking if a file path
exists. A more general exists() function or method my be useful and
still be consistent with it.

With pythons dynamic variables, I think an exists function would be
useful to check if an object exists. And to use 'if x:' to check if
a (value!=0) exists. It's clear what is being tested for from the
context.

I can't do:

def exists(object):
try object:
return True
return False

if not exists(object):
object = 0
This generates a not defined error if object isn't defined when exists
is called.
So I have to do:
try:
if object:
exist = True
except:
exist = False
if not exist:
object = 0

That can be shortened to:

try:
if object:
pass
except:
object = 0

This isn't to bad, but I would prefer something like,

if not object.exists: # does the abject already exist?
object = 0 # if not, create and set initial value
# else use the existing value

I think I diverged from True or False a bit here. And I'm not sure if
this functionality already exists or not?

_Ron Adam









There's probably a way to do this in python already.


Jul 18 '05 #26

P: n/a
KefX:
Well, actually, some coding standards suggest you always compare against false. This is so the code is slightly more clear, and "!= false" avoids the pitfall that "== true" has. The problem of course is that some unwitting maintenance programmer may decide that "== true" os more clear than "!= false", not
realizing it is wrong...which is why all maintenance programmers should read programming standards. :) We can't program in baby C just for them, after all, but we shouldn't make things unnecessarily difficult for them either, but I think we have bigger things to worry about if a maintenance programmer fails to understand such a simple concept after being told about it.

Now of course any idiot C (or C++, or Java) programmer knows that these two are equivalent:

if(blah != false)
do_blah();

if(blah)
do_blah();

But if whatever goes in "blah" is really long (and often it is), you very
quickly see what is being compared: it's a straight boolean comparison, whereas with the second you have to look at the whole thing, find no comparison
operator, and go, "oh, there's no explicit comparison so it's obviously an
implicit straight boolean comparison". This is especially valuable in really long 'if' statements, such as one might want for an inverse parser (don't worry if you don't know what one is). The idea is if you compare against 'false' all the time, you won't forget it when it would actually give the code more
clarity.


That strikes me as a really bad practice, in C, Python, or any language with
a similar if statement. Code should read the way people think, and people
don't tack on "!= false" when they make decisions based on conditions.

Which would you say: "If you're hungry, eat!" or "If your hunger is not
equal to false, eat!"

So which is more clear:

if( hungry )
eat();

or:

if( hungry != false )
eat();

It's just as bad when you want to make the opposite test. Do you say, "If
you're not hungry, don't eat!" or "If your hunger is equal to false, don't
eat!"

So do you code:

if( ! hungry )
dontEat();

or:

if( hungry == false )
dontEat();

(For those not familiar with C, "!" is the logical not operator and is
pronounced "not".)

I don't buy the argument that "you have to look at the whole thing, find no
comparison operator, and go, 'oh, there's no explicit comparison so it's
obviously an implicit straight boolean comparison.'" You *always* have to
look at the whole thing, and an if statement always tests its entire
argument for truth or falsity. Adding an explicit "!= false" or "== false"
simply adds noise and reduces clarity.

Comparing against a boolean isn't discouraged in Python because of some
arbitrary cultural preference, it's discouraged because it makes code harder
to read and understand.

-Mike
Jul 18 '05 #27

P: n/a
KefX wrote:
I'm not so sure about that. In most languages (including Python),
'false' is
guaranteed to be only one value (usually zero), therefore comparing
against it
poses no problem. I assume you're saying that doing so isn't
problematic in any
way, it's just pointless.
Yes. The same cascade into insanity developes. If you're testing for
falsity, why not write x == false? But what about _that_ test,
shouldn't that be (x == false) != false? And _that_ test ...
Well, actually, some coding standards suggest you always compare
against false.
My point is that any such coding standard is dumb.
But if whatever goes in "blah" is really long (and often it is), you
very
quickly see what is being compared: it's a straight boolean
comparison, whereas
with the second you have to look at the whole thing, find no
comparison
operator, and go, "oh, there's no explicit comparison so it's
obviously an
implicit straight boolean comparison".


I don't see the value in this. The expression in an if statement is
treated as a Boolean expression. In languages where there isn't a
distinct Boolean type without implicit conversions (like your example,
C89), it doesn't matter whether you put the explicit comparison there or
not. However long the expression is, I don't see how adding `== true'
at the end makes it more clear. It's a Boolean test, what's to make
explicit?

All including the explicit test there does is make other programmers
wonder if you've lost your mind, and admit the possibility of you making
the type of error we've been discussing (x == True) where True is a
solitary constant in a much larger world of Booleans which evaluate as
true. Trying to correct that error, you end up with monstrosities such
as bool(x) == True or operator.truth(x) == True (or the equivalent in
other languages), and after some point it should dawn on the programmer
that the explicit True test is pointless.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ Why don't you grow up for crying out loud?
-- Capt. Benjamin "Hawkeye" Pierce
Jul 18 '05 #28

P: n/a
Ron Adam wrote:
To me the usefulness of using True and False is that it is defined to
values consistent with the programming language that you are using.
I agree, insofar as the value of True and False as constants is that now
have values set aside which mean _nothing_ but their Boolean values.
This is very helpful for writing self-documenting code, something which
I've always been a strong supporter of. If I have code where 0 or 1
gets assigned to a variable, I'm going to have to look at the whole
block to tell precisely what that's being used for: Is it a counter
variable, a three-state value (say, -1, 0, and +1), is it an enumerated
value type, or is it a Boolean? If I'm scanning code and I see

x = True

then I know right away that what I'm looking at is a variable used as a
Boolean. (Of course, in proper self-documenting code, the variable
would be named something more helpful than `x', but you see my point.)
So using them to assign x = True, or x = False. insures that when I
do:

x = True
if x:
....

So I get consistent results for the language and platform I'm using
now and in the future. If down the road someone decided to make True
= 3, and False = -5, and they change the language so that any boolean
comparisons return 3 and -5 respectively, my use of True and False
will still work. If I tested for 1 or 0 using the 'if x:' method,
then my program will break.


While this may be true in some sense, I don't think this is a powerful
argument for using True/False. The chances of this happening are
utterly remote, since it would break practically all code. (Obviously
you weren't suggesting it was a real possibility given your choices of
the alternate constants, but still.)

I don't consider insulation from something utterly implausible happening
very persuasive, since I'm not worried about that utterly implausible
thing happening. I find explicit Boolean constants available for
writing self-documenting code much more compelling.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ Why don't you grow up for crying out loud?
-- Capt. Benjamin "Hawkeye" Pierce
Jul 18 '05 #29

P: n/a
On Mon, 17 Nov 2003 11:24:54 -0800, Erik Max Francis <ma*@alcyone.com>
wrote:
Ron Adam wrote:
To me the usefulness of using True and False is that it is defined to
values consistent with the programming language that you are using.
I agree, insofar as the value of True and False as constants is that now
have values set aside which mean _nothing_ but their Boolean values.
This is very helpful for writing self-documenting code, something which
I've always been a strong supporter of. If I have code where 0 or 1
gets assigned to a variable, I'm going to have to look at the whole
block to tell precisely what that's being used for: Is it a counter
variable, a three-state value (say, -1, 0, and +1), is it an enumerated
value type, or is it a Boolean? If I'm scanning code and I see

x = True

then I know right away that what I'm looking at is a variable used as a
Boolean. (Of course, in proper self-documenting code, the variable
would be named something more helpful than `x', but you see my point.)
So using them to assign x = True, or x = False. insures that when I
do:

x = True
if x:
....

So I get consistent results for the language and platform I'm using
now and in the future. If down the road someone decided to make True
= 3, and False = -5, and they change the language so that any boolean
comparisons return 3 and -5 respectively, my use of True and False
will still work. If I tested for 1 or 0 using the 'if x:' method,
then my program will break.


While this may be true in some sense, I don't think this is a powerful
argument for using True/False. The chances of this happening are
utterly remote, since it would break practically all code. (Obviously
you weren't suggesting it was a real possibility given your choices of
the alternate constants, but still.)


No, this one point is not the only reason, I made the example a
little farfetched to demonstrate a concept I think is a valid reason
to have 'True' and 'False' as Constants. Their actual internal
values shouldn't be relevant or depended on. They need to be constant
to how a boolean expression evaluates in the language they are in.

In python you can change the value of True, or set True to point to
something different.

For example you can do this.
True True False False True = False
True False

Now all bets are off.... To be sure that True is True and False is
False, we need to put in explicit definitions into our programs.
True = True
True False

Ooops.... <wink> so much for that. So we need to do it this way.
True = (1==1)
True

True
True should be a Constant and always equal to (1==1) and False should
always be equal to (1!=1). It's not, so we need to be careful
using True.

x = True

"lots of code"

True = 3 # as a programming error.

"more code"

if (x == True): # evaluates as False!
print True
else:
print False
or possibly this.....
True = 0 # another programming error

"lost of code"

x = True
if x: # evaluates as False again!
print True
else:
print False


I don't consider insulation from something utterly implausible happening
very persuasive, since I'm not worried about that utterly implausible
thing happening. I find explicit Boolean constants available for
writing self-documenting code much more compelling.


The above is much less implausible. Do you agree?
_Ronald Adam
Jul 18 '05 #30

P: n/a
Ron Adam wrote:
No, this one point is not the only reason, I made the example a
little farfetched to demonstrate a concept I think is a valid reason
to have 'True' and 'False' as Constants. Their actual internal
values shouldn't be relevant or depended on. They need to be constant
to how a boolean expression evaluates in the language they are in.
In effect you are arguing against the point you were trumpeting earlier.
If we take your argument to its logical conclusion, that means that True
and False may be modified (accidentally or intentionally) by a
programmer and so we should never rely on its value. Which means that
you should never use True or False.

Of course, the fact that any builtin can be overridden sort of dulls
that point, since that means you shouldn't use _anything_.
In python you can change the value of True, or set True to point to
something different.

For example you can do this.
True True False False True = False
True False

Now all bets are off....
Sure, but that's got nothing to do with True or False as specific
entities. This can happen with any builtin function, even the
type/converters:
int = float
float = str
str = lambda x: None
file = 'elif'


Since these can happen with any of these things, singling out True and
False doesn't make sense.
True should be a Constant and always equal to (1==1) and False should
always be equal to (1!=1). It's not, so we need to be careful
using True.
I really don't see your point here. It's true that someone malicious or
insufficiently careful can override the values of "constants" like True
or False. Of course that's true with all the other builtin functions,
constants, and types, so that point really has nothing to do with True
or False.

So how does this point relate to explicit testing against the values of
True or False
The above is much less implausible. Do you agree?


Yes, but it is still programmer error. If `str' got overridden -- quite
frankly, a much more common programmer error -- you'd have the same
problem, and it has nothing to do with Booleans.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ And there inside our private war / I died the night before
-- Sade
Jul 18 '05 #31

P: n/a
Yes. The same cascade into insanity developes. If you're testing for
falsity, why not write x == false? But what about _that_ test,
shouldn't that be (x == false) != false? And _that_ test ...

Of course the point that those tests aren't any less redundant from the
language perspective is valid. But they're a heck of a lot more redundant to a
human reader than a single "== false".
My point is that any such coding standard is dumb.
In my experience, every coding standard has things one would call "dumb". But
not everybody calls the same thing dumb. (I remember some people objecting to
my assertion that "assert" should be used as often to check parameters in C
code when defining functions...I still don't get how that's dumb. Some even
claimed that assert was a C++ thing!)
But if whatever goes in "blah" is really long (and often it is), you
very
quickly see what is being compared: it's a straight boolean
comparison, whereas
with the second you have to look at the whole thing, find no
comparison
operator, and go, "oh, there's no explicit comparison so it's
obviously an
implicit straight boolean comparison".


I don't see the value in this. The expression in an if statement is
treated as a Boolean expression. In languages where there isn't a
distinct Boolean type without implicit conversions (like your example,
C89), it doesn't matter whether you put the explicit comparison there or
not. However long the expression is, I don't see how adding `== true'
at the end makes it more clear.


What if the expression is 37 lines long? (Can't happen? I'm LOOKING at such an
example!) Fishing out the main comparison in such a monster isn't always the
easiest thing to do. Of course I'm exaggerating here, since we usually don't
write 37-line expressions, but still.
It's a Boolean test, what's to make
explicit?
Yes, all tests are boolean tests in the sense that they evaluate to a bool and
the if statement then compares the result, but not all comparisons are boolean
comparisons in the sense that we don't always compare to a boolean value. In
other words, "a == 0" isn't comparing against true or false, it's comparing
against an integer. It's worth noting here that omitting the "== 0" here is
considered bad style by many (though this is by no means universal). The camp
that would have you write "== false" invariably falls in the same camp that
would have you write "== 0", because that way the two would be consistent in
that you always specify what's being compared to what. Of course, this doesn't
mean everybody would have you write "== 0" would also have you write "==
false". The idea is consistency (I don't know how that slipped my mind in my
original posting.)
All including the explicit test there does is make other programmers
wonder if you've lost your mind
Not all programmers would think that, again. :)
Trying to correct that error, you end up with monstrosities such
as bool(x) == True or operator.truth(x) == True (or the equivalent in
other languages), and after some point it should dawn on the programmer
that the explicit True test is pointless.


I don't see how that would logically follow just from making an explicit bool
test. We know that such code is broken when we consider it, and then we reject
it, and we just do it the way we always did it, whether that's omitting the
explicit comparison altogether or comparing against false, or whatever other
possibility.

- Kef

Jul 18 '05 #32

P: n/a
On Mon, 17 Nov 2003 15:37:41 -0800, Erik Max Francis <ma*@alcyone.com>
wrote:
Ron Adam wrote:
No, this one point is not the only reason, I made the example a
little farfetched to demonstrate a concept I think is a valid reason
to have 'True' and 'False' as Constants. Their actual internal
values shouldn't be relevant or depended on. They need to be constant
to how a boolean expression evaluates in the language they are in.
In effect you are arguing against the point you were trumpeting earlier.
If we take your argument to its logical conclusion, that means that True
and False may be modified (accidentally or intentionally) by a
programmer and so we should never rely on its value. Which means that
you should never use True or False.


I'm not arguing at all. Only exploring the issue.

I don't know if we should never use True and False. It's as
dependable as any other variables and we need to handle them in the
same way. That includes making sure they have not been changed if we
use them for something that can be a mission critical application.
ie...

True = (1==1)
False = (1!=1)

or if you prefer;

True = bool(1)
False = bool(0)

The interpreter initializes True and False when it starts. So for
small applications, they are fairly dependable, it shouldn't be a
problem to use them. For large application with multiple files
imported into them written by several programmers, it might not be a
bad idea to initialize them like above to be safe.

This of course is why they are constants in other languages. It
increases the dependability of the code. Both by using True and False
and by making sure they cannot be changed.
Of course, the fact that any builtin can be overridden sort of dulls
that point, since that means you shouldn't use _anything_.
It may be beneficial to make changes to built in's not so easy in some
cases.
int(2.3) 2 def int(): return 32
int(2.3)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in -toplevel-
int(2.3)
TypeError: int() takes no arguments (1 given)

So maybe you are correct, we shouldn't use anything. (?)

Being able to change things in Python is one of the reasons that makes
it powerful, but being able to depend on certain things being
consistent is also a good thing. So where do these intersect? What
is the optimum mix of the two?

In python you can change the value of True, or set True to point to
something different.

For example you can do this.
>>> True

True
>>> False

False
>>> True = False
>>> True

False

Now all bets are off....


Sure, but that's got nothing to do with True or False as specific
entities. This can happen with any builtin function, even the
type/converters:


Yes, so what are True and False? Are they just preinitialized
variables? Are do they have special properties of their own?

From what I've seen so far, the 'True' and 'False' values are useful,
but the names 'True' and 'False' can be changed and aren't synonymous
with the values 'True' and 'False'. Two different things.

So how would you use True and False? I say go ahead and use them to
make your code readable, but if its a large or mission critical
application, you might want to make sure they are what they should be
before you do by initializing them the same as you would any other
variable.

int = float
float = str
str = lambda x: None
file = 'elif'
Since these can happen with any of these things, singling out True and
False doesn't make sense.
True should be a Constant and always equal to (1==1) and False should
always be equal to (1!=1). It's not, so we need to be careful
using True.
I really don't see your point here. It's true that someone malicious or
insufficiently careful can override the values of "constants" like True
or False. Of course that's true with all the other builtin functions,
constants, and types, so that point really has nothing to do with True
or False.


If a programmer is malicious and wants to sabotage code, making True
and False constants will hardly stop them.
So how does this point relate to explicit testing against the values of
True or False


Well if True and False can be changed, then it really isn't an
explicit test is it? It's a relative test.

if you want to test if a value is explicitly equal to 'True', you
need to use (value == (1==1)).

And if you want to explicitly test if something is equal to 'false',
use (value ==(1!=1)).

These will always work. And doing:

if x: # x is not 'False'

is not the same as:

if x=True:

This is because Bools are a subset of ints and not a subset of binary
as in some other languages. If they were a subset of binary, they
would be equivalent. We just need to be aware of that. Bools as a
subset of ints give the advantage of 'if x:'. where x is true if its
not 0 instead of x only being "True" if it's equal to 1.

I'm probably repeating what's already been said in this thread
already.

The above is much less implausible. Do you agree?


Yes, but it is still programmer error. If `str' got overridden -- quite
frankly, a much more common programmer error -- you'd have the same
problem, and it has nothing to do with Booleans.


What am I missing? The thread is about 'True inconsistency in
Python', and the reason it's inconsistent is because it can be changed
so easy.

Doing this causes an error:
1 = 2 SyntaxError: can't assign to literal
Doing this does not cause an error:
True = False


Are True and False Bools?

Why are they not also literals? Wouldn't that be consistent?
_Ronald Adam
Jul 18 '05 #33

P: n/a
On 18 Nov 2003 01:11:13 GMT, KefX wrote:
un-attributed author wrote:
I don't see the value in this. The expression in an if statement is
treated as a Boolean expression. [...]
However long the expression is, I don't see how adding `== true' at
the end makes it more clear.
What if the expression is 37 lines long?


What of it? Is a long expression in an 'if' statement somehow less
likely to be treated as Boolean? What does appending ' == True' gain?
How could it not be obvious that the entire expression will be evaluated
for Boolean truth, when the expression is the argument to 'if' ?
Fishing out the main comparison in such a monster isn't always the
easiest thing to do.
How does "fishing out the main comparison" have anything to do with
appending ' == True' to the expression?
"a == 0" isn't comparing against true or false, it's comparing against
an integer.
Correct. The comparison, though, is a Boolean expression, which will
evaluate to either True or False. Its use in an 'if' statement will
always evaluate it this way.
It's worth noting here that omitting the "== 0" here is
considered bad style by many (though this is by no means universal).
Only in cases where ' == 0' is *not* a test for Boolean falsity.
Compare a variable against 0 if you want to test if its value is
numerically zero; evaluate the variable if it is supposed to contain a
Boolean true or false value.
The camp that would have you write "== false" invariably falls in the
same camp that would have you write "== 0", because that way the two
would be consistent in that you always specify what's being compared
to what.
No. The argument to 'if' is a Boolean expression. A test against
numeric zero is not the same as a test against Boolean false, except by
implementation coincidence.

If the variable 'a' is conceptually containing a numeric value, then
using it as a Boolean value implies things that are not necessarily true
about the Boolean implementation. Hence, 'if( a == 0 )' and not
'if( ( a == 0 ) == True )'. Similarly, testing the negative case is
'if( not ( a == 0 ) )'. No explicit comparison to True or False is
required.

If the variable 'a' is conceptually containing a Boolean value, then
using it as the argument to 'if' is consistent. Hence, 'if( a )' and
not 'if( a == True )'. Similarly, testing the negative case is
'if( not a )'. No explicit comparison to True or False is required.

Once the expression *reads as a Boolean expression*, then adding further
comparisons against Boolean values helps nothing.
The idea is consistency (I don't know how that slipped my mind in my
original posting.)


I, too, value consistency, which is why I abhor adding ' == True' to
some Boolean expressions but not to others. It should be added to none
of them.

You appear to want semantic consistency between types (integer and
Boolean) that *by design* aren't semantically consistent. The 'if'
statement takes a Boolean expression as argument; to be consistent, one
passes it a Boolean expression argument, not some other type of
argument.

--
\ "A celebrity is one who is known by many people he is glad he |
`\ doesn't know." -- Henry L. Mencken |
_o__) |
Ben Finney <http://bignose.squidly.org/>
Jul 18 '05 #34

P: n/a
KefX wrote:
What if the expression is 37 lines long? (Can't happen? I'm LOOKING at
such an
example!) Fishing out the main comparison in such a monster isn't
always the
easiest thing to do. Of course I'm exaggerating here, since we usually
don't
write 37-line expressions, but still.
What if it's twenty pages long? I still don't see the benefit. If
you're looking at an expression in an if statement, you need to look at
the _whole_ expression to figure out what it's doing. I don't see how
ending it with `== True' makes it any more readable.
Yes, all tests are boolean tests in the sense that they evaluate to a
bool and
the if statement then compares the result, but not all comparisons are
boolean
comparisons in the sense that we don't always compare to a boolean
value. In
other words, "a == 0" isn't comparing against true or false, it's
comparing
against an integer. It's worth noting here that omitting the "== 0"
here is
considered bad style by many (though this is by no means universal).
Well, if you leave off the `== 0', it means something else.
The camp
that would have you write "== false" invariably falls in the same camp
that
would have you write "== 0", because that way the two would be
consistent in
that you always specify what's being compared to what.
Not even a little. An explicit test for an individual value is one
thing. An explicit comparison for an individual value _when there are
only two possible categories_ (true or false) is utterly pointless,
because all it does is add the opportunity to create an error.
Of course, this
doesn't
mean everybody would have you write "== 0" would also have you write
"==
false". The idea is consistency (I don't know how that slipped my mind
in my
original posting.)
It's not at all consistent, that's the problem. Not to mention the
fact, as others pointed out, that not all false values are False.
I don't see how that would logically follow just from making an
explicit bool
test.


Because in Python the explicit Boolean test cannot possibly be anything
other than redundant. If it is not redundant, it is probably an error.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ So little time, so little to do.
-- Oscar Levant
Jul 18 '05 #35

P: n/a
Ron Adam wrote:
I'm not arguing at all. Only exploring the issue.
Maybe you should summarize your central tenets, I'm afraid they've
gotten lost. It seems like we've run around in a big circle.
The interpreter initializes True and False when it starts. So for
small applications, they are fairly dependable, it shouldn't be a
problem to use them. For large application with multiple files
imported into them written by several programmers, it might not be a
bad idea to initialize them like above to be safe.
Unless you're using naughty things like `from module import *', no
collision can occur. If you are, why are you more worried about
collisions with the True/False constants, rather than any of the other
builtins? They're all just as possible.
So maybe you are correct, we shouldn't use anything. (?)
My point is that you need to expect a sane environment. If you're
working with fellow engineers who keep planting time bombs, maybe they
should be removed from the team rather than having to defensively work
around their potential disasters.

Python has as a central concept that everyone's an adult. If you want
to mess things up really badly, you can. If you want to use some clever
trick in order to save a lot of work, you can do that too. With power
and flexibility comes the ability to mess things up really badly. Lack
of constants is an example of this idea in Python (as is, for example,
the lack of access control on object attributes).

If someone's going to keep overriding True and False, or int, or open,
then you're not going to get anywhere. Python isn't designed so that
you can write code that is completely protected from the misbehavior of
other engineers. And it shouldn't be.
Yes, so what are True and False? Are they just preinitialized
variables? Are do they have special properties of their own?
They're builtins, just like all the other builtins like int, max, file,
map, etc.
From what I've seen so far, the 'True' and 'False' values are useful,
but the names 'True' and 'False' can be changed and aren't synonymous
with the values 'True' and 'False'. Two different things.
All the other "preinitialized variables" have exactly the same
characteristic. There are no constants in Python.
So how would you use True and False? I say go ahead and use them to
make your code readable, but if its a large or mission critical
application, you might want to make sure they are what they should be
before you do by initializing them the same as you would any other
variable.
I never suggested that True and False shouldn't be used; far from it. I
just used your objection (that their values can be overridden) to
illustrate a reductio ad absurdum. Either that's a really scary thing
(which you can't defend against) and the interpreter comes crumbling
down, or you assume that people are going to behave themselves and don't
worry about it.
If a programmer is malicious and wants to sabotage code, making True
and False constants will hardly stop them.
Exactly. So I don't understand what your point is; you're the one who
brought up the danger of overriding True and False.
What am I missing? The thread is about 'True inconsistency in
Python', and the reason it's inconsistent is because it can be changed
so easy.
You've gotten severely sidetracked on this thread. The original
inconsistency mentioned in this thread is that explicit comparisons with
True or False do not involve an implicit conversion to bool. So 3 ==
True is False, even though bool(3) == True is True.
Doing this causes an error:
1 = 2 SyntaxError: can't assign to literal

Doing this does not cause an error:
True = False

That's because a literal is not a name that can be assigned to, anymore
than

'asdf' = 2 + 3

could possibly make any sense. True and False are, on the other hand,
names.
Are True and False Bools?
True and False are names which are initially bound to the true and false
Boolean values, respectively. They're names like any other names: x,
thisIsAVariable, int, str, sys, etc.
Why are they not also literals? Wouldn't that be consistent?


They're not literals because that's not the way that they're handled by
the language. None, for instance, is not a literal; it's a name. So
neither are True and False.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ So little time, so little to do.
-- Oscar Levant
Jul 18 '05 #36

P: n/a

"Ron Adam" <ra****@tampabay.rr.com> wrote in message
news:iv********************************@4ax.com...
x = True
if x:
....
since the above snippert is equivalent to

if True:
....

which is equivalent to

....

you must have meant something more imvolved. But I am having trouble
filling in the missing pieces.
So I get consistent results for the language and platform I'm using
now and in the future. If down the road someone decided to make True = 3, and False = -5, and they change the language so that any boolean comparisons return 3 and -5 respectively, my use of True and False
will still work.
This strikes me as comparable to worrying about being killed by an
asteroid. Is there some actual historical event that makes it more
plausible to you?

'Someone' would have to be someone with the authority to make such a
change in either the language or a particular implementation thereof.
Such people are usually at least somewhat sane. If someone did make
such a lunatic change, I suspect that it would not be the only one,
and one would have to be a lunatic to keep using that
language/implementation for serious work. Unless the language were
locked up and proprietary, users could reject such a change anyway.
(On the other hand, exposure to lesser lunacies *is* one of the risks
of using proprietary unclonible systems.)

.... It looks to me that 'True' in python is a combination of the boolean
binary logic of 1 or 0, and as an "exists" test of 0 or not 0.
I do not understand this. If you have a reference to 0, then 0
exists. If you do not, then the 'existence' or not of an int with
value 0 is irrelevant.
If python had an exists operator, you could do.
I think you are confusing names and objects. You can only apply an
operator to objects and only to objects that exist.
if x exists:
'do something'
Do you mean
if bound_to_something('x'): <do something>
?

Normally, in the absence of error, one only uses names that one has
defined (bound to somethingj). So you must be worried about the
following scenario:

if a: x=1
<more code>
if exists(x): <do something with x>

In non-module script only:
import __main__ as mm
x = 1
hasattr(mm, 'x') # True
hasattr(mm, 'y') # False

Anywhere: use try ... except NameError

Or, don't do that (have conditionally defined name). Instead,

x=None
if a: x = something_not_None()
<more code>
if x != None: <do something with x>

In other words, name != None is often idiom for exists('name')!
This could serve two options also... does the object exist?
Again, Python only operates on objects that do exist.

.... With pythons dynamic variables, I think an exists function would be
useful to check if an object exists.


Same comment.

Terry J. Reedy
Jul 18 '05 #37

P: n/a

"Ron Adam" <ra****@tampabay.rr.com> wrote in message
news:8q********************************@4ax.com...
No, this one point is not the only reason, I made the example a
little farfetched to demonstrate a concept I think is a valid reason
to have 'True' and 'False' as Constants.
The developers agree and would make them so now if it were not for
backward compatibility needs. They probably will make them so in the
future. Currently, reassigning None can get you a Warning.
Their actual internal
values shouldn't be relevant or depended on.
When the bool type was added, a few people argued for a pure bool type
with no relation to anything else. However, in Python, 'practicality
beats purity'. Having True/False == 1/0 now and forever has practical
uses.
In python you can change the value of True, or set True to point to
something different.
Yes, you are currently allowed to stab yourself in the back (but even
this will probably change in the future). Don't do it.
For example you can do this.
True = False
Now all bets are off....


Ditto.
To be sure that True is True and False is
False, we need to put in explicit definitions into our programs.
In 2.2.2+, you only need to not change them and to not work with a
psycopath.

.... The above is much less implausible. Do you agree?


Yes, it is more plausible that you shoot yourself in the feet than
that Guido and the whole Python development community go bonkers. I
strongly suspect that PyChecker can check for assignments to True and
False (along with about a hundred other things). Get it and use it.

Terry J. Reedy
Jul 18 '05 #38

P: n/a
On Mon, 17 Nov 2003 23:13:24 -0500, "Terry Reedy" <tj*****@udel.edu>
wrote:

"Ron Adam" <ra****@tampabay.rr.com> wrote in message
news:iv********************************@4ax.com.. .
x = True
if x:
....
since the above snippert is equivalent to

if True:
...

which is equivalent to

...

you must have meant something more imvolved. But I am having trouble
filling in the missing pieces.


Yes, the paragraph (that you snipped) above this code snippit,
explained that you need to be able to depend on 'True' being
consistent with how the underlying operating system evaluates boolean
expressions. If that trust is broken, then comparisons using True
may not work. Including "if True:".

This is so basic and simple, that you take it for granted. And so do
many others.

I believe the words 'True' and 'False' need to be treated the same as
the digits 1, 2, 3, ... The values of the digits do not change. We
depend on them not changing.

True should always evaluate to True also. So we can depend on it as
well.

This is my opinion, you don't have to agree with it.

So I get consistent results for the language and platform I'm using
now and in the future. If down the road someone decided to make

True
= 3, and False = -5, and they change the language so that any

boolean
comparisons return 3 and -5 respectively, my use of True and False
will still work.


This strikes me as comparable to worrying about being killed by an
asteroid. Is there some actual historical event that makes it more
plausible to you?


Again, it was an example of a concept. I was trying to point out
even if the underlying values that the operating system uses to
represent true and false are changed, having True as a constant equal
to a boolean true evaluation, will still work. I chose numbers that
are very unlikely to try demonstrate in an obvious way that the
concept is valid. Sorry, if I lost you.

Does making 'True' and 'False' constants and/or literals have any draw
backs for you? I can only think of benefits and don't see any reason
for not doing it in this particular case. While I admit that any
knowledgable programmer can write good programs without these being
constants or literals, I also realize that python is becoming
popular as a teaching tool for entry level programming. So yes, I
believe errors using and miss using True and False will happen.

<clipped, and opinion noted>


...
It looks to me that 'True' in python is a combination of the boolean
binary logic of 1 or 0, and as an "exists" test of 0 or not 0.
I do not understand this. If you have a reference to 0, then 0
exists. If you do not, then the 'existence' or not of an int with
value 0 is irrelevant.


if x: is a test to see if the value 0 does not exist in x.

Or as someone has stated to me earlier... it is a test that something
does exist. That something being whatever the value x represents.

x is the number of coins I have. ' if x:' is a true statement if I
have some coins. We are testing for the existence of my coins.

If python had an exists operator, you could do.


I think you are confusing names and objects. You can only apply an
operator to objects and only to objects that exist.


No, I'm not confused, and yes I am diverging here.
if x exists:
'do something'


Do you mean
if bound_to_something('x'): <do something>
?


Yes, you understand.
Normally, in the absence of error, one only uses names that one has
defined (bound to somethingj). So you must be worried about the
following scenario:

if a: x=1
<more code>
if exists(x): <do something with x>

In non-module script only:
import __main__ as mm
x = 1
hasattr(mm, 'x') # True
hasattr(mm, 'y') # False

Anywhere: use try ... except NameError

Or, don't do that (have conditionally defined name). Instead,

x=None
if a: x = something_not_None()
<more code>
if x != None: <do something with x>

In other words, name != None is often idiom for exists('name')!
This could serve two options also... does the object exist?


Again, Python only operates on objects that do exist.


Yes, I noticed. The reason I bring this up is in situations where
you want to initialize a variable if it has not been defined yet, but
do not want to re initialize it if it's already been defined.

Being able to check if an object already exists could be useful. I'll
look into the hasattr() function more, thanks for pointing it out.

I did stray a bit on this and I admitted so in my post.
_Ronald Adam
Jul 18 '05 #39

P: n/a
On Mon, 17 Nov 2003 23:40:52 -0500, "Terry Reedy" <tj*****@udel.edu>
wrote:

"Ron Adam" <ra****@tampabay.rr.com> wrote in message
news:8q********************************@4ax.com.. .
No, this one point is not the only reason, I made the example a
little farfetched to demonstrate a concept I think is a valid reason
to have 'True' and 'False' as Constants.
The developers agree and would make them so now if it were not for
backward compatibility needs. They probably will make them so in the
future. Currently, reassigning None can get you a Warning.


That would be good.

Their actual internal
values shouldn't be relevant or depended on.


When the bool type was added, a few people argued for a pure bool type
with no relation to anything else. However, in Python, 'practicality
beats purity'. Having True/False == 1/0 now and forever has practical
uses.


Good also.
In python you can change the value of True, or set True to point to
something different.


Yes, you are currently allowed to stab yourself in the back (but even
this will probably change in the future). Don't do it.

I agree, it's good that it may change.
For example you can do this.
>>> True = False

Now all bets are off....


Ditto.
To be sure that True is True and False is
False, we need to put in explicit definitions into our programs.


In 2.2.2+, you only need to not change them and to not work with a
psycopath.


Many people are starting to learn programming with python as their
first computer language. I wouldn't refer to them as a psychopath.
They may one day write programs that save peoples lives. They have to
start someplace. Many people using python will not be professional
programmers but enthusiast and hobbiests, or web page programmers,
or ..... in other words, a very large and diverse group.
...
The above is much less implausible. Do you agree?


Yes, it is more plausible that you shoot yourself in the feet than
that Guido and the whole Python development community go bonkers. I
strongly suspect that PyChecker can check for assignments to True and
False (along with about a hundred other things). Get it and use it.

Terry J. Reedy


I'm not sure what your point is here, but using PyChecker sounds like
a good suggestion.

_Ronald Adam
Jul 18 '05 #40

P: n/a
On Tue, 18 Nov 2003 07:15:01 GMT, Ron Adam wrote:
I believe the words 'True' and 'False' need to be treated the same as
the digits 1, 2, 3, ... The values of the digits do not change. We
depend on them not changing.


Possibly so. For myself, I think it's good that they exist at all now.
Incremental improvement toward a canonical Boolean type is good.

- We now have a separate 'bool' type.
- We now hove True and False singleton objects of type 'bool'.
- Boolean expressions now evaluate to one of these two objects.

These are all quite recent in Python. Perhaps immutable Boolean values
will be in a future Python version. However, I don't see that it's a
pressing need.

Assigning a new value to None is possible (until recently, it didn't
even generate a warning). How much Python code does this break? How
many potential errors does it cause? My guess would be few. Same for
the True and False values (and the numbers, if they were mutable).

There are many ways to shoot yourself in the foot in Python, if you try
hard enough. This is one of them. Acknowledge its existence,
acknowledge that you'd be crazy to do it, and move on.

--
\ "Yesterday I parked my car in a tow-away zone. When I came back |
`\ the entire area was missing." -- Steven Wright |
_o__) |
Ben Finney <http://bignose.squidly.org/>
Jul 18 '05 #41

P: n/a
On Mon, 17 Nov 2003 18:47:34 -0800, Erik Max Francis <ma*@alcyone.com>
wrote:
Ron Adam wrote:
I'm not arguing at all. Only exploring the issue.
Maybe you should summarize your central tenets, I'm afraid they've
gotten lost. It seems like we've run around in a big circle.


I think so too.

My basic tenant, belief, or point, is.

The main inconsistencies of 'True' and 'False' are due to the
possibility of the names 'True' and 'False' being reassigned.

And the best way to fix this is by making 'True' and 'False' literals
or constants.

Unless you're using naughty things like `from module import *', no
collision can occur. If you are, why are you more worried about
collisions with the True/False constants, rather than any of the other
builtins? They're all just as possible.
It looks to me the benefits of changing this one item are worthwhile,
and the drawbacks if it very low. It is also consistent to have them
as basic constants and/or literals in the same way digits and the
alphabet are. The values True and False are to Type boo() as digits
are to int() or floats(), and as the alphabet is to string().

So maybe you are correct, we shouldn't use anything. (?)


My point is that you need to expect a sane environment. If you're
working with fellow engineers who keep planting time bombs, maybe they
should be removed from the team rather than having to defensively work
around their potential disasters.


I expect a set of programmers that have many different skill levels.
With a lot of beginners, a fair amount who are average, a good
number who are above average, and a small number who are experts.

Python has as a central concept that everyone's an adult. If you want
to mess things up really badly, you can. If you want to use some clever
trick in order to save a lot of work, you can do that too. With power
and flexibility comes the ability to mess things up really badly. Lack
of constants is an example of this idea in Python (as is, for example,
the lack of access control on object attributes).
No not every one is an adult. Python is being taught as a first
computer language in some high schools now. I'm only suggesting that
this one item be changed here. And that this change is beneficial
with very few if any drawbacks.

If someone's going to keep overriding True and False, or int, or open,
then you're not going to get anywhere. Python isn't designed so that
you can write code that is completely protected from the misbehavior of
other engineers. And it shouldn't be.
Is python just for engineers? I don't believe it is.

Yes, so what are True and False? Are they just preinitialized
variables? Are do they have special properties of their own?


They're builtins, just like all the other builtins like int, max, file,
map, etc.


So they have not special property of there own. From what I
understand, being a built in is a matter of where the code is, and
doesn't have anything to do with what it does. It's a practical
matter that the most frequently used items are built ins.
From what I've seen so far, the 'True' and 'False' values are useful,
but the names 'True' and 'False' can be changed and aren't synonymous
with the values 'True' and 'False'. Two different things.


All the other "preinitialized variables" have exactly the same
characteristic. There are no constants in Python.


Yes, Other than the literals like the digits, and alphabetic
characters. You can't change them. Why not have True and False work
the same way?
I never suggested that True and False shouldn't be used; far from it. I
just used your objection (that their values can be overridden) to
illustrate a reductio ad absurdum.
It was an observation, not an objection.

Either that's a really scary thing
(which you can't defend against) and the interpreter comes crumbling
down, or you assume that people are going to behave themselves and don't
worry about it.
Or I don't assume anything, and realize both of those are
possibilities. And with a large enough group of programmers, they
will happen. Although, I think "the interpreter crumbling down" is
exaggerating a bit.

If a programmer is malicious and wants to sabotage code, making True
and False constants will hardly stop them.


Exactly. So I don't understand what your point is; you're the one who
brought up the danger of overriding True and False.


And you agree it is a danger. Don't you? That is my point.

What am I missing? The thread is about 'True inconsistency in
Python', and the reason it's inconsistent is because it can be changed
so easy.


You've gotten severely sidetracked on this thread. The original
inconsistency mentioned in this thread is that explicit comparisons with
True or False do not involve an implicit conversion to bool. So 3 ==
True is False, even though bool(3) == True is True.


Ok, I see, yes, I missed that part. But this is consistent with
"if value:" evaluating to True if it's not zero. I understand it's
because of practical convenience that type bool is a subset of
integers, and this is how bool should operate if bool is a subset of
integers and not a subset of type binary. (if there were a type
binary in Python.)

My background is in digital electronics, so I am aware this isn't a
true bool type and it varies from pure binary logic. But it is
consistent, and it does make sense to me.

So the inconsistency I saw was in that True and False are not treated
the same as other types made up from literals. 1 is always equal to
1, and it's never equal to 2. The same can't be said for True and
False and bool(), So doing comparisons to True is not as reliable as
adding digits, or constructing strings from the alphabet.

Doing this causes an error:
>>> 1 = 2

SyntaxError: can't assign to literal

Doing this does not cause an error:
>>> True = False
>>>


That's because a literal is not a name that can be assigned to, anymore
than

'asdf' = 2 + 3

could possibly make any sense. True and False are, on the other hand,
names.


And my point is maybe they shouldn't be names, but treated the same
as letters and numbers.

Are True and False Bools?


True and False are names which are initially bound to the true and false
Boolean values, respectively. They're names like any other names: x,
thisIsAVariable, int, str, sys, etc.
Why are they not also literals? Wouldn't that be consistent?


They're not literals because that's not the way that they're handled by
the language. None, for instance, is not a literal; it's a name. So
neither are True and False.


But that's not a reason, its a situation. I know they are names.

Why could they not be made to be literals? And why would we not want
them to be literals?

Terry Reedy has pointed out to me that this will likely be changed in
the future. I think it will make Python more consistent by preventing
the possible reassignments of True, False, and None. If these values
are used throughout the libraries, reassigning them will cause
something to not work somewhere at sometime. So preventing them from
being reassigned is practical also.

_Ronald Adam
Jul 18 '05 #42

P: n/a
Ron Adam wrote:
The main inconsistencies of 'True' and 'False' are due to the
possibility of the names 'True' and 'False' being reassigned.

And the best way to fix this is by making 'True' and 'False' literals
or constants.
But True and False are no different from None, int, str, or any of the
other builtins.
It looks to me the benefits of changing this one item are worthwhile,
and the drawbacks if it very low. It is also consistent to have them
as basic constants and/or literals in the same way digits and the
alphabet are. The values True and False are to Type boo() as digits
are to int() or floats(), and as the alphabet is to string().
But, as I said, you're not going to run into this problem unless you're
doing unsafe things already (like `from module import *'), or letting
people you don't trust edit your source. I don't see this as a big
problem.

Accidental rebindings of things like int, str, and other builtin
types/functions with common names seem _far_ more common than
"accidentally" rebinding True or False.
So they have not special property of there own. From what I
understand, being a built in is a matter of where the code is, and
doesn't have anything to do with what it does. It's a practical
matter that the most frequently used items are built ins.
Yes. And builtins other than True and False are far more frequently
accidentally rebound.
So the inconsistency I saw was in that True and False are not treated
the same as other types made up from literals. 1 is always equal to
1, and it's never equal to 2. The same can't be said for True and
False and bool(),
It's not true for int, either.
Terry Reedy has pointed out to me that this will likely be changed in
the future. I think it will make Python more consistent by preventing
the possible reassignments of True, False, and None.


It will change in the sense that rebinding these names may result in
warnings or errors (already there's a warning for rebinding None in the
usual way), not that they'll become literals.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ God will forgive me; that's his business.
-- Heinrich Heine
Jul 18 '05 #43

P: n/a

"KefX" <ke**********@aol.comNOSPAM> wrote in message
news:20***************************@mb-m17.aol.com...
not. However long the expression is, I don't see how adding `== true'at the end makes it more clear.


What if the expression is 37 lines long?


Given that

if <horrendous long expression

is *exactly equivalent* to

if True == <horrendous long expression

I see no reason for the latter and a big reason against it: adding
'True==' deceptively implies that there is some difference to justify
the extra chars. I get the feeling you actually somehow believe that
there is a difference.

Would you advocate that sums and products always start (or end) with
an analogous and explicit '0+' or '1*'? What would you think of a
style guide that mandated code like the following:

x = (0+0j) + a + b
y = 1.0 * d * e

These have been occasionally used to force result type. 'True==' also
forces, as an alternative to bool(), but if bool() is redundant, as it
is in Python for conditional expressions, so is 'True =='.

Terry J. Reedy
Jul 18 '05 #44

P: n/a

"Ron Adam" <ra****@tampabay.rr.com> wrote in message
news:83********************************@4ax.com...
I believe the words 'True' and 'False' need to be treated the same as the digits 1, 2, 3, ... The values of the digits do not change. We depend on them not changing.
True should always evaluate to True also.
So we can depend on it as well.
This is my opinion, you don't have to agree with it.
Others have also proposed that None, True, and False be made keywords.
We'll see how far Guido goes in 3.0. I do not think even he really
knows.
It looks to me that 'True' in python is a combination of the boolean binary logic of 1 or 0, and as an "exists" test of 0 or not 0. [me]
I do not understand this. If you have a reference to 0, then 0
exists. If you do not, then the 'existence' or not of an int with
value 0 is irrelevant.

if x: is a test to see if the value 0 does not exist in x.
Aha. Got it. Above, you are using 'exist' at a different level of
abstraction than I understood. I was thinking of object or binding
existence, whereas you were speaking of value connotation. Yes, if c
is a count of something, then 'if c:' tests for the positive existence
of at least one counted something. Similarly for list L of
somethings, 'if L:' tests for the existence of at least one listed
something.

I consider this 'overloading' of conditional expressions to be one of
the great features of Python. I now take it for granted.
if x exists:
'do something'


Do you mean
if bound_to_something('x'): <do something>
?


Yes, you understand.


Whoops, now you are agreeing with 'exist' as 'binding existence'.
Yes, this is a 'divergence' from your other sense of exist.
Yes, I noticed. The reason I bring this up is in situations where
you want to initialize a variable if it has not been defined yet, but do not want to re initialize it if it's already been defined.


For just one variable, I might use

try: x
except NameError: x = 'value'

Terry J. Reedy
Jul 18 '05 #45

P: n/a

"Ron Adam" <ra****@tampabay.rr.com> wrote in message
news:7r********************************@4ax.com...
On Mon, 17 Nov 2003 23:40:52 -0500, "Terry Reedy" <tj*****@udel.edu>
wrote:
In 2.2.2+, you only need to not change them and to not work with a
psycopath.
Many people are starting to learn programming with python as their
first computer language. I wouldn't refer to them as a psychopath.


Neither would I. I was thinking of the following scenario. You are
part of a programming group. You write module ronad, to be imported
by danor written by 'Dan Oreo'. Psycho writes unrelated module
'sneaky' with

import ronad
ronad.True, ronad.False = False, True

perhaps disguised. You get blamed for the 'bug' that you did not
write and cannot find.

[Prohibiting this scenario (import module and mask builtins there in)
has been suggested. I believe it was once approved and is still under
consideration but the change has the problem that there seem to be
legitimate uses.]
They may one day write programs that save peoples lives. They have to start someplace. Many people using python will not be professional
programmers but enthusiast and hobbiests, or web page programmers,
or ..... in other words, a very large and diverse group.
People often post code redefining builtings like file and list, and
get reminders not to do so. I cannot remember anyone accidentally
overwriting True or False.

.... I'm not sure what your point is here, but using PyChecker sounds like a good suggestion.


That suggestion was my final point. Ignore the warm-up pitch.

Terry J. Reedy
Jul 18 '05 #46

P: n/a
On Tue, 18 Nov 2003 19:50:49 -0500, "Terry Reedy" <tj*****@udel.edu>
wrote:
[Prohibiting this scenario (import module and mask builtins there in)
has been suggested. I believe it was once approved and is still under
consideration but the change has the problem that there seem to be
legitimate uses.]


It might conflict with existing programs that assign 'True = 1' and
'False = 0', I can see where that could be a very common
occurrence for people who are new to Python. And once they learn
about the True and False values, they may not go back and change the
older programs. ie... if it'n not broke don't fix it. In other
words, they leave them as is and move on to the next project.

_Ronald Adam
Jul 18 '05 #47

This discussion thread is closed

Replies have been disabled for this discussion.