"0 in [True,False]" returns True

1 view
Skip to first unread message

Pierre Quentel

unread,
Dec 12, 2005, 4:26:47 PM12/12/05
to
Hi all,

In some program I was testing if a variable was a boolean, with this
test : if v in [True,False]

My script didn't work in some cases and I eventually found that for v =
0 the test returned True

So I changed my test for the obvious "if type(v) is bool", but I still
find it confusing that "0 in [True,False]" returns True

By the way, I searched in the documentation what "obj in list" meant and
couldn't find a precise definition (does it test for equality or
identity with one of the values in list ? equality, it seems) ; did I
miss something ?

Regards,
Pierre

Fredrik Lundh

unread,
Dec 12, 2005, 4:36:03 PM12/12/05
to pytho...@python.org
Pierre Quentel wrote:

>>> issubclass(bool, int)
True
>>> isinstance(False, int)
True
>>> False == 0
True
>>> int(False)
0

but seriously, unless you're writing an introspection tool, testing for
bool is pretty silly. just use "if v" or "if not v", and leave the rest to
Python.

</F>

Carsten Haese

unread,
Dec 12, 2005, 4:38:31 PM12/12/05
to Pierre Quentel, pytho...@python.org

Where/how did you search? http://docs.python.org/lib/typesseq.html
states unambiguously that "x in s" returns "True if an item of s is
equal to x, else False"

HTH,

Carsten.


Steven Bethard

unread,
Dec 12, 2005, 7:34:26 PM12/12/05
to
Pierre Quentel wrote:
> In some program I was testing if a variable was a boolean, with this
> test : if v in [True,False]
>
> My script didn't work in some cases and I eventually found that for v =
> 0 the test returned True

This seems like a strange test. What is this code trying to do?

If you're sure you have to do this, I would do either:

if isinstance(v, bool):
...

or

if v is True or v is False:
...

But it really seems like this code is trying to code some other language
in Python...

STeVe

David Wahler

unread,
Dec 12, 2005, 9:46:23 PM12/12/05
to
Pierre Quentel wrote:
> Hi all,
>
> In some program I was testing if a variable was a boolean, with this
> test : if v in [True,False]
>
> My script didn't work in some cases and I eventually found that for v =
> 0 the test returned True
>
> So I changed my test for the obvious "if type(v) is bool", but I still
> find it confusing that "0 in [True,False]" returns True

>From the docs: Python Library Reference, section 2.3.10.9:
"Boolean values are the two constant objects False and True. They are
used to represent truth values (although other values can also be
considered false or true). In numeric contexts (for example when used
as the argument to an arithmetic operator), they behave like the
integers 0 and 1, respectively."

I don't blame you for not knowing about this; it is rather unintuitive.

-- David

bon...@gmail.com

unread,
Dec 12, 2005, 10:17:59 PM12/12/05
to
The OP's code(and his work around) doesn't look like he is testing for
boolean but more like the data type of something. I thought there is
some idiom in python which said something like "don't assume" ?

Fredrik Lundh

unread,
Dec 13, 2005, 2:27:46 AM12/13/05
to pytho...@python.org
bon...@gmail.com wrote:

> > but seriously, unless you're writing an introspection tool, testing for
> > bool is pretty silly. just use "if v" or "if not v", and leave the rest to
> > Python.
> >
> The OP's code(and his work around) doesn't look like he is testing for
> boolean

which of course explains why he wrote

In some program I was testing if a variable was a boolean

in the post I replied to...

> but more like the data type of something. I thought there is some idiom
> in python which said something like "don't assume" ?

"think before you post" ?

</F>

bon...@gmail.com

unread,
Dec 13, 2005, 2:46:13 AM12/13/05
to
Don't know what you mean.

He seems to be testing "boolean type", not whether it is true or false.

Antoon Pardon

unread,
Dec 13, 2005, 2:55:17 AM12/13/05
to
Op 2005-12-12, Fredrik Lundh schreef <fre...@pythonware.com>:

That depends on the circumstances. I have code where a particular
variable can be a boolean or an integer. I don't want that code
to behave the same on 0 and False nor on any other number and
True.

--
Antoon Pardon

bon...@gmail.com

unread,
Dec 13, 2005, 3:13:21 AM12/13/05
to
Then your program/implementation/requirement is wrong because it
doesn't fit in the use case of "if v:" or "if not v:", refactor ;-)

Steve Holden

unread,
Dec 13, 2005, 3:41:19 AM12/13/05
to pytho...@python.org
It actually uses the __contains__() method of the right-hand operand,
and in the case of a list that will test for equality of the left-hand
operand to one of the list elements. Since False == 0 that's why you see
what you do.

The really interesting question your post raises, though, is "Why do you
feel it's necessary to test to see whether a variable is a Boolean?".

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Paul Rubin

unread,
Dec 13, 2005, 4:03:41 AM12/13/05
to
Steve Holden <st...@holdenweb.com> writes:
> The really interesting question your post raises, though, is "Why do
> you feel it's necessary to test to see whether a variable is a
> Boolean?".

What's the point of having Booleans, if you can't tell them from integers?

Antoon Pardon

unread,
Dec 13, 2005, 4:25:57 AM12/13/05
to
Op 2005-12-13, Steve Holden schreef <st...@holdenweb.com>:

> Pierre Quentel wrote:
>> Hi all,
>>
>> In some program I was testing if a variable was a boolean, with this
>> test : if v in [True,False]
>>
>> My script didn't work in some cases and I eventually found that for v =
>> 0 the test returned True
>>
>> So I changed my test for the obvious "if type(v) is bool", but I still
>> find it confusing that "0 in [True,False]" returns True
>>
>> By the way, I searched in the documentation what "obj in list" meant and
>> couldn't find a precise definition (does it test for equality or
>> identity with one of the values in list ? equality, it seems) ; did I
>> miss something ?
>>
> It actually uses the __contains__() method of the right-hand operand,
> and in the case of a list that will test for equality of the left-hand
> operand to one of the list elements. Since False == 0 that's why you see
> what you do.
>
> The really interesting question your post raises, though, is "Why do you
> feel it's necessary to test to see whether a variable is a Boolean?".

I can give you one example. I have written a tube class. A tube behaves
like Queue but it has additional code so that it can be registed with
gtk in the same way as file descriptor can be registered with
io_add_watch. The way this is implemented is by registering an idle
handler when the tube is not empty and removing it when the tube is
empty. So I have a variable cb_src (for callback source) that can be
a boolean or an integer. The possible values are

False: Not registered by the user
True: Registered by the user but no nternal idle callback registerd
a number: gtk integer ID, from the registered idle callback handler.

--
Antoon Pardon

Erik Max Francis

unread,
Dec 13, 2005, 4:30:52 AM12/13/05
to
Paul Rubin wrote:

Because

return True

is clearer than

return 1

if the purpose of the return value is to indicate a Boolean rather than
an arbitrary integer.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
The basis of optimism is sheer terror.
-- Oscar Wilde

Steve Holden

unread,
Dec 13, 2005, 4:46:30 AM12/13/05
to pytho...@python.org

Booleans are specifically defined as a subtype of int at the C level.
One might also ask "what's the point of having floats if you can't tell
them from integers":

>>> 0.0 in [1,2,0,4]
True
>>>

It just so happens that __contains__() uses an equality test (which it
should) and equality tests perform certain coercions (which they
arguably shouldn't, but in that case I wouldn't be the one doing the
arguing).

"""
The only thing that changes is the preferred values to represent
truth values when returned or assigned explicitly. Previously,
these preferred truth values were 0 and 1; the PEP changes the
preferred values to False and True, and changes built-in
operations to return these preferred values.
"""

PEP 285.

Fredrik Lundh

unread,
Dec 13, 2005, 4:45:09 AM12/13/05
to pytho...@python.org
Erik Max Francis wrote:

> > What's the point of having Booleans, if you can't tell them from integers?
>
> Because
>
> return True
>
> is clearer than
>
> return 1
>
> if the purpose of the return value is to indicate a Boolean rather than
> an arbitrary integer.

the real reason booleans were added was that sillyness like

True = 1 == 1
False = not True

and

return 1 # true

and

class Boolean:

def __init__(self, value = 0):
self.value = operator.truth(value)

def __cmp__(self, other):
if isinstance(other, Boolean):
other = other.value
return cmp(self.value, other)

def __repr__(self):
if self.value:
return "<Boolean True at %x>" % id(self)
else:
return "<Boolean False at %x>" % id(self)

def __int__(self):
return self.value

def __nonzero__(self):
return self.value

True, False = Boolean(1), Boolean(0)

were all too common in the wild.

for the full story, see

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

and, to briefly return to the original topic, note that

"This PEP does *not* change the fact that almost all object types
can be used as truth values. For example, when used in an if
statement, an empty list is false and a non-empty one is true;
this does not change and there is no plan to ever change this.

The only thing that changes is the preferred values to represent
truth values when returned or assigned explicitly. Previously,
these preferred truth values were 0 and 1; the PEP changes the
preferred values to False and True, and changes built-in
operations to return these preferred values."

in general, returning True and False is pythonic, explicitly testing for
them is not.

</F>

Robin Becker

unread,
Dec 13, 2005, 4:54:29 AM12/13/05
to
Carsten Haese wrote:
.......

>
> Where/how did you search? http://docs.python.org/lib/typesseq.html
> states unambiguously that "x in s" returns "True if an item of s is
> equal to x, else False"
.....

exactly and I see

>>> 0==False
True
>>>

so I guess nothing is wrong :)
--
Robin Becker

bon...@gmail.com

unread,
Dec 13, 2005, 5:02:16 AM12/13/05
to

Erik Max Francis wrote:
> Paul Rubin wrote:
>
> > Steve Holden <st...@holdenweb.com> writes:
> >> The really interesting question your post raises, though, is "Why do
> >> you feel it's necessary to test to see whether a variable is a
> >> Boolean?".
> >
> > What's the point of having Booleans, if you can't tell them from integers?
>
> Because
>
> return True
>
> is clearer than
>
> return 1
>
> if the purpose of the return value is to indicate a Boolean rather than
> an arbitrary integer.
>
True, but if that is the only reason, Two built-in value of
True/False(0/1) serves the need which is what is now(well sort of). Why
have seperate types and distinguish them ?

>>>True == 1
True
>>>True is 1
False

Steve Holden

unread,
Dec 13, 2005, 5:03:18 AM12/13/05
to pytho...@python.org
Well I guess you'd better hope that gtk never returns a zero or one, then.

Note, though, that True and False are defined to be singleton instances,
so it *is* permissible to say

if i is False:

>>> 0 is False
False
>>> 1 is True
False
>>>

However I must say the coupling in that interface has a very definite
code smell. Why not use two variables, a Boolean "registered" and an
integer ID that is meaningless when registered is False?

Erik Max Francis

unread,
Dec 13, 2005, 5:14:52 AM12/13/05
to
bon...@gmail.com wrote:

> True, but if that is the only reason, Two built-in value of
> True/False(0/1) serves the need which is what is now(well sort of). Why
> have seperate types and distinguish them ?

Because of this:

x = True
y = 1 # but I mean it to represent true

print x, y

Besides, it's not the only reason, but it's a good one.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis

Ipsa scientia potestas est. "Knowledge itself is power."
-- a Latin proverb

bon...@gmail.com

unread,
Dec 13, 2005, 5:18:45 AM12/13/05
to

Erik Max Francis wrote:
> bon...@gmail.com wrote:
>
> > True, but if that is the only reason, Two built-in value of
> > True/False(0/1) serves the need which is what is now(well sort of). Why
> > have seperate types and distinguish them ?
>
> Because of this:
>
> x = True
> y = 1 # but I mean it to represent true
>
> print x, y
>
> Besides, it's not the only reason, but it's a good one.
>
True too, and could be the reason(or similar too) why the OP wants to
test the type rather than the logical value of it.

Erik Max Francis

unread,
Dec 13, 2005, 5:21:26 AM12/13/05
to
bon...@gmail.com wrote:

> True too, and could be the reason(or similar too) why the OP wants to
> test the type rather than the logical value of it.

The type is for the self-documentation purposes. The value is the same;
so no, that's not a good reason either.

Duncan Booth

unread,
Dec 13, 2005, 5:28:34 AM12/13/05
to
wrote:

>> if the purpose of the return value is to indicate a Boolean rather than
>> an arbitrary integer.
>>
> True, but if that is the only reason, Two built-in value of
> True/False(0/1) serves the need which is what is now(well sort of). Why
> have seperate types and distinguish them ?
>
>>>>True == 1
> True
>>>>True is 1
> False
>

Within Python that would probably be sufficient, but some external
libraries e.g. COM or XMLRPC make a distinction between integers and
booleans, so it makes it more convenient if there is a defined way to
distinguish between calling one overloaded method which takes an integer or
another of the same name which take a boolean.

Before Python had a separate boolean type there was an implementation
detail which mean that it was possible to distinguish the constants 0 and 1
which were generated by a comparison from other constant 0 and 1 values.
The python COM libraries used this 'feature'.

XMLRPC has its own Boolean class which is used in Python versions where
boolean is not a builtin.

Another reason to have a boolean type is of course to provide a cast:

def isNameSet(self):
return boolean(self.name)

instead of:

def isNameSet(self):
if self.name:
return True
else:
return False

quentel...@wanadoo.fr

unread,
Dec 13, 2005, 5:30:01 AM12/13/05
to
Ok, I'll explain why I wanted to test if the value was a boolean

I have a program that generates HTML tags with attributes. The
principle is that
TAG('text',arg1=val1,arg2=val2)
generates
<TAG arg1="val1" arg2="val2">text</TAG>

For HTML attributes that don't have an explicit value (such as the
SELECTED attribute in OPTION) the keyword argument to the function must
have the value True

My program has a class for each tag, all derived from a generic TAG
class whose __init__ method takes the arguments :
def __init__(self, innerHTML="", **attrs):

I have to handle differently the cases where the value is a boolean or
another type:
- if it's a boolean then if the value is True, generate the argument
name ; if the value is False, don't generate anything
- if it's not a boolean, generate arg="val". Specifically, it val is 0,
generate val = "0"

Testing with "if v:" as suggested would fail for val = 0

Anyway, I exposed my silly "if v in [True,False]" just to give my
opinion that I found confusing that
0 in [True,False]
or (boolean type checking set aside)
0 in [1,range(2),False,'text']

return True

Regards,
Pierre

bon...@gmail.com

unread,
Dec 13, 2005, 5:30:16 AM12/13/05
to

Erik Max Francis wrote:
> bon...@gmail.com wrote:
>
> > True too, and could be the reason(or similar too) why the OP wants to
> > test the type rather than the logical value of it.
>
> The type is for the self-documentation purposes. The value is the same;
> so no, that's not a good reason either.
>
I don't know why he wants it, let alone whether it is a good or bad
reason. The only thing I read from his post is that he wants to
distinguish the type, why and how it fits in his big picture, no one
but he knows. It could be for similar reason, say to document the
content of data, store it in text file, translate it to another
language(say converting python object to js object but I forgot if
javascript treat 0/1 the same way as python).

quentel...@wanadoo.fr

unread,
Dec 13, 2005, 5:33:09 AM12/13/05
to
Thanks for the link Carsten, the explanation is clear

I didn't know where to search in the Python documentation, there isn't
a section about keywords (always wondered why without daring to say -
now it's done). So I typed ' "in" operator Python ' in Google, which
gave :
- on the first page a link to AM Kuchling's and Moshe Zadka's "What's
new in Python 2.0" which said :
"obj in seq returns true if obj is present in the sequence seq; Python
computes this by simply trying every index of the sequence until either
obj is found or an IndexError is encountered"
- on the second page a link to the Python tutorial that says : "The
comparison operators in and not in check whether a value occurs (does
not occur) in a sequence"

I couldn't tell if "present in the sequence" or "obj is found" or
"occurs/does not occur in a sequence" meant "is equal to" or "is the
same object as". The answer you pointed me to is clear, but for some
reason I didn't have the idea of looking in the section "Sequence Types
-- str, unicode, list, tuple, buffer, xrange" for the definition of
"in" (after all "in" is also used in list comprehensions, generator
expressions, exec, etc... and for iteration on iterators)

Regards,
Pierre

Duncan Booth

unread,
Dec 13, 2005, 5:40:21 AM12/13/05
to
wrote:

> For HTML attributes that don't have an explicit value (such as the
> SELECTED attribute in OPTION) the keyword argument to the function must
> have the value True
>

A better way to do this (given that HTML defines exactly which attributes
do not take a value) is to use the attribute name and simply generate the
attribute only if the value is non-false.

From Zope's TAL parser:

BOOLEAN_HTML_ATTRS = [
# List of Boolean attributes in HTML that may be given in
# minimized form (e.g. <img ismap> rather than <img ismap="">)
# From http://www.w3.org/TR/xhtml1/#guidelines (C.10)
"compact", "nowrap", "ismap", "declare", "noshade", "checked",
"disabled", "readonly", "multiple", "selected", "noresize",
"defer"
]

EMPTY_HTML_TAGS = [
# List of HTML tags with an empty content model; these are
# rendered in minimized form, e.g. <img />.
# From http://www.w3.org/TR/xhtml1/#dtds
"base", "meta", "link", "hr", "br", "param", "img", "area",
"input", "col", "basefont", "isindex", "frame",
]

Ron Griswold

unread,
Dec 13, 2005, 5:28:39 AM12/13/05
to pytho...@python.org
I haven't read all of the responses to this thread, so perhaps this has
already been suggested. But it occurs to me that if one needs to
determine whether a variable is a bool or int it could be done like so:

>>> Booltype = False
>>> var = 0
>>> Booltype == var
True
>>> Booltype.__class__ == var.__class__
False

Ron Griswold
Character TD
R!OT Pictures
rgri...@rioting.com

Fredrik Lundh

unread,
Dec 13, 2005, 5:39:21 AM12/13/05
to pytho...@python.org
Duncan Booth wrote:

> Another reason to have a boolean type is of course to provide a cast:
>
> def isNameSet(self):
> return boolean(self.name)
>
> instead of:
>
> def isNameSet(self):
> if self.name:
> return True
> else:
> return False

given that Python already had a function for this, that wasn't
much of a reason:

>>> help(operator.truth)
Help on built-in function truth in module operator:

truth(...)
truth(a) -- Return True if a is true, False otherwise.

(truth returned 1 or 0 in pre-boolean versions)

(btw, instead of speculating about the rationale, why don't you all
go and read Guido's PEP ?)

</F>

bon...@gmail.com

unread,
Dec 13, 2005, 5:48:59 AM12/13/05
to

Fredrik Lundh wrote:
> Duncan Booth wrote:
>
> > Another reason to have a boolean type is of course to provide a cast:
> >
> > def isNameSet(self):
> > return boolean(self.name)
> >
> > instead of:
> >
> > def isNameSet(self):
> > if self.name:
> > return True
> > else:
> > return False
>
> given that Python already had a function for this, that wasn't
> much of a reason:
>
> >>> help(operator.truth)
> Help on built-in function truth in module operator:
>
> truth(...)
> truth(a) -- Return True if a is true, False otherwise.
>
> (truth returned 1 or 0 in pre-boolean versions)
>
I see you skip another use case of XMLRPC Duncan mentioned, is that a
valid reason ?

Fredrik Lundh

unread,
Dec 13, 2005, 5:53:59 AM12/13/05
to pytho...@python.org
Duncan Booth wrote:
>
> > For HTML attributes that don't have an explicit value (such as the
> > SELECTED attribute in OPTION) the keyword argument to the function must
> > have the value True
>
> A better way to do this (given that HTML defines exactly which attributes
> do not take a value) is to use the attribute name and simply generate the
> attribute only if the value is non-false.

footnote: strictly speaking, minimized attributes have values but no names;
it's up to the parser to determine what attribute you're setting when you
specify the value.

(for example, in <img ismap>, "ismap" is the value, not the attribute name.
it's up to the parser to figure out (from the DTD) that this value can only
be used by the "ismap" attribute, and interpret it as <img ismap=ismap>)

</F>

Fredrik Lundh

unread,
Dec 13, 2005, 5:57:51 AM12/13/05
to pytho...@python.org
bon...@gmail.com wrote:

> I see you skip another use case of XMLRPC Duncan mentioned, is that a
> valid reason ?

the PEP has the answer. also see my reply to Erik Max Francis:

http://groups.google.com/group/comp.lang.python/msg/adb5e9389ea20b3c

(the silly Boolean class in that post is taken from Python's xmlrpclib library)

</F>

Stefan Rank

unread,
Dec 13, 2005, 6:04:19 AM12/13/05
to pytho...@python.org
on 13.12.2005 11:39 Fredrik Lundh said the following:

> Duncan Booth wrote:
>>Another reason to have a boolean type is of course to provide a cast:
>>
>> def isNameSet(self):
>> return boolean(self.name)
[snip]

>
> given that Python already had a function for this, that wasn't
> much of a reason:
>
>>>>help(operator.truth)
>
> Help on built-in function truth in module operator:
>
> truth(...)
> truth(a) -- Return True if a is true, False otherwise.
>
[snip]

As operator.truth() is equivalent to bool()
and as it is the only thing in operator that is not really reflecting an
operator, I had a look into PEP3000 to see if (the redundant)
operator.truth is going to be removed. It is not mentioned.

(not that I really care, but I thought I could provide something
productively new to discuss about, to end the "why is bool an int?"
discussion ;-)

stefan

Fredrik Lundh

unread,
Dec 13, 2005, 6:21:32 AM12/13/05
to pytho...@python.org
Duncan Booth wrote:

> A better way to do this (given that HTML defines exactly which attributes
> do not take a value) is to use the attribute name and simply generate the
> attribute only if the value is non-false.

another approach (which may or may not be suitable in this case) is to
use the presence of an attribute in the dictionary as an indication that
it should be included in the file, and use the special value None to mean
that it should be minimized.

yet another approach is to use an existing HTML serialization library, and
do whatever they do.

</F>

Antoon Pardon

unread,
Dec 13, 2005, 6:29:10 AM12/13/05
to

Why? It won't break my code.

> Note, though, that True and False are defined to be singleton instances,
> so it *is* permissible to say
>
> if i is False:
>
> >>> 0 is False
> False
> >>> 1 is True
> False
> >>>
>
> However I must say the coupling in that interface has a very definite
> code smell. Why not use two variables, a Boolean "registered" and an
> integer ID that is meaningless when registered is False?

Because the integer ID can be meaningless when registered is True.
If I should use two variables, the "registered" variable should
be a three value variable. Something like:

0: Not registered by the user
1: Registered by the user but no internal idle callback registerd
2: internal idle callback registerd

Only in the last case is the integer ID meaningfull. But IMO I buy
nothing buy seperating the information over two variables. Checking
whether the "registered" variable is 2 or not, doesn't buy me
anything over checking whether the cb_src is of BooleanType or
not.

And having the information in one variable means I have to worry
less about synchronisation. If I register the internal idle
handler I just store its ID in cb_src, without having to worry
about another variable that has to be set right.

--
Antoon Pardon

Chris Mellon

unread,
Dec 13, 2005, 9:08:45 AM12/13/05
to pytho...@python.org

This is the sort of horrible smelly wretchedness that makes me gag in
C. Bearing in mind that you of course are free to write your code in
whatever way you want, and I'm not your boss, this is horrible and
shouldn't be considered something to be catered for.

First and most importantly, you're replacing a literate,
self-documenting mechanism with an obtuse one.

if self.userRegisteredCallback:

is much, much better than

if type(self.callback) is bool:


If you have a consistent API and you're checking for error values from
your GTK functions, then you already have a lot more code than using 2
varaibles will cost you. 10 lines, maybe.

The fact that you think setting two variables is "too hard" but you're
perfectly happy with checking for boolean types instead just testing
truth values I think is a real problem. You aren't saving yourself any
performance. You're barely even saving yourself any typing, and you're
making your code (intentionally, it seems) that much more compllicated
and hard to understand.

Granted, of course, it's your code. But I wouldn't accept it in
anything I was in charge of.


> --
> Antoon Pardon
> --
> http://mail.python.org/mailman/listinfo/python-list
>

bon...@gmail.com

unread,
Dec 13, 2005, 9:44:03 AM12/13/05
to

Chris Mellon wrote:
> Granted, of course, it's your code. But I wouldn't accept it in
> anything I was in charge of.
>
That says it all. It is his code, whether you would accept it means
nothing. If you can point out that it is functionally wrong, it may
mean something. Otherise, it is nothing more than "I prefer it this
way". It may be hard to understand, hard to maintain(probably by
others, probably by him a few years down the road) but no one(other
than him) knows what the program is about so whether it needs to be
touched again.

Antoon Pardon

unread,
Dec 13, 2005, 10:08:56 AM12/13/05
to
Op 2005-12-13, Chris Mellon schreef <ark...@gmail.com>:

Well either your self-documenting code is not that obvious or
your code doesn't make the same disctinction than the one
you want to replace it with.

And if you want self documenting code then I guess I could rewrite
it as follows

if type(self.callback) is not GtkID:

> If you have a consistent API and you're checking for error values from
> your GTK functions, then you already have a lot more code than using 2
> varaibles will cost you. 10 lines, maybe.
>
> The fact that you think setting two variables is "too hard" but you're
> perfectly happy with checking for boolean types instead just testing
> truth values I think is a real problem.

These aren't just truth values. If I would have to go split in
meaningfull truth values I would need at least three variables.

> You aren't saving yourself any
> performance. You're barely even saving yourself any typing, and you're
> making your code (intentionally, it seems) that much more compllicated
> and hard to understand.

There is nothing complicated or hard to understand.

I find it odd that each time declaration are mentioned people here
react very rejecting and say that one of the features they love
about python is the freedom that a name is not limited to a variable
of one type, while when someone makes use of that freedom labeling
such code as code smell.

But lets make an effort to make the code more readable. What
about the following suggestion. I use a kind of EnumType with
two values: NotRegistered and Registerd. And the name of the
type is NotConnected. So I can then write

if type(self.callback) is NotConnected.

Would that be selfdocumenting enough for you?

--
Antoon Pardon

Grant Edwards

unread,
Dec 13, 2005, 10:18:54 AM12/13/05
to
On 2005-12-13, bon...@gmail.com <bon...@gmail.com> wrote:
>
> Fredrik Lundh wrote:
>> bon...@gmail.com wrote:
>>
>> > > but seriously, unless you're writing an introspection tool, testing for
>> > > bool is pretty silly. just use "if v" or "if not v", and leave the rest to
>> > > Python.
>> > >
>> > The OP's code(and his work around) doesn't look like he is testing for
>> > boolean
>>
>> which of course explains why he wrote

>>
>> In some program I was testing if a variable was a boolean
>>
>> in the post I replied to...
>>
>> > but more like the data type of something. I thought there is some idiom
>> > in python which said something like "don't assume" ?
>>
>> "think before you post" ?
>>
> Don't know what you mean.
>
> He seems to be testing "boolean type", not whether it is true
> or false.

Right. But that's almost always pointless. Knowing whether a
variable is a boolean or not is very rarely useful. What one
wants to know is whether a varible is true or not. The code for
that is:

if v:
something

if not v:
something

--
Grant Edwards grante Yow! My DIGITAL WATCH
at has an automatic SNOOZE
visi.com FEATURE!!

Grant Edwards

unread,
Dec 13, 2005, 10:20:27 AM12/13/05
to
On 2005-12-13, Paul Rubin <> wrote:
> Steve Holden <st...@holdenweb.com> writes:

>> The really interesting question your post raises, though, is

>> "Why do you feel it's necessary to test to see whether a
>> variable is a Boolean?".


>
> What's the point of having Booleans, if you can't tell them
> from integers?

You _can_ tell them from integers. The point is that thinking
you need to in "normal" code is usually wrong. Or at least
unpythonic.

--
Grant Edwards grante Yow! It's NO USE... I've
at gone to "CLUB MED"!!
visi.com

bon...@gmail.com

unread,
Dec 13, 2005, 10:28:33 AM12/13/05
to

Grant Edwards wrote:
> > He seems to be testing "boolean type", not whether it is true
> > or false.
>
> Right. But that's almost always pointless. Knowing whether a
> variable is a boolean or not is very rarely useful. What one
> wants to know is whether a varible is true or not. The code for
> that is:
>
> if v:
> something
>
> if not v:
> something
>
He doesn't want to know whether a variable is true or not, but whether
it is a boolean value. He seems to use the same variable to store both
boolean value, as well as other data type(see another post by OP) for
distinct meaning. Whether this is a good design is another matter and
debatable. Within Python, I think it is not needed as 1/0 and
True/False are basically interchangeable no matter where it is used.

Mike Meyer

unread,
Dec 13, 2005, 11:07:29 AM12/13/05
to

But this isn't necessarilly true: <img alt=ismap> is perfectly legal.
I would say that ismap only has one valid value - "ismap", so the
parser knows that it should interepret a bare "ismap" as ismap=ismap,
which gets you the same behavior in the end.

<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

Fredrik Lundh

unread,
Dec 13, 2005, 11:33:32 AM12/13/05
to pytho...@python.org
Mike Meyer wrote:

> > (for example, in <img ismap>, "ismap" is the value, not the attribute name.
> > it's up to the parser to figure out (from the DTD) that this value can only
> > be used by the "ismap" attribute, and interpret it as <img ismap=ismap>)
>
> But this isn't necessarilly true: <img alt=ismap> is perfectly legal.
> I would say that ismap only has one valid value - "ismap", so the
> parser knows that it should interepret a bare "ismap" as ismap=ismap,
> which gets you the same behavior in the end.

I think you could have figured out what I meant, but alright, replace
value with "enumeration value". the "alt" attribute isn't an enumeration,
and cannot be minimized.

the point is that SGML lets you say things like

"format can be one of A4, Letter, or Legal"

and then set the format simply by saying

<document letter>

on the other hand, this means that you cannot say things like

"paper can be one of A4, Letter, or Legal"
"pdf-size can be one of A4, Letter, or Legal"

and use minimization for these attributes.

(unless I'm missing some obscure corner of the spec, HTML only uses
attribute minimization for boolean attributes, so exactly how this is
done doesn't really matter. I'll better go *plonk* myself now...)

</F>

Steve Holden

unread,
Dec 13, 2005, 12:28:58 PM12/13/05
to pytho...@python.org
Antoon Pardon wrote:
> Op 2005-12-13, Chris Mellon schreef <ark...@gmail.com>:
[...]

>>If you have a consistent API and you're checking for error values from
>>your GTK functions, then you already have a lot more code than using 2
>>varaibles will cost you. 10 lines, maybe.
>>
>>The fact that you think setting two variables is "too hard" but you're
>>perfectly happy with checking for boolean types instead just testing
>>truth values I think is a real problem.
>
>
> These aren't just truth values. If I would have to go split in
> meaningfull truth values I would need at least three variables.
>
>
>>You aren't saving yourself any
>>performance. You're barely even saving yourself any typing, and you're
>>making your code (intentionally, it seems) that much more compllicated
>>and hard to understand.
>
>
> There is nothing complicated or hard to understand.
>
Nope, just a messy, hard to maintain misuse of a single variable for
multiple purposes. Perfectly simple, perfectly easy to understand and
rather more bug-prone that a straightforward separation of state and
other data.

> I find it odd that each time declaration are mentioned people here
> react very rejecting and say that one of the features they love
> about python is the freedom that a name is not limited to a variable
> of one type, while when someone makes use of that freedom labeling
> such code as code smell.
>

There's a difference between using a single name to refer to values of
polymorphic types (which can therefore all be handled by the same code)
and using the same name to reference state information in one case (this
item has no connected callback) and other data (the callback is to
such-and-such an object).

> But lets make an effort to make the code more readable. What
> about the following suggestion. I use a kind of EnumType with
> two values: NotRegistered and Registerd. And the name of the
> type is NotConnected. So I can then write
>
> if type(self.callback) is NotConnected.
>
> Would that be selfdocumenting enough for you?
>

It would be somewhat more self-documenting, but why not just use one
name to indicate the state and another, only meaningful in certain
states, to indicate the callback?

Xavier Morel

unread,
Dec 13, 2005, 1:02:09 PM12/13/05
to
Mike Meyer wrote:
> But this isn't necessarilly true: <img alt=ismap> is perfectly legal.
>
> <mike

Legal but irrelevant since the ALT attribute cannot be minimized.

Steven D'Aprano

unread,
Dec 13, 2005, 4:15:28 PM12/13/05
to
On Tue, 13 Dec 2005 09:46:30 +0000, Steve Holden wrote:

> Paul Rubin wrote:
>> Steve Holden <st...@holdenweb.com> writes:
>>
>>>The really interesting question your post raises, though, is "Why do

>>>you feel it's necessary to test to see whether a variable is a


>>>Boolean?".
>>
>>
>> What's the point of having Booleans, if you can't tell them from integers?
>

> Booleans are specifically defined as a subtype of int at the C level.

That's an implementation detail, and in fact an explicit decision made,
not a inescapable fact of programming. What you are saying is,
effectively, the point of having bools which are subclasses of ints is
that Guido wanted them that way.


> One might also ask "what's the point of having floats if you can't tell
> them from integers":

But you certainly can:

py> isinstance(True, int)
True
py> isinstance(0.0, int)
False

However, you can also ask:

py> isinstance(True, bool)
True
py> isinstance(1, bool)
False

or even:

py> type(True) == type(1)
False

but, I believe, using type() is frowned upon.

--
Steven

Antoon Pardon

unread,
Dec 14, 2005, 2:55:34 AM12/14/05
to
Op 2005-12-13, Steve Holden schreef <st...@holdenweb.com>:
> Antoon Pardon wrote:
>> Op 2005-12-13, Chris Mellon schreef <ark...@gmail.com>:
> [...]
>>>If you have a consistent API and you're checking for error values from
>>>your GTK functions, then you already have a lot more code than using 2
>>>varaibles will cost you. 10 lines, maybe.
>>>
>>>The fact that you think setting two variables is "too hard" but you're
>>>perfectly happy with checking for boolean types instead just testing
>>>truth values I think is a real problem.
>>
>>
>> These aren't just truth values. If I would have to go split in
>> meaningfull truth values I would need at least three variables.
>>
>>
>>>You aren't saving yourself any
>>>performance. You're barely even saving yourself any typing, and you're
>>>making your code (intentionally, it seems) that much more compllicated
>>>and hard to understand.
>>
>>
>> There is nothing complicated or hard to understand.
>>
> Nope, just a messy, hard to maintain misuse of a single variable for
> multiple purposes.

No that variable has just one purpose, noting the state of the tube.

> Perfectly simple, perfectly easy to understand and
> rather more bug-prone that a straightforward separation of state and
> other data.

What you call other date is IMO just state information.

>> I find it odd that each time declaration are mentioned people here
>> react very rejecting and say that one of the features they love
>> about python is the freedom that a name is not limited to a variable
>> of one type, while when someone makes use of that freedom labeling
>> such code as code smell.
>>
> There's a difference between using a single name to refer to values of
> polymorphic types (which can therefore all be handled by the same code)
> and using the same name to reference state information in one case (this
> item has no connected callback) and other data (the callback is to
> such-and-such an object).
>
>> But lets make an effort to make the code more readable. What
>> about the following suggestion. I use a kind of EnumType with
>> two values: NotRegistered and Registerd. And the name of the
>> type is NotConnected. So I can then write
>>
>> if type(self.callback) is NotConnected.
>>
>> Would that be selfdocumenting enough for you?
>>
> It would be somewhat more self-documenting, but why not just use one
> name to indicate the state and another, only meaningful in certain
> states, to indicate the callback?

Why should I do that? Checking the type of a variable is conceptually
no different form testing set membership. So what I did, was just
bringing two disjoint sets togther and working with a variable from
that union. This is all in all a rather simple mathematical idea.
And I don't see why I should put certain information into a seperate
variable. It makes as much sense as working with numbers and using
a seperate variable to store whether a particular number is postive,
even or has some other characteristic. You don't seperate information
you can easily acquire from the variable itself. So why should I
seperate this information that is aquired just as easily?

--
Antoon Pardon

Steve Holden

unread,
Dec 14, 2005, 3:45:02 AM12/14/05
to pytho...@python.org
Antoon Pardon wrote:
> Op 2005-12-13, Steve Holden schreef <st...@holdenweb.com>:
[...]

>>
>>>But lets make an effort to make the code more readable. What
>>>about the following suggestion. I use a kind of EnumType with
>>>two values: NotRegistered and Registerd. And the name of the
>>>type is NotConnected. So I can then write
>>>
>>> if type(self.callback) is NotConnected.
>>>
>>>Would that be selfdocumenting enough for you?
>>>
>>
>>It would be somewhat more self-documenting, but why not just use one
>>name to indicate the state and another, only meaningful in certain
>>states, to indicate the callback?
>
>
> Why should I do that? Checking the type of a variable is conceptually
> no different form testing set membership. So what I did, was just
> bringing two disjoint sets togther and working with a variable from
> that union. This is all in all a rather simple mathematical idea.
> And I don't see why I should put certain information into a seperate
> variable. It makes as much sense as working with numbers and using
> a seperate variable to store whether a particular number is postive,
> even or has some other characteristic. You don't seperate information
> you can easily acquire from the variable itself. So why should I
> seperate this information that is aquired just as easily?
>

Well, as you might argue, I'm not tryng to effect a change in your
behaviour, I'm simply trying to point out how it could be made more
rational.

bon...@gmail.com

unread,
Dec 14, 2005, 3:56:48 AM12/14/05
to

Steve Holden wrote:
> >>It would be somewhat more self-documenting, but why not just use one
> >>name to indicate the state and another, only meaningful in certain
> >>states, to indicate the callback?
> >
> >
> > Why should I do that? Checking the type of a variable is conceptually
> > no different form testing set membership. So what I did, was just
> > bringing two disjoint sets togther and working with a variable from
> > that union. This is all in all a rather simple mathematical idea.
> > And I don't see why I should put certain information into a seperate
> > variable. It makes as much sense as working with numbers and using
> > a seperate variable to store whether a particular number is postive,
> > even or has some other characteristic. You don't seperate information
> > you can easily acquire from the variable itself. So why should I
> > seperate this information that is aquired just as easily?
> >
>
> Well, as you might argue, I'm not tryng to effect a change in your
> behaviour, I'm simply trying to point out how it could be made more
> rational.
>
What would be the difference in his usage and allowing Null in a RDBMS
column ? Or return NaN instead of raising exception for numeric
functions ?

Antoon Pardon

unread,
Dec 14, 2005, 3:56:56 AM12/14/05
to
Op 2005-12-14, Steve Holden schreef <st...@holdenweb.com>:
> Antoon Pardon wrote:

>>>It would be somewhat more self-documenting, but why not just use one
>>>name to indicate the state and another, only meaningful in certain
>>>states, to indicate the callback?
>>
>>
>> Why should I do that? Checking the type of a variable is conceptually
>> no different form testing set membership. So what I did, was just
>> bringing two disjoint sets togther and working with a variable from
>> that union. This is all in all a rather simple mathematical idea.
>> And I don't see why I should put certain information into a seperate
>> variable. It makes as much sense as working with numbers and using
>> a seperate variable to store whether a particular number is postive,
>> even or has some other characteristic. You don't seperate information
>> you can easily acquire from the variable itself. So why should I
>> seperate this information that is aquired just as easily?
>>
>
> Well, as you might argue, I'm not tryng to effect a change in your
> behaviour, I'm simply trying to point out how it could be made more
> rational.

I guess we will just have to agree to disagree on what is more rational
in this case. Maybe it is just a case of what idiom one is used to.

--
Antoon Pardon

Grant Edwards

unread,
Dec 14, 2005, 9:57:13 AM12/14/05
to
On 2005-12-14, bon...@gmail.com <bon...@gmail.com> wrote:

>> Well, as you might argue, I'm not tryng to effect a change in your
>> behaviour, I'm simply trying to point out how it could be made more
>> rational.
>
> What would be the difference in his usage and allowing Null in a RDBMS
> column?

Don't know -- homey don't play 'dat.

> Or return NaN instead of raising exception for numeric
> functions ?

Because usually (in my applications anyway) NaN is a perfectly
valid value and not an "exception" case that needs to be handled.

--
Grant Edwards grante Yow! Am I in GRADUATE
at SCHOOL yet?
visi.com

Antoon Pardon

unread,
Dec 14, 2005, 10:07:03 AM12/14/05
to
Op 2005-12-14, Grant Edwards schreef <gra...@visi.com>:

> On 2005-12-14, bon...@gmail.com <bon...@gmail.com> wrote:
>
>>> Well, as you might argue, I'm not tryng to effect a change in your
>>> behaviour, I'm simply trying to point out how it could be made more
>>> rational.
>>
>> What would be the difference in his usage and allowing Null in a RDBMS
>> column?
>
> Don't know -- homey don't play 'dat.
>
>> Or return NaN instead of raising exception for numeric
>> functions ?
>
> Because usually (in my applications anyway) NaN is a perfectly
> valid value and not an "exception" case that needs to be handled.

I don't see the difference. In my application False and True
(or Registered and UnRegistered if you prefer) are perfectly valid
values too. They are not "exception" cases that need to be
handled.

--
Antoon Pardon

Grant Edwards

unread,
Dec 14, 2005, 10:37:30 AM12/14/05
to
On 2005-12-14, Antoon Pardon <apa...@forel.vub.ac.be> wrote:

>>>> Well, as you might argue, I'm not tryng to effect a change in
>>>> your behaviour, I'm simply trying to point out how it could be
>>>> made more rational.

[...]


>>> Or return NaN instead of raising exception for numeric
>>> functions ?
>>
>> Because usually (in my applications anyway) NaN is a perfectly
>> valid value and not an "exception" case that needs to be
>> handled.
>
> I don't see the difference. In my application False and True
> (or Registered and UnRegistered if you prefer) are perfectly
> valid values too. They are not "exception" cases that need to
> be handled.

Well, in my case, a given name (or return value) is always
bound to a floating point object. I don't test the type of the
object and treat it in two different ways depending on what
type it is. It's just a float.

--
Grant Edwards grante Yow! .. Do you like
at "TENDER VITTLES?"?
visi.com

Mike Meyer

unread,
Dec 14, 2005, 12:29:28 PM12/14/05
to

Having a value to indicate "no value" is, of course, perfectly
reasonable. However, you then test *for that value*; you don't test
the type of the value to see if it's of the right type.

Once you get beyond the variable either having a valid value or not,
it's really time to consider a different approach. As has been
indicated, using two variables is ba well-respected method of doing
this. Another alternative (on the spur of the moment - I have no idea
how well this will really work) is a value-carrying "invalid value":

# untested code:
class Invalid:
state = 'unknown'

...

if self.count is Invalid:
if self.count.state == 'unregistered':
# Register self.
elif self.count.state == 'registered':
# Whatever
else:
# Deal with self.count outstanding requests

Hmm. I'm not sure I like this...

bon...@gmail.com

unread,
Dec 14, 2005, 4:59:09 PM12/14/05
to
He doesn't need to test the type, in this case.

if self.count is False:
elif self.count is True:
else:

The alternative suggested :

if self.state is False:
elif self.state is True:
else: deal with self.count

I don't see much difference. He can also use a better name to represent
True/False.

Registered=True
UnRegistered=False

Antoon Pardon

unread,
Dec 15, 2005, 2:52:51 AM12/15/05
to
Op 2005-12-14, Grant Edwards schreef <gra...@visi.com>:

Do you find that difference so important? As far as I understand
the gtk identifiers are always positive integers. So I could
have coded as follows:

UnConnected = (-1, -2)
Registered, UnRegistered = UnConnected

...

if self.cb_src in UnConnected:

Now all values are integers and I no longer treat an object different
depending on type but on value. However conceptually nothing changed.
My code branches depending on set membership of this attribute.

Could you explain why it should make a (big) difference between
these two approaches?

--
Antoon Pardon

bon...@gmail.com

unread,
Dec 15, 2005, 3:07:12 AM12/15/05
to
That is what I would do in C or similar language where a variable can
only be one type.

Antoon Pardon

unread,
Dec 15, 2005, 3:04:32 AM12/15/05
to
Op 2005-12-14, Mike Meyer schreef <m...@mired.org>:

How do you feel about testing for set membership? I can have a set
with values to be treated differently than values not in the set.
Do you consider that an acceptable approach?

--
Antoon Pardon

Grant Edwards

unread,
Dec 15, 2005, 9:25:45 AM12/15/05
to
On 2005-12-15, Antoon Pardon <apa...@forel.vub.ac.be> wrote:

>>>>> Or return NaN instead of raising exception for numeric
>>>>> functions ?
>>>>
>>>> Because usually (in my applications anyway) NaN is a perfectly
>>>> valid value and not an "exception" case that needs to be
>>>> handled.
>>>
>>> I don't see the difference. In my application False and True
>>> (or Registered and UnRegistered if you prefer) are perfectly
>>> valid values too. They are not "exception" cases that need to
>>> be handled.
>>
>> Well, in my case, a given name (or return value) is always
>> bound to a floating point object. I don't test the type of the
>> object and treat it in two different ways depending on what
>> type it is. It's just a float.
>
> Do you find that difference so important?

Possibly. In my case, a float is always a float. You can
always do the same set of operations on it.

> As far as I understand
> the gtk identifiers are always positive integers. So I could
> have coded as follows:
>
> UnConnected = (-1, -2)
> Registered, UnRegistered = UnConnected

In your case, there isn't a single set of operations that work
regardles of the value. You have to _check_ the value in order
to decide what operations are allowed on that value. I'm not
saying the latter is "evil" but I think the distinction is
important.

> ...
>
> if self.cb_src in UnConnected:
>
> Now all values are integers and I no longer treat an object different
> depending on type but on value. However conceptually nothing changed.
> My code branches depending on set membership of this attribute.
>
> Could you explain why it should make a (big) difference between
> these two approaches?

Your examples are still both very different from the NaN
example. A NaN is a floating point operation that supports all
the same operations as all other floating point operations. In
your example an integer object of -2 does not support the same
"operations" that a "real" GTK identifier does. They are two
different types.

--
Grant Edwards grante Yow! Hey, wait a
at minute!! I want a
visi.com divorce!!... you're not
Clint Eastwood!!

Antoon Pardon

unread,
Dec 16, 2005, 4:43:11 AM12/16/05
to
Op 2005-12-15, Grant Edwards schreef <gra...@visi.com>:

I think the disctinction you are making is based on which level
you look at things. For you floats are something you use, you
see NaN as just a floats because the details of implementation
have been abstracted out for you.

But look at it from the level of someone who has to implement
floating point numbers. He can't just take two floats and put
them into his general add_float algorithm. If he did that
the result of working with a NaN could result in a regular
number. So he has to test for special values like NaN is
his 'code' too.

Of course we tend to forget this because in this case the
abstraction is usually done at the hardware level. But
I don't think that is such an important disctinction here.

--
Antoon Pardon

Grant Edwards

unread,
Dec 16, 2005, 8:47:00 AM12/16/05
to
On 2005-12-16, Antoon Pardon <apa...@forel.vub.ac.be> wrote:

>> Your examples are still both very different from the NaN
>> example. A NaN is a floating point operation that supports all
>> the same operations as all other floating point operations. In
>> your example an integer object of -2 does not support the same
>> "operations" that a "real" GTK identifier does. They are two
>> different types.
>
> I think the disctinction you are making is based on which level
> you look at things.

Of course. I was looking at things from a Python point of view
since this is c.l.p.

> For you floats are something you use, you see NaN as just a
> floats because the details of implementation have been
> abstracted out for you.

That goes without saying for anything in computer science or
electronics: it's all just quantum physics whose details of
implimentation have been abstracted out for me.

> But look at it from the level of someone who has to implement
> floating point numbers. He can't just take two floats and put
> them into his general add_float algorithm. If he did that the
> result of working with a NaN could result in a regular number.
> So he has to test for special values like NaN is his 'code'
> too.
>
> Of course we tend to forget this because in this case the
> abstraction is usually done at the hardware level. But I don't
> think that is such an important disctinction here.

The distinction is in regards to readability and
maintainability of _Python_ code. This is comp.lang.python.

--
Grant Edwards grante Yow! does your DRESSING
at ROOM have enough ASPARAGUS?
visi.com

Reply all
Reply to author
Forward
0 new messages