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

Question About Logic In Python

P: n/a
Greetings! I'm new to Python and am struggling a little with "and" and
"or" logic in Python. Since Python always ends up returning a value
and this is a little different from C, the language I understand best
(i.e. C returns non-zero as true, and zero as false), is there anything
I should be aware of given Python's different approach? Namely any
pitfalls or neat tricks that make the Python approach cool or save my
butt.

Thank you!

James

Sep 19 '05 #1
Share this Question
Share on Google+
22 Replies


P: n/a
James H. wrote:
Greetings! I'm new to Python and am struggling a little with "and" and
"or" logic in Python. Since Python always ends up returning a value
and this is a little different from C, the language I understand best
(i.e. C returns non-zero as true, and zero as false), is there anything
I should be aware of given Python's different approach? Namely any
pitfalls or neat tricks that make the Python approach cool or save my
butt.


The most common use of this feature is "x = x or default_val" as a
shorthand for "if not x: x = default_val".

Also, you can emulate C's ternary operator (cond ? t : f) with
(cond and [t] or [f])[0].

Sep 19 '05 #2

P: n/a

James H. wrote:
Greetings! I'm new to Python and am struggling a little with "and" and
"or" logic in Python. Since Python always ends up returning a value
and this is a little different from C, the language I understand best
(i.e. C returns non-zero as true, and zero as false), is there anything
I should be aware of given Python's different approach? Namely any
pitfalls or neat tricks that make the Python approach cool or save my
butt.

Thank you!

James


Booleans are a subtype of plain integers, so if you use them
in arithmetic expressions, they evaluate to 0 and 1.
def bool(): print "Boolean algebra"
print "%9s %9s | %9s %9s %9s" % ('A','B','A and B','A or B','A xor B')
print "-"*51
for a in [False,True]:
for b in [False,True]:
print "%9s %9s | %9s %9s %9s" % (a,b,(a and b),(a or b),((a and not
b) or (not a and b)))
print
print
print "Arithmetic"
print "%9s %9s | %9s %9s %9s" % ('A','B','A + B','A * B','A - B')
print "-"*51
for a in [False,True]:
for b in [False,True]:
print "%9s %9s | %9s %9s %9s" % (a,b,(a + b),(a * b),(a - b))

bool()

Boolean algebra
A B | A and B A or B A xor B
---------------------------------------------------
False False | False False False
False True | False True True
True False | False True True
True True | True True False
Arithmetic
A B | A + B A * B A - B
---------------------------------------------------
False False | 0 0 0
False True | 1 0 -1
True False | 1 0 1
True True | 2 1 0

Sep 19 '05 #3

P: n/a
At 02:20 19.09.2005, James H. wrote:
Greetings! I'm new to Python and am struggling a little with "and" and
"or" logic in Python. Since Python always ends up returning a value
and this is a little different from C, the language I understand best
(i.e. C returns non-zero as true, and zero as false), is there anything
I should be aware of given Python's different approach? Namely any
pitfalls or neat tricks that make the Python approach cool or save my
butt.


to make sure that an operation yields a boolean value wrap a bool()
around an expression.
None, 0 and objects which's len is 0 yield False.
so you can also do stuff like that:
a = []
b = [1,2,3]
a or b [1, 2, 3]
class Foo: .... def __len__(self): return 0
.... class Bar: .... def __len__(self): return 1
.... foo = Foo()
bar = Bar()
foo or bar

<__main__.Bar instance at 0x7D289940>

sven.

Sep 19 '05 #4

P: n/a
On Mon, 19 Sep 2005 12:16:15 +0200, sven wrote:
to make sure that an operation yields a boolean value wrap a bool()
around an expression.
None, 0 and objects which's len is 0 yield False.
so you can also do stuff like that:


Are there actually any usage cases for *needing* a Boolean value? Any
object can be used for truth testing, eg:

if the_str

is to be preferred over:

if bool(the_str)

or even worse:

if bool(the_str != "")

Or wait, I have thought of one usage case: if you are returning a value
that you know will be used only as a flag, you should convert it into a
bool. Are there any other uses for bool()?

--
Steven.

Sep 19 '05 #5

P: n/a
On Mon, 19 Sep 2005 23:46:05 +1000, Steven D'Aprano <st***@REMOVETHIScyber.com.au> wrote:
On Mon, 19 Sep 2005 12:16:15 +0200, sven wrote:
to make sure that an operation yields a boolean value wrap a bool()
around an expression.
None, 0 and objects which's len is 0 yield False.
so you can also do stuff like that:


Are there actually any usage cases for *needing* a Boolean value? Any
object can be used for truth testing, eg:

if the_str

is to be preferred over:

if bool(the_str)

or even worse:

if bool(the_str != "")

Or wait, I have thought of one usage case: if you are returning a value
that you know will be used only as a flag, you should convert it into a
bool. Are there any other uses for bool()?

making an index (it's an int subclass), as in
things = None, 0, 1, 0.0, 5.0, '', 'a', [], [1], {}, {1:2}
for thing in things:

... print 'if %-6r would act like if %s' % (thing, ('False','True')[bool(thing)])
...
if None would act like if False
if 0 would act like if False
if 1 would act like if True
if 0.0 would act like if False
if 5.0 would act like if True
if '' would act like if False
if 'a' would act like if True
if [] would act like if False
if [1] would act like if True
if {} would act like if False
if {1: 2} would act like if True

Regards,
Bengt Richter
Sep 19 '05 #6

P: n/a
Steven D'Aprano wrote:
On Mon, 19 Sep 2005 12:16:15 +0200, sven wrote:

to make sure that an operation yields a boolean value wrap a bool()
around an expression.
None, 0 and objects which's len is 0 yield False.
so you can also do stuff like that:

Are there actually any usage cases for *needing* a Boolean value? Any
object can be used for truth testing, eg:

if the_str

is to be preferred over:

if bool(the_str)

or even worse:

if bool(the_str != "")

Or wait, I have thought of one usage case: if you are returning a value
that you know will be used only as a flag, you should convert it into a
bool. Are there any other uses for bool()?


Of course if any of the default False or True conditions are
inconsistent with the logic you use, you need to do explicit truth testing.

if val > -1:

Where 0 would be True condition.
if arg != None:

Where '' could be a True condition.
Also... you need to be careful what order you do your comparisons in as..

(1 and 2) != (2 and 1) # they are both True, but not equal.

bool(1 and 2) == bool(2 and 1)

(1 and 2) * value != (2 and 1) * value
# except if value is False.

bool(1 and 2) * value == bool(2 and 1) * value
So..

bool(a and b) * value

Would return value or zero, which is usually what I want when I do this
type of expression.

Cheers,
Ron





Sep 20 '05 #7

P: n/a
On Mon, 19 Sep 2005 22:31:05 +0000, Bengt Richter wrote:
On Mon, 19 Sep 2005 23:46:05 +1000, Steven D'Aprano <st***@REMOVETHIScyber.com.au> wrote:
Are there actually any usage cases for *needing* a Boolean value? Any
object can be used for truth testing, eg:
[snip]
making an index (it's an int subclass), as in
>>> things = None, 0, 1, 0.0, 5.0, '', 'a', [], [1], {}, {1:2}
>>> for thing in things:

... print 'if %-6r would act like if %s' % (thing, ('False','True')[bool(thing)])
...


That's a pretty artificial example though. Your general index ranges from
0 to n inclusive, where n is unlikely to be 1. That limits the usefulness
of the idiom sequence_or_mapping[bool(thing)] to a tiny set of cases.

As near as I can tell, explicitly converting objects to booleans is mostly
useful for demonstrating that booleans aren't needed for truth testing.
--
Steven.

Sep 21 '05 #8

P: n/a
On Tue, 20 Sep 2005 03:03:15 +0000, Ron Adam wrote:
Steven D'Aprano wrote:
Are there actually any usage cases for *needing* a Boolean value? Any
object can be used for truth testing, eg:

[snip]
Of course if any of the default False or True conditions are
inconsistent with the logic you use, you need to do explicit truth testing.
[snip]
So..

bool(a and b) * value

Would return value or zero, which is usually what I want when I do this
type of expression.


That's all very interesting, and valuable advice for somebody who doesn't
understand how Python's logical operators work, but the question is, when
would you actually want that type of expression?

In practice, how often do you really care that your truth values have the
specific values 0 and 1 rather than anything false and anything true? In
what circumstances?

--
Steven.

Sep 21 '05 #9

P: n/a
On Wed, 21 Sep 2005 09:03:00 +1000, Steven D'Aprano <st***@REMOVETHIScyber.com.au> wrote:
On Tue, 20 Sep 2005 03:03:15 +0000, Ron Adam wrote:
Steven D'Aprano wrote:
Are there actually any usage cases for *needing* a Boolean value? Any
object can be used for truth testing, eg:


[snip]
Of course if any of the default False or True conditions are
inconsistent with the logic you use, you need to do explicit truth testing.


[snip]
So..

bool(a and b) * value

Would return value or zero, which is usually what I want when I do this
type of expression.


That's all very interesting, and valuable advice for somebody who doesn't
understand how Python's logical operators work, but the question is, when
would you actually want that type of expression?

In practice, how often do you really care that your truth values have the
specific values 0 and 1 rather than anything false and anything true? In
what circumstances?

When you want to use the value as an index fed to something that has a
__getitem__ for which only the values 0 and 1 are valid, e.g., a list
or tuple of length 2, as I tried to illustrate before ;-)

Also, since values 0 and 1 are the values of a bit, you can shift it
and create a mask that encodes many logical values at once, which can
be handy for truth table stuff or perhaps indexing a 2**nbits table
rather than using a tree of nested if/elses to select values.

BTW, you asked
"Are there actually any usage cases for *needing* a Boolean value?"
^^^ ;-)
AFAIK, "one" is enough to make the answer "yes" ;-)

Of course you can use other expressions than bool(x) to get the boolean
value, but you may have to think more about whether (x and 1) will
do it, or whether you should write (x!=0) or, in case x can be None,
perhaps settle on (x and 1 or 0) as an idiom to play safe.
Well, bool(x) is safe, and less typing ;-) OTOH, it's not a hammer for all nails.

Regards,
Bengt Richter
Sep 21 '05 #10

P: n/a
Steven D'Aprano wrote:
So..

bool(a and b) * value

Would return value or zero, which is usually what I want when I do this
type of expression.
That's all very interesting, and valuable advice for somebody who doesn't
understand how Python's logical operators work, but the question is, when
would you actually want that type of expression?
It's a filter which returns a value or zero depending on conditions a and b.

Some examples...

High pass filter:

(value > 0) * value

Low pass filter:

(value < 0) * value

Band pass filter:

(min < value < max) * value
Changing and and or to return bools only, doesn't prevent us from doing
anything we can already do. It just means changing the context to
explicitly return a non bool when you want one as I did here.
In practice, how often do you really care that your truth values have the
specific values 0 and 1 rather than anything false and anything true? In
what circumstances?


We can separate these into two groups...

1. True and false condition testing in which the result of the
condition is not used in any further expressions.

You are correct in this case, it doesn't matter. Any True values would work.

2. Expressions that will be used in a calculation or another
expression.

This matters because if you aren't careful your results may not be what
you expect.

But group (2) can also be a part of group (1). So then again it may
matter there too.

This has more to do with clarity and separating function into forms that
have the potential for least surprises. Or to put it another way, forms
that are predictable with no exceptional circumstances.

In boolean math it is useful to add and subtract.
a = b = True
a + b 2 # Non boolean result.
True * True 1 # Why not return True here as well?

This is like adding two integer types and getting a float.
There's the possibility of adding two (normally) True values and getting
a False result.
a = True
b = -1
a + b # True_value + True = False_value

0
Should bool type act like bools as expressed here?

http://www.ee.surrey.ac.uk/Projects/...w/boolalgebra/

# P1: X = 0 or X = 1
# P2: 0 . 0 = 0
# P3: 1 + 1 = 1
# P4: 0 + 0 = 0
# P5: 1 . 1 = 1
# P6: 1 . 0 = 0 . 1 = 0
# P7: 1 + 0 = 0 + 1 = 1

Table 1: Boolean Postulates

Python's bools work this way if you use 'and' and 'or' and always cast
any non bools to bools first. But it would be easier IMO if bool
operations gave bool results so I wouldn't need to do:

bool_result = a and bool(b)

or

bool_result = bool(a and b)

On one hand these seem like little things, but little things is
sometimes what will bite you the hardest as they are more likely to get
by your guard.

Cheers,
Ron







Sep 21 '05 #11

P: n/a
> On Wed, 21 Sep 2005 09:03:00 +1000, Steven D'Aprano
<st***@REMOVETHIScyber.com.au> wrote:
In practice, how often do you really care that your truth values have the
specific values 0 and 1 rather than anything false and anything true? In
what circumstances?


Another example: you have an exam with N questions and score the answers
True or False. The number correct is the sum of the True/False scores. I
have done things like this in other languages with explicit 1/0 for
True/False.

Terry J. Reedy

Sep 21 '05 #12

P: n/a
On Wed, 21 Sep 2005 18:53:34 +0000, Ron Adam wrote:
Steven D'Aprano wrote:
So..

bool(a and b) * value

Would return value or zero, which is usually what I want when I do this
type of expression.
That's all very interesting, and valuable advice for somebody who doesn't
understand how Python's logical operators work, but the question is, when
would you actually want that type of expression?
It's a filter which returns a value or zero depending on conditions a and b.


Ah, that's a good example, thanks, except I notice you didn't actually
cast to bool in them, eg: (min < value < max) * value

You also said:
In boolean math it is useful to add and subtract. >>> a = b = True
>>> a + b
2 # Non boolean result.


I presume you mean Boolean algebra by "Boolean math". I have to disagree
with you there. It is *not* useful to do addition, subtraction,
multiplication or division in Boolean algebra. Those operations aren't
defined on Booleans, because they return results which aren't Booleans. If
you wanted to extend arithmetic operations on Booleans, you would need to
either redefine addition and multiplication as XOR and AND (as
mathematicians do when they extend Boolean algebras to rings), or do your
arithmetic modulo 2.

I'm not saying that it can't be useful to treat Booleans as if they were
the integers 0 and 1, but in mathematics Booleans are abstract values
distinct from the integers (even when they use the symbols 0 and 1) and
the concept "True plus True is two" is meaningless.

It is useful to read the comments here:

http://www.python.org/doc/2.3/whatsn...tion-bool.html

eg "Python's Booleans were not added for the sake of strict type-checking.
A very strict language such as Pascal would also prevent you performing
arithmetic with Booleans, and would require that the expression in an if
statement always evaluate to a Boolean result."
Should bool type act like bools as expressed here?

http://www.ee.surrey.ac.uk/Projects/...w/boolalgebra/


That is only one possible Boolean algebra, the simplest one. Strictly
speaking, Booleans aren't limited to two values. See
http://en.wikipedia.org/wiki/Boolean_algebra for more detail.

Python's bools aren't Booleans. They are merely aliases for 0 and 1.
--
Steven.

Sep 21 '05 #13

P: n/a
Steven D'Aprano wrote:
Ah, that's a good example, thanks, except I notice you didn't actually
cast to bool in them, eg: (min < value < max) * value
It wasn't needed in these particular examples. But it could be needed
if several comparisons with 'and' between them are used.

It just seems odd to me that:

3 and 2 and 1 -> 1
1 and 2 and 3 -> 3

But that may be because I learned boolean algebra as part of an
electronics logic (computer tech) course dealing with gates in the early
80's.

In boolean math it is useful to add and subtract.
>>> a = b = True
>>> a + b

2 # Non boolean result. I presume you mean Boolean algebra by "Boolean math". I have to disagree
with you there. It is *not* useful to do addition, subtraction,
multiplication or division in Boolean algebra. .... (clip)

Yes, but not quite as strict as True BA would be and not with the strict
type checking other languages have.

I'm not saying that it can't be useful to treat Booleans as if they were
the integers 0 and 1, but in mathematics Booleans are abstract values
distinct from the integers (even when they use the symbols 0 and 1) and
the concept "True plus True is two" is meaningless.

It is useful to read the comments here:

http://www.python.org/doc/2.3/whatsn...tion-bool.html
Thanks and the PEP link from there was useful too.

eg "Python's Booleans were not added for the sake of strict type-checking.
A very strict language such as Pascal would also prevent you performing
arithmetic with Booleans, and would require that the expression in an if
statement always evaluate to a Boolean result."
It doesn't need to be that strict. But a few changes could resolve and
reduce the chance of errors especially for beginners, while not limiting
more advanced uses. These would be Python 3k changes most likely if at all.

1. 'and', 'or', and 'not' always return bool values.

Lots of discussion on this one already. From the look of it, I don't
think it will change. But Guido seemed to suggest its possible with the
addition of a trinary operation. But even with that it wouldn't be done
any time soon.

2. bool == value to be the same as bool == value.__nonzero__()

By doing this comparisons with Bool types will match the behavior of if
conditions without restricting if to strictly bools.

3. Math with bools as both arguments should return bools.

This wouldn't prevent adding bools and ints, or doing other operations
on them. But bools would remain bool types until an operation with a
non bool type.

True * True -> True instead of 1
True * False -> False instead of 0
False * True -> False instead of 0
False * False -> False instead of 0
True * 10 -> 10
False * 10 -> 0
True * 0 -> 0

True + True -> True instead of 2 **changed**
True + False -> True instead of 1
False + True -> True instead of 1
False + False -> False instead of 0
True + 1 = 2
False + 0 = 0

-True -> False instead of -1 **changed**
-False -> True instead of 0 **changed**
1-True -> 0
1-False -> 1
2-True -> 1
2-False -> 2
True-1 -> 0
False-1 -> -1

Notice there is only three places above where the change would be
significantly different than now. All other cases would just exchange
True of 1 or False for 0.

Some operation would need a trinary operation in place of the current
and/or.

person.name = (if name then name else 'default name')

Not my favorite syntax, but I can live with it. It might be possible to
have a short form.

person.name = (name else 'default name')

Should bool type act like bools as expressed here?

http://www.ee.surrey.ac.uk/Projects/...w/boolalgebra/


That is only one possible Boolean algebra, the simplest one. Strictly
speaking, Booleans aren't limited to two values. See
http://en.wikipedia.org/wiki/Boolean_algebra for more detail.


I look at those earlier and was surprised at how complex some Boolean
algebra concepts were. Interesting though, and I'll probably go back
and study it a bit more.

Python's bools aren't Booleans. They are merely aliases for 0 and 1.


Yes, and according to the PEP they were introduced to help reduce
errors. ;-)

Cheers,
Ron
Sep 22 '05 #14

P: n/a
Ron Adam wrote:
Steven D'Aprano wrote:

So..

bool(a and b) * value

Would return value or zero, which is usually what I want when I do this
type of expression.
That's all very interesting, and valuable advice for somebody who doesn't
understand how Python's logical operators work, but the question is, when
would you actually want that type of expression?

It's a filter which returns a value or zero depending on conditions a and b.

Some examples...

High pass filter:

(value > 0) * value

Low pass filter:

(value < 0) * value

Band pass filter:

(min < value < max) * value
Changing and and or to return bools only, doesn't prevent us from doing
anything we can already do. It just means changing the context to
explicitly return a non bool when you want one as I did here.

In practice, how often do you really care that your truth values have the
specific values 0 and 1 rather than anything false and anything true? In
what circumstances?

We can separate these into two groups...

1. True and false condition testing in which the result of the
condition is not used in any further expressions.

You are correct in this case, it doesn't matter. Any True values would work.

2. Expressions that will be used in a calculation or another
expression.

By which you appear to mean "expressions in which Boolean values are
used as numbers".
This matters because if you aren't careful your results may not be what
you expect.
Well yes, but then I wouldn't necessarily expect good results if I tried
to use a nail file as a tyre-lever, either. If you abuse the intent of
anything sufficiently you should expect trouble. But then, you seem to
like trouble ;-)
But group (2) can also be a part of group (1). So then again it may
matter there too.

This has more to do with clarity and separating function into forms that
have the potential for least surprises. Or to put it another way, forms
that are predictable with no exceptional circumstances.

In boolean math it is useful to add and subtract. >>> a = b = True
>>> a + b 2 # Non boolean result.
Quite.
>>> True * True 1 # Why not return True here as well?
Why not return 42? Why not return a picture of a banana?
This is like adding two integer types and getting a float.
No it isn't. It's like trying to multiply April 2 1994 by June 5 2005.
The operation isn't defined. So you choose an arbitrary definition and
say "it would be nice if it worked like this instead of how it actually
does work".

When in fact it doesn't really "work" at all, except for the most
tenuous possible value of "work". It's an accident, because Guido
decided that least code breakage was good when Booleans were introduced.

There's the possibility of adding two (normally) True values and getting
a False result.
>>> a = True
>>> b = -1
>>> a + b # True_value + True = False_value
0

Which is yet another reason why it makes absolutely no sense to apply
arithmetic operations to Boolean values.
Should bool type act like bools as expressed here?

http://www.ee.surrey.ac.uk/Projects/...w/boolalgebra/

# P1: X = 0 or X = 1
# P2: 0 . 0 = 0
# P3: 1 + 1 = 1
# P4: 0 + 0 = 0
# P5: 1 . 1 = 1
# P6: 1 . 0 = 0 . 1 = 0
# P7: 1 + 0 = 0 + 1 = 1

Table 1: Boolean Postulates

Python's bools work this way if you use 'and' and 'or' and always cast
any non bools to bools first. But it would be easier IMO if bool
operations gave bool results so I wouldn't need to do:

bool_result = a and bool(b)

or

bool_result = bool(a and b)
You are, of course, ignoring the huge amount of code breakage this
little change you'd find so convenient would cause.
On one hand these seem like little things, but little things is
sometimes what will bite you the hardest as they are more likely to get
by your guard.

Kindly think again about the vast number of times that Python
programmers have relied on the documented property of "and", which says
that it returns the left operand (without evaluating the right one)
unless the left operand is equivalent to False, in which case it returns
the right operand.

You talk about "least surprises" and "in my opinion" as though your
opinions are the only ones that anyone would dream of holding. This is
in itself quite surprising to me.

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

Sep 22 '05 #15

P: n/a
Steve Holden wrote:
Ron Adam wrote:

2. Expressions that will be used in a calculation or another
expression.

By which you appear to mean "expressions in which Boolean values are
used as numbers".


Or compared to other types, which is common.

This matters because if you aren't careful your results may not be
what you expect.

Well yes, but then I wouldn't necessarily expect good results if I tried
to use a nail file as a tyre-lever, either. If you abuse the intent of
anything sufficiently you should expect trouble. But then, you seem to
like trouble ;-)


Steve... You seem to agree, but think if any one has a problem with
this, it's a misuse or an abuse. Ok. fair enough.

Its not so much I like trouble, It's more that I tend to get stuck on
contradictions and inconsistencies. They bug me. (sometimes I bug
myself as well) ;-)

>>> True * True

1 # Why not return True here as well?

Why not return 42? Why not return a picture of a banana?


My question still stands. Could it be helpful if bools were preserved
in more cases than they are now?

My feelings is that it isn't needed as long as you strictly use your own
modules, functions, and classes, and can depend on the behavior you
decide on. But if you are using routines and object written by others,
you can't always be sure if a values should be treated as a bool or as
an integer. Preserving bools when possible, may help in that regard.

This is like adding two integer types and getting a float.

No it isn't. It's like trying to multiply April 2 1994 by June 5 2005.
The operation isn't defined. So you choose an arbitrary definition and
say "it would be nice if it worked like this instead of how it actually
does work".


Sure, but if we didn't suggest changes, then nothing would change. We
would just have extremely detailed documentation of everything and
strict rules of use so that we don't misuse them. ;-)

When in fact it doesn't really "work" at all, except for the most
tenuous possible value of "work". It's an accident, because Guido
decided that least code breakage was good when Booleans were introduced.
Good point, but it could be changed in Python 3000 since it will drop
the backwards compatible requirement. This doesn't mean that it should
though. The reasons for doing so still need to be sufficient.

There's the possibility of adding two (normally) True values and
getting a False result.
>>> a = True
>>> b = -1
>>> a + b # True_value + True = False_value

0

Which is yet another reason why it makes absolutely no sense to apply
arithmetic operations to Boolean values.


Again you agree, yet disagree. Ok, I see your point about breaking
code, but should this be changed, either throw an exception or by
changing to a boolean operation in Python 3000? You already consider it
an abuse.

You are, of course, ignoring the huge amount of code breakage this
little change you'd find so convenient would cause.
I'm not suggesting anything be changed before Python 3000 which has as a
purpose of changing things that haven't been changed because of
backwards compatibility. And I don't think I'm the only one who has
suggested these.

On one hand these seem like little things, but little things is
sometimes what will bite you the hardest as they are more likely to
get by your guard.

Kindly think again about the vast number of times that Python
programmers have relied on the documented property of "and", which says
that it returns the left operand (without evaluating the right one)
unless the left operand is equivalent to False, in which case it returns
the right operand.


The shortcut behavior would still work, but the returned values would be
either True or False. I agree the above is useful behavior, but I also
see the boolean behavior as desirable. I would like both in clear and
separate contexts if possible.

Guido said the other day on python-dev, he would consider having 'and'
and 'or' return True and False in order to reduce bugs, if a trinary was
also added. It's not as short to type, but the same functionality would
still be present in the language.

Another possibility would be to just add bool operators '||' and '&&'
which would always return True and False and leave 'and' and 'or' as
they are.

You talk about "least surprises" and "in my opinion" as though your
opinions are the only ones that anyone would dream of holding. This is
in itself quite surprising to me.


No, "in my opinion" means exactly that, It's my personal opinion. You
are free and welcome to express "your opinion" as well.

And "least surprises" is, I believe, a good thing to strive for.
Weather or not this would fit that I'm not sure. It's quite possible
that some of these changes would create more surprises not less.

Also these ideas aren't mine, they are fairly standard concepts that
other languages use as well, nothing really new here.

Cheers,
Ron
Sep 22 '05 #16

P: n/a

"Steve Holden" <st***@holdenweb.com> wrote in message
news:dg**********@sea.gmane.org...
Which is yet another reason why it makes absolutely no sense to apply
arithmetic operations to Boolean values.


Except for counting the number of true values. This and other legitimate
uses of False/True as 0/1 (indexing, for instance) were explicitly
considered as *features* of the current design when it was entered. The
design was not merely based on backwards compatibility, but also on
actually use cases which Guido did not want to disable. There was lots of
discussion on c.l.p.

Terry J. Reedy

Sep 22 '05 #17

P: n/a
On Thursday 22 September 2005 12:26 pm, Ron Adam wrote:
Steve Holden wrote:
Ron Adam wrote:
>>> True * True
1 # Why not return True here as well?

Why not return 42? Why not return a picture of a banana?


My question still stands. Could it be helpful if bools were preserved
in more cases than they are now?


No. "*" is "multiplication".
The multiplication operator is undefined for boolean values. It only
makes sense if they are interpreted as numbers. As it happens, both
can be coerced to 1, so the result is 1*1. This makes perfect sense
to me.
True and True

True

Also makes sense (and this is indeed what happens).

Cheers,
Terry

--
Terry Hancock ( hancock at anansispaceworks.com )
Anansi Spaceworks http://www.anansispaceworks.com

Sep 22 '05 #18

P: n/a
On Thu, 22 Sep 2005 14:12:52 -0400, "Terry Reedy" <tj*****@udel.edu> wrote:

"Steve Holden" <st***@holdenweb.com> wrote in message
news:dg**********@sea.gmane.org...
Which is yet another reason why it makes absolutely no sense to apply
arithmetic operations to Boolean values.


Except for counting the number of true values. This and other legitimate
uses of False/True as 0/1 (indexing, for instance) were explicitly
considered as *features* of the current design when it was entered. The
design was not merely based on backwards compatibility, but also on
actually use cases which Guido did not want to disable. There was lots of
discussion on c.l.p.

OTOH ISTM choosing to define bool as a subclass of int was a case of
practicality beats purity, but I'm not sure it wasn't an overeager coercion in disguise.

I.e., IMO a boolean is really not an integer, but it does belong to an ordered set,
or enumeration, that has a very useful correspondence to the enumeration of binary digits,
which in turn corresponds to the beginning subset of the ordered set of the non-negative integers.
IIRC Pascal actually does use an enumeration to define its bools, and you get the integer values
via an ord function.

BTW, for counting you could always use sum(1 for x in boolables if x) ;-)

And giving the bool type an __int__ method of its own might have covered a lot of coercions
of convenience, especially if __getitem__ of list and tuple would do coercion (you
could argue about coercing floats, etc. in that context, as was probably done ;-)

Regards,
Bengt Richter
Sep 22 '05 #19

P: n/a
Terry Hancock wrote:
On Thursday 22 September 2005 12:26 pm, Ron Adam wrote:
Steve Holden wrote:
Ron Adam wrote:

>>> True * True
1 # Why not return True here as well?
Why not return 42? Why not return a picture of a banana?
My question still stands. Could it be helpful if bools were preserved
in more cases than they are now?

No. "*" is "multiplication".
The multiplication operator is undefined for boolean values. It only
makes sense if they are interpreted as numbers. As it happens, both
can be coerced to 1, so the result is 1*1. This makes perfect sense
to me.


I'm not implying it doesn't make sense. It does to me as well. And it
would only make sense to return bools in this case if Python supported
boolean math.

If it did, coercion to ints (or floats) would still occur with mixed
types are used in expressions, but there are some situations where the
bool-bool results differ, so it's most likely an all or nothing move.

Both views are valid and there are benefits to both as well.

True and True


True

Also makes sense (and this is indeed what happens).


Only because True is the last value here. ;-)
Cheers,
Terry

Cheers,
Ron





Sep 23 '05 #20

P: n/a
Terry Reedy wrote:
"Steve Holden" <st***@holdenweb.com> wrote in message
news:dg**********@sea.gmane.org...
Which is yet another reason why it makes absolutely no sense to apply
arithmetic operations to Boolean values.

Except for counting the number of true values. This and other legitimate
uses of False/True as 0/1 (indexing, for instance) were explicitly
considered as *features* of the current design when it was entered. The
design was not merely based on backwards compatibility, but also on
actually use cases which Guido did not want to disable. There was lots of
discussion on c.l.p.

Sure. Perhaps I should have said it makes absolutely no sense "to expect
the results of aritmetic operations on bools to themselves be bools".
Sheesh, you have to be so careful nowadays ... :-)

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

Sep 23 '05 #21

P: n/a
On Thursday 22 September 2005 07:09 pm, Ron Adam wrote:
Terry Hancock wrote:
On Thursday 22 September 2005 12:26 pm, Ron Adam wrote:
>True and True


True

Also makes sense (and this is indeed what happens).


Only because True is the last value here. ;-)


Nope, works for False, too:
True and False False

I see what you mean, but if you were mixing types, then
you probably wanted the "value preserved" behavior. If
both objects are bool, the result is too (even if this
is only a coincidence, it still happens to be true).

So this still makes sense:
True and 1

1

Effectively, what you'd be asking for is to have bool
coerce more strongly than ints or other types, so that
results would become boolean if any boolean argument
existed. But that would be a pretty major change in Python,
and break lots of code.

--
Terry Hancock ( hancock at anansispaceworks.com )
Anansi Spaceworks http://www.anansispaceworks.com

Sep 23 '05 #22

P: n/a
Steven D'Aprano wrote:
Or wait, I have thought of one usage case: if you are returning a value
that you know will be used only as a flag, you should convert it into a
bool. Are there any other uses for bool()?


We could, of course, get along without it. One use for
canonical true and false values is to give 'not' something
sensible to return.
--
--Bryan
Sep 23 '05 #23

This discussion thread is closed

Replies have been disabled for this discussion.