Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #110282 > unrolled thread

Operator Precedence/Boolean Logic

Started byElizabeth Weiss <cake240@gmail.com>
First post2016-06-21 20:40 -0700
Last post2016-06-22 20:43 +0100
Articles 20 on this page of 95 — 20 participants

Back to article view | Back to comp.lang.python


Contents

  Operator Precedence/Boolean Logic Elizabeth Weiss <cake240@gmail.com> - 2016-06-21 20:40 -0700
    Re: Operator Precedence/Boolean Logic Ben Finney <ben+python@benfinney.id.au> - 2016-06-22 13:59 +1000
      Re: Operator Precedence/Boolean Logic Elizabeth Weiss <cake240@gmail.com> - 2016-06-22 21:19 -0700
      Re: Operator Precedence/Boolean Logic Elizabeth Weiss <cake240@gmail.com> - 2016-06-22 21:20 -0700
    Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-06-22 16:02 +1000
    Re: Operator Precedence/Boolean Logic Christian Gollwitzer <auriocus@gmx.de> - 2016-06-22 08:26 +0200
      Re: Operator Precedence/Boolean Logic Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-06-22 10:14 +0300
        Re: Operator Precedence/Boolean Logic Elizabeth Weiss <cake240@gmail.com> - 2016-06-22 21:21 -0700
    Re: Operator Precedence/Boolean Logic Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-22 00:42 -0700
      Re: Operator Precedence/Boolean Logic Larry Hudson <orgnut@yahoo.com> - 2016-06-22 20:12 -0700
        Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-06-23 13:59 +1000
          Re: Operator Precedence/Boolean Logic Elizabeth Weiss <cake240@gmail.com> - 2016-06-22 21:23 -0700
          Re: Operator Precedence/Boolean Logic Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-06-23 09:58 +0200
            Re: Operator Precedence/Boolean Logic Marko Rauhamaa <marko@pacujo.net> - 2016-06-23 11:16 +0300
              Re: Operator Precedence/Boolean Logic Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-23 01:53 -0700
                Re: Operator Precedence/Boolean Logic Marko Rauhamaa <marko@pacujo.net> - 2016-06-23 12:10 +0300
                  Re: Operator Precedence/Boolean Logic Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-06-23 11:27 +0200
                    Re: Operator Precedence/Boolean Logic Marko Rauhamaa <marko@pacujo.net> - 2016-06-23 12:53 +0300
                      Re: Operator Precedence/Boolean Logic Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-06-23 12:54 +0200
                        Re: Operator Precedence/Boolean Logic Marko Rauhamaa <marko@pacujo.net> - 2016-06-23 13:59 +0300
                          Re: Operator Precedence/Boolean Logic Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-06-23 13:15 +0200
                            Re: Operator Precedence/Boolean Logic Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-06-23 15:05 +0300
                              Re: Operator Precedence/Boolean Logic Chris Angelico <rosuav@gmail.com> - 2016-06-23 22:13 +1000
                  Re: Operator Precedence/Boolean Logic Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-23 02:44 -0700
                    Re: Operator Precedence/Boolean Logic Marko Rauhamaa <marko@pacujo.net> - 2016-06-23 12:57 +0300
                      Re: Operator Precedence/Boolean Logic Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-24 22:38 -0700
                        Re: Operator Precedence/Boolean Logic Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-06-25 09:46 +0300
              Re: Operator Precedence/Boolean Logic Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-06-23 11:01 +0200
            Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-06-23 19:39 +1000
              Re: Operator Precedence/Boolean Logic Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-06-23 12:21 +0200
                Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-06-23 22:37 +1000
                  Re: Operator Precedence/Boolean Logic Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-06-23 15:24 +0200
                  Re: Operator Precedence/Boolean Logic Random832 <random832@fastmail.com> - 2016-06-23 09:26 -0400
                    Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-06-24 02:43 +1000
                  Re: Operator Precedence/Boolean Logic Chris Angelico <rosuav@gmail.com> - 2016-06-24 01:49 +1000
          Re: Operator Precedence/Boolean Logic Marko Rauhamaa <marko@pacujo.net> - 2016-06-25 11:56 +0300
        Re: Operator Precedence/Boolean Logic Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-22 21:47 -0700
          Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-06-22 22:00 -0700
          Re: Operator Precedence/Boolean Logic Andreas Röhler <andreas.roehler@online.de> - 2016-06-23 08:34 +0200
            Re: Operator Precedence/Boolean Logic Marko Rauhamaa <marko@pacujo.net> - 2016-06-23 09:46 +0300
            Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-06-23 17:05 +1000
              Re: Operator Precedence/Boolean Logic Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-06-23 10:17 +0200
                Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-06-23 18:48 +1000
                  Re: Operator Precedence/Boolean Logic Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-06-23 11:23 +0200
                  Re: Operator Precedence/Boolean Logic Chris Angelico <rosuav@gmail.com> - 2016-06-23 21:45 +1000
                  Re: Operator Precedence/Boolean Logic Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-06-23 14:08 +0200
                  Re: Operator Precedence/Boolean Logic Andreas Röhler <andreas.roehler@online.de> - 2016-06-23 14:22 +0200
              Re: Operator Precedence/Boolean Logic Andreas Röhler <andreas.roehler@online.de> - 2016-06-23 10:23 +0200
              Re: Operator Precedence/Boolean Logic Andreas Röhler <andreas.roehler@online.de> - 2016-06-23 10:32 +0200
                Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-06-23 19:17 +1000
                  Re: Operator Precedence/Boolean Logic Marko Rauhamaa <marko@pacujo.net> - 2016-06-23 12:46 +0300
                    Re: Operator Precedence/Boolean Logic Andreas Röhler <andreas.roehler@online.de> - 2016-06-23 12:19 +0200
                    Re: Operator Precedence/Boolean Logic Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2016-06-26 11:01 +1200
                      Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-06-29 03:21 -0700
                        Re: Operator Precedence/Boolean Logic Chris Angelico <rosuav@gmail.com> - 2016-06-29 21:06 +1000
                        Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-06-29 23:08 +1000
                          Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-06-29 06:30 -0700
                            Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-06-30 09:40 +1000
                              Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-06-30 09:01 -0700
                                Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-07-01 03:22 +1000
                                  Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-07-15 22:48 -0700
                                    Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-07-15 22:58 -0700
                                      Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-07-16 19:14 +1000
                                    Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-07-16 20:16 +1000
                                      Re: Operator Precedence/Boolean Logic Chris Angelico <rosuav@gmail.com> - 2016-07-16 20:46 +1000
                                        Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-07-16 21:02 +1000
                                          Re: Operator Precedence/Boolean Logic Chris Angelico <rosuav@gmail.com> - 2016-07-17 00:26 +1000
                                        Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-07-16 05:33 -0700
                                          Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-07-17 02:27 +1000
                                            Re: Operator Precedence/Boolean Logic MRAB <python@mrabarnett.plus.com> - 2016-07-16 17:58 +0100
                                              Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-07-16 20:43 -0700
                                                Re: Operator Precedence/Boolean Logic Chris Angelico <rosuav@gmail.com> - 2016-07-17 14:05 +1000
                                                  Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-07-16 23:44 -0700
                                                    Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-07-16 23:59 -0700
                                                    Re: Operator Precedence/Boolean Logic Chris Angelico <rosuav@gmail.com> - 2016-07-17 17:33 +1000
                                                      Re: Operator Precedence/Boolean Logic Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-07-17 00:44 -0700
                                                        Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-07-17 20:04 +1000
                                                    Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-07-17 21:02 +1000
                                                      Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-07-17 08:00 -0700
                                                        Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-07-18 01:58 +1000
                                                          Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-07-18 02:01 +1000
                                            Re: Operator Precedence/Boolean Logic Chris Angelico <rosuav@gmail.com> - 2016-07-17 03:06 +1000
                                      Re: Operator Precedence/Boolean Logic Rustom Mody <rustompmody@gmail.com> - 2016-07-16 05:15 -0700
                                        Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-07-17 02:36 +1000
                          Re: Operator Precedence/Boolean Logic Grant Edwards <grant.b.edwards@gmail.com> - 2016-06-29 15:00 +0000
                            Re: Operator Precedence/Boolean Logic Jon Ribbens <jon+usenet@unequivocal.eu> - 2016-06-29 15:05 +0000
                            Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve@pearwood.info> - 2016-06-30 09:44 +1000
                  Re: Operator Precedence/Boolean Logic Andreas Röhler <andreas.roehler@online.de> - 2016-06-23 11:51 +0200
          Re: Operator Precedence/Boolean Logic Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-06-23 17:20 +1000
          Re: Operator Precedence/Boolean Logic Random832 <random832@fastmail.com> - 2016-06-23 09:18 -0400
        Re: Operator Precedence/Boolean Logic Christian Gollwitzer <auriocus@gmx.de> - 2016-06-23 09:11 +0200
      Re: Operator Precedence/Boolean Logic Elizabeth Weiss <cake240@gmail.com> - 2016-06-22 21:22 -0700
    Fwd: Operator Precedence/Boolean Logic Jorge Gimeno <jlgimeno71@gmail.com> - 2016-06-21 20:56 -0700
    Re: Operator Precedence/Boolean Logic Random832 <random832@fastmail.com> - 2016-06-22 10:10 -0400
    Re: Operator Precedence/Boolean Logic Erik <python@lucidity.plus.com> - 2016-06-22 20:43 +0100

Page 2 of 5 — ← Prev page 1 [2] 3 4 5  Next page →


#110405

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2016-06-23 13:15 +0200
Message-ID<mailman.68.1466680570.11516.python-list@python.org>
In reply to#110404
Op 23-06-16 om 12:59 schreef Marko Rauhamaa:
> Antoon Pardon <antoon.pardon@rece.vub.ac.be>:
>
>> Op 23-06-16 om 11:53 schreef Marko Rauhamaa:
>> Maybe something like this:
>>
>> def empty(sq):
>>     try:
>>         iter(sq).next()
>>     except StopIteration:
>>         return False
>>     except:
>>         raise TypeError
>>     else:
>>         return True
> That may or may not be as effective as a boolean check. The point is,
> Python has already declared that __bool__ is the canonical emptiness
> checker. You could even say that it's the principal purpose of the
> __bool__ method.

I think it is wrong to say __bool__ is the canonical emptiness checker.
It can be used for anything where you somehow think it is reasonable
to make a distinction between truthy and falsy. Even when talking
about emptyness doesn't make sense.

The function above at least raises an exception in a lot of cases
where the class provides booly behaviour yet emptyness wouldn't make
sense.

Would it be worth while? That you have to decide for yourself.

-- 
Antoon. 
 

[toc] | [prev] | [next] | [standalone]


#110409

FromJussi Piitulainen <jussi.piitulainen@helsinki.fi>
Date2016-06-23 15:05 +0300
Message-ID<lf5twgkqfdt.fsf@ling.helsinki.fi>
In reply to#110405
Antoon Pardon writes:

> Op 23-06-16 om 12:59 schreef Marko Rauhamaa:
>> Antoon Pardon <antoon.pardon@rece.vub.ac.be>:
>>
>>> Op 23-06-16 om 11:53 schreef Marko Rauhamaa:
>>> Maybe something like this:
>>>
>>> def empty(sq):
>>>     try:
>>>         iter(sq).next()
>>>     except StopIteration:
>>>         return False
>>>     except:
>>>         raise TypeError
>>>     else:
>>>         return True
>> That may or may not be as effective as a boolean check. The point is,
>> Python has already declared that __bool__ is the canonical emptiness
>> checker. You could even say that it's the principal purpose of the
>> __bool__ method.
>
> I think it is wrong to say __bool__ is the canonical emptiness checker.
> It can be used for anything where you somehow think it is reasonable
> to make a distinction between truthy and falsy. Even when talking
> about emptyness doesn't make sense.
>
> The function above at least raises an exception in a lot of cases
> where the class provides booly behaviour yet emptyness wouldn't make
> sense.

It also *changes* many things where emptiness *would* make sense. In
particular, it can first *make* a thing empty and then happily declare
it not empty. Not good.

Is "sq" mnemonic for something?

[toc] | [prev] | [next] | [standalone]


#110412

FromChris Angelico <rosuav@gmail.com>
Date2016-06-23 22:13 +1000
Message-ID<mailman.72.1466684035.11516.python-list@python.org>
In reply to#110409
On Thu, Jun 23, 2016 at 10:05 PM, Jussi Piitulainen
<jussi.piitulainen@helsinki.fi> wrote:
> Is "sq" mnemonic for something?

Presumably "sequence", which fits the other assumption that you noted:
that calling 'iter' on it will produce a non-destructive iterator.

I hope that code is never used on older Pythons that don't have
exception chaining, given that it has a bare except in it. Actually, I
hope that code is never used at all.

ChrisA

[toc] | [prev] | [next] | [standalone]


#110393

FromLawrence D’Oliveiro <lawrencedo99@gmail.com>
Date2016-06-23 02:44 -0700
Message-ID<855a6682-a627-4c0f-ae95-fc3d2eb6e0d2@googlegroups.com>
In reply to#110388
On Thursday, June 23, 2016 at 9:11:05 PM UTC+12, Marko Rauhamaa wrote:
> Lawrence D’Oliveiro:
> 
>> On Thursday, June 23, 2016 at 8:17:02 PM UTC+12, Marko Rauhamaa wrote:
>>>     if len(leftover) > 0:    # no, I'd never write this
>>>         ...
>>
>> I regularly write “len(leftover) != 0”. Why not?
> 
> The __len__ method is not guaranteed to execute in O(1).

So what is?

[toc] | [prev] | [next] | [standalone]


#110398

FromMarko Rauhamaa <marko@pacujo.net>
Date2016-06-23 12:57 +0300
Message-ID<87k2hgfcs9.fsf@elektro.pacujo.net>
In reply to#110393
Lawrence D’Oliveiro <lawrencedo99@gmail.com>:

> On Thursday, June 23, 2016 at 9:11:05 PM UTC+12, Marko Rauhamaa wrote:
>> The __len__ method is not guaranteed to execute in O(1).
>
> So what is?

The __bool__ method is the appropriate place to implement an efficient
emptiness check. It might not be O(1) but it will be the most efficient
way to check for emptiness, or the class is badly implemented.


Marko

[toc] | [prev] | [next] | [standalone]


#110491

FromLawrence D’Oliveiro <lawrencedo99@gmail.com>
Date2016-06-24 22:38 -0700
Message-ID<8b32b098-423a-46a8-8be3-7603f058278f@googlegroups.com>
In reply to#110398
On Thursday, June 23, 2016 at 9:57:35 PM UTC+12, Marko Rauhamaa wrote:
> Lawrence D’Oliveiro:
> 
>> On Thursday, June 23, 2016 at 9:11:05 PM UTC+12, Marko Rauhamaa wrote:
>>> The __len__ method is not guaranteed to execute in O(1).
>>
>> So what is?
> 
> The __bool__ method is the appropriate place to implement an efficient
> emptiness check. It might not be O(1) but it will be the most efficient
> way to check for emptiness, or the class is badly implemented.

Saying “or the class is badly implemented” sounds like circular reasoning...

[toc] | [prev] | [next] | [standalone]


#110492

FromJussi Piitulainen <jussi.piitulainen@helsinki.fi>
Date2016-06-25 09:46 +0300
Message-ID<lf5y45tojf1.fsf@ling.helsinki.fi>
In reply to#110491
Lawrence D’Oliveiro writes:

> On Thursday, June 23, 2016 at 9:57:35 PM UTC+12, Marko Rauhamaa wrote:
>> Lawrence D’Oliveiro:
>> 
>>> On Thursday, June 23, 2016 at 9:11:05 PM UTC+12, Marko Rauhamaa wrote:
>>>> The __len__ method is not guaranteed to execute in O(1).
>>>
>>> So what is?
>> 
>> The __bool__ method is the appropriate place to implement an
>> efficient emptiness check. It might not be O(1) but it will be the
>> most efficient way to check for emptiness, or the class is badly
>> implemented.
>
> Saying “or the class is badly implemented” sounds like circular
> reasoning...

What are you thinking? If there's a better way to implement __bool__,
why shouldn't that better way have been used?

[toc] | [prev] | [next] | [standalone]


#110386

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2016-06-23 11:01 +0200
Message-ID<mailman.60.1466672514.11516.python-list@python.org>
In reply to#110379
Op 23-06-16 om 10:16 schreef Marko Rauhamaa:
> I don't particularly like Python's falsey/truthy semantics, but I can
> live with it. The biggest problem I have with it is the absence of an
> emptiness predicate. I'd like to be able to write:
>
>     if not leftover.empty():
>         ...
>
> or even:
>
>     if not empty(leftover):
>         ...
>
> rather than having to say:
>
>     if not leftover:
>         ...
>
> or:
>
>     if len(leftover) > 0:    # no, I'd never write this
>         ...

Well if I have to test for emptyness, I always write

   if len(seq) > 0:

Because this will throw an exception when len can't
apply to seq and so this will catch possible bugs
sooner than writing:

  if not seq.

-- 
Antoon Pardon

[toc] | [prev] | [next] | [standalone]


#110392

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2016-06-23 19:39 +1000
Message-ID<576bae4c$0$11112$c3e8da3@news.astraweb.com>
In reply to#110378
On Thursday 23 June 2016 17:58, Antoon Pardon wrote:

> Op 23-06-16 om 05:59 schreef Steven D'Aprano:
>> On Thu, 23 Jun 2016 01:12 pm, Larry Hudson wrote:
>>
>>> On 06/22/2016 12:42 AM, Lawrence D’Oliveiro wrote:
>>> [snip]
>>>> I feel that’s a needlessly complicated rule. It would have been simpler
>>>> if boolean operators (and conditional expressions like in if-statements
>>>> and while-statements) only allowed values of boolean types. But that’s
>>>> one of the few warts in the design of Python...
>>>>
>>> Wart??  I *strongly* disagree.  I find it one of the strengths of Python,
>>> it enhances Python's
>>> expressiveness.  Of course, everyone is entitled to their own
>>> opinion...and this is mine.
>> Allowing any value as a truth value is just applying the principle of
>> duck-typing to booleans.
> 
> What does that mean? As far as I understood, duck typing was that you
> could define any class with the same attributes and methods as an other,
> often a built in, at which point you could substitute instance of this
> new class anywhere you originally expected instance of the old class.

But you only need to implement the behaviour you need, not the entire Duck 
interface. If you only need quack(), you don't need to implement swim(), or 
provide an actual Duck, any object capable of quacking will do.

To decide on a branch, you don't need an actual bool, anything capable of 
acting like a bool will do. As a language design, ALL objects are capable of 
acting like a bool. Python has a specific protocol in place for deciding 
whether an object quacks like a bool:

if the object defines __len__:
   if it returns 0, then the object is false;
   else the object is true
elif the object defines __nonzero__ (__bool__ in Python 3)
    if it returns a true value, then the object is true
    else the object is false
else
    # neither __len__ nor __nonzero__ is defined
    the object is true


> My experience is that this doesn't work with booleans. When I need
> real booleans, encountering whatever else that can act like a boolean,
> is more often than not an indication something went wrong but the
> detection of it going wrong is delayed, because almost everything
> can act like a boolean. It is why I have sometime found the need
> to write:
> 
>     if flag is True:
> 
> Because flag needed to be True, not truthy.

I find this hard to believe. Why do you care if somebody passes you 1 or "T" as 
the flag instead of True? And if they do pass something other than True, you 
don't get an exception, you simply take the false branch.

Somehow I doubt that you write three-state logic everywhere:

if flag is True: ...
elif flag is False: ...
else: ...


By the way, it is a particular error of folks using so-called "real bools" to 
compare something you already know is a bool against True. I used to see it all 
the time in my Pascal days, where people would define a boolean flag then write 
"if flag == True". Given:

assert isinstance(flag, bool)

then writing 

    flag is True

returns a bool. So how do you test a bool? By comparing it to True:

    flag is True is True

But that also returns a bool, so you must enter an infinite regress:

    flag is True is True is True is True... # help me, where do I stop???

The right answer, of course, is to stop *right at the beginning*. Stopping at 
Step 2 is silly and pointless. Since you know flag is a True or False value, 
then you just write:

    flag

And the same applies to true and false values.




-- 
Steve

[toc] | [prev] | [next] | [standalone]


#110401

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2016-06-23 12:21 +0200
Message-ID<mailman.65.1466677348.11516.python-list@python.org>
In reply to#110392
Op 23-06-16 om 11:39 schreef Steven D'Aprano:
> On Thursday 23 June 2016 17:58, Antoon Pardon wrote:
>
>> Op 23-06-16 om 05:59 schreef Steven D'Aprano:
>>> On Thu, 23 Jun 2016 01:12 pm, Larry Hudson wrote:
>>>
>>>> On 06/22/2016 12:42 AM, Lawrence D’Oliveiro wrote:
>>>> [snip]
>>>>> I feel that’s a needlessly complicated rule. It would have been simpler
>>>>> if boolean operators (and conditional expressions like in if-statements
>>>>> and while-statements) only allowed values of boolean types. But that’s
>>>>> one of the few warts in the design of Python...
>>>>>
>>>> Wart??  I *strongly* disagree.  I find it one of the strengths of Python,
>>>> it enhances Python's
>>>> expressiveness.  Of course, everyone is entitled to their own
>>>> opinion...and this is mine.
>>> Allowing any value as a truth value is just applying the principle of
>>> duck-typing to booleans.
>> What does that mean? As far as I understood, duck typing was that you
>> could define any class with the same attributes and methods as an other,
>> often a built in, at which point you could substitute instance of this
>> new class anywhere you originally expected instance of the old class.
> But you only need to implement the behaviour you need, not the entire Duck 
> interface. If you only need quack(), you don't need to implement swim(), or 
> provide an actual Duck, any object capable of quacking will do.
>
> To decide on a branch, you don't need an actual bool, anything capable of 
> acting like a bool will do. As a language design, ALL objects are capable of 
> acting like a bool. Python has a specific protocol in place for deciding 
> whether an object quacks like a bool:

But an object acting like a bool, doesn't mean this bool behaviour makes the
disctinction you actually need. Python tempts people to rely on those truthy
values, because it saves typing is pythonic and it works for the moment and
then something unexpected gets passed through and you find yourself chasing
a very illusive bug. 

>> My experience is that this doesn't work with booleans. When I need
>> real booleans, encountering whatever else that can act like a boolean,
>> is more often than not an indication something went wrong but the
>> detection of it going wrong is delayed, because almost everything
>> can act like a boolean. It is why I have sometime found the need
>> to write:
>>
>>     if flag is True:
>>
>> Because flag needed to be True, not truthy.
> I find this hard to believe. Why do you care if somebody passes you 1 or "T" as 
> the flag instead of True? And if they do pass something other than True, you 
> don't get an exception, you simply take the false branch.
>
> Somehow I doubt that you write three-state logic everywhere:

Since I wrote above the I *sometimes* found this need. You may
safely assume I don't write it everywhere.

>
> if flag is True: ...
> elif flag is False: ...
> else: ...
>
>
> By the way, it is a particular error of folks using so-called "real bools" to 
> compare something you already know is a bool against True. I used to see it all 
> the time in my Pascal days, where people would define a boolean flag then write 
> "if flag == True". Given:
>
> assert isinstance(flag, bool)

But of course if one would show such a line in code on this
list, it would illicit a lot of comments on how unpythonic this
this is and that you really shouldn't, and that you should realy
rely on an exception being thrown when what you are provided
doesn't work.

You come here with a remark depending on not using duck typing
when you start your contribution with defending duck typing.

-- 
Antoon.

[toc] | [prev] | [next] | [standalone]


#110414

FromSteven D'Aprano <steve@pearwood.info>
Date2016-06-23 22:37 +1000
Message-ID<576bd818$0$1619$c3e8da3$5496439d@news.astraweb.com>
In reply to#110401
On Thu, 23 Jun 2016 08:21 pm, Antoon Pardon wrote:

> Op 23-06-16 om 11:39 schreef Steven D'Aprano:
[...]
>> To decide on a branch, you don't need an actual bool, anything capable of
>> acting like a bool will do. As a language design, ALL objects are capable
>> of acting like a bool. Python has a specific protocol in place for
>> deciding whether an object quacks like a bool:
> 
> But an object acting like a bool, doesn't mean this bool behaviour makes
> the disctinction you actually need. 

Um... okay?

I'm not really sure I understand the point you think your making. Lists and
tuples can be exchanged in many duck-typing situations, but if you need
something with an in-place sort method, you can't use a tuple. That's a
given. If you need some feature that isn't offered by truthiness, you can't
use truthiness to detect that feature. It seems hardly worth mentioning.


> Python tempts people to rely on those 
> truthy values, because it saves typing is pythonic and it works for the
> moment and then something unexpected gets passed through and you find
> yourself chasing a very illusive bug.

You keep saying that, but I've never seen it happen. I've seen cases where
people have been surprised by the unexpected truthiness of an object ("I
expected an exhausted iterator to be false, but it was true"), but that's
not what you seem to be describing.

To be honest, I'm not sure what you are describing. Your explanation is
maddeningly vague. Since bools offer a *very small* API (beyond what they
also offer as a subclass of int), I cannot imagine what unexpected thing
you might get passed in that leads to "a very illusive bug".

The bottom line is, bools offer only a single major API[1]: are they truthy,
or falsey? What else can do you with them? Nothing. They support
conditional branches, and boolean operators "or" and "and". That's all.
They don't have methods to call, or attributes to set. You can use a bool
to take the if branch, or the else branch, and that's effectively all.

Since *all* objects support that same bool API, what can you *possibly* be
passed in place of a bool that fails to work?

I acknowledge, cheerfully, that there might be a mismatch between what you
expect and what the object actually does. "I expect empty containers to be
falsey, and non-empty ones to be truthy; but this RedBlackTree object is
always false even if it has many items; and this SortedDict is always true
even when it is empty."

That's a nuisance and a pain when it happens, but it's arguably a bug in the
object or at least a misfeature, and besides that's the risk when you
duck-type. You're trusting the object that you get to behave like the
object you expect, or it will break things.

(An object with a misbehaving __bool__ is no better or worse than an object
with a misbehaving sort() method, or __add__ method.)

So I'm not really sure what you are trying to describe. I guess it might be
something like this:

def spam(alist):
    if alist:
        process(alist)
    else:
        print("empty list")


If you pass 1 instead of an actual list, then you don't get an error until
somewhere inside process(). Potentially far, far away. So you want to
write:

def spam(alist):
    if len(alist):
        process(alist)  # requires an actual list
    else:
        print("empty list")


and now calling spam(1) will raise immediately. Great.

But that's not really anything to do with *bools* specifically. If you call
spam() with a dict, or a set, or a tuple, or a RedBlackTree, any other
object with a length, you're no better off. If you absolutely need a list,
and nothing else, then you have to type-check.

In practice, I don't see how truthy/falsey objects lead to more or worse
bugs than any other form of dynamic typing.

To me, your position is equivalent to saying that dynamic typing and
duck-typing is really great, except for len(). len() should absolutely only
work on lists, and nothing else, so any time you want to get the length of
an object, you must work with real lists, not listy sequences:

if len(list(mystring)) > 20: ...

print(len(list(mydict.keys())), "items")


etc. Substitute "bool" for "len" and you might understand how I feel about
your position.


[...]
>> Somehow I doubt that you write three-state logic everywhere:
> 
> Since I wrote above the I *sometimes* found this need. You may
> safely assume I don't write it everywhere.

Fair enough.




[1] I exclude minor things like repr(True), and the fact that they are
subclassed from int.
 

-- 
Steven

[toc] | [prev] | [next] | [standalone]


#110417

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2016-06-23 15:24 +0200
Message-ID<mailman.77.1466688319.11516.python-list@python.org>
In reply to#110414
Op 23-06-16 om 14:37 schreef Steven D'Aprano:

> So I'm not really sure what you are trying to describe. I guess it might be
> something like this:
>
> def spam(alist):
>     if alist:
>         process(alist)
>     else:
>         print("empty list")
>
>
> If you pass 1 instead of an actual list, then you don't get an error until
> somewhere inside process(). Potentially far, far away. So you want to
> write:
>
> def spam(alist):
>     if len(alist):
>         process(alist)  # requires an actual list
>     else:
>         print("empty list")
>
>
> and now calling spam(1) will raise immediately. Great.
>
> But that's not really anything to do with *bools* specifically. If you call
> spam() with a dict, or a set, or a tuple, or a RedBlackTree, any other
> object with a length, you're no better off. If you absolutely need a list,
> and nothing else, then you have to type-check.

Yes it has to do with the booly nature of python objects. The fact that your
examples still allows for bugs, doesn't contradict it already cathes a lot
of bugs. So yes I'm better of even if I am not completly save. Encouraging
the user to write explicit test, will detect bugs sooner and will make
it more probable the code behaves as expected even when the tests are done
one an unexpected kind of object.

> In practice, I don't see how truthy/falsey objects lead to more or worse
> bugs than any other form of dynamic typing.

Sure, this from a language that states that explicit is better than implicit.
The truthy/falsy objects encourage people to be implicit and thus allowing
a lot of things to pass that were originally not though off.

> To me, your position is equivalent to saying that dynamic typing and
> duck-typing is really great, except for len(). len() should absolutely only
> work on lists, and nothing else, so any time you want to get the length of
> an object, you must work with real lists, not listy sequences:
>
> if len(list(mystring)) > 20: ...
>
> print(len(list(mydict.keys())), "items")
>
>
> etc. Substitute "bool" for "len" and you might understand how I feel about
> your position.

IMO, bool is like you would give any object a lengthy nature and so having any
object also behave like a tuple with the object as it's only item. Then bool and
len would be similar. 

-- 
Antoon.

[toc] | [prev] | [next] | [standalone]


#110418

FromRandom832 <random832@fastmail.com>
Date2016-06-23 09:26 -0400
Message-ID<mailman.78.1466688398.11516.python-list@python.org>
In reply to#110414
On Thu, Jun 23, 2016, at 08:37, Steven D'Aprano wrote:
> You keep saying that, but I've never seen it happen. I've seen cases
> where people have been surprised by the unexpected truthiness of an
> object ("I expected an exhausted iterator to be false, but it was
> true"), but that's not what you seem to be describing.

I suspect that he's referring to cases like
http://bugs.python.org/issue4945 where a set of flags that are expected
to be bool under normal circumstances are interchangeably tested with
==, is, boolean checks, and the inversion of any of those.

If you test with "== True", then you treat 2 as non-truthy. If you test
with "is True", then you treat 1 as non-truthy. And the reverse of
either may treat 0 as truthy. If you mix and match any truth-test (e.g.
"== True") with anything that is not its opposite ("!= True", not e.g.
"== False") you may end up with situations where neither branch was
taken and your result is an unexpected state.

I don't actually agree with him that the object being passed in can be
blamed for this class of error.

It also occurs to me you could conceivably run into problems if you use
a passed-in mutable object as a flag to be tested multiple times.

> The bottom line is, bools offer only a single major API[1]: are they
> truthy, or falsey? What else can do you with them? Nothing. They
> support conditional branches, and boolean operators "or" and "and".
> That's all. They don't have methods to call, or attributes to set. You
> can use a bool to take the if branch, or the else branch, and that's
> effectively all.

Don't forget, they're integers valued 0 and 1. So you can multiply it by
a number to get 0 or that number. I recently did so (in a code golf
challenge, not serious code). You can sum an iterable of them to get a
count of true items.

[toc] | [prev] | [next] | [standalone]


#110430

FromSteven D'Aprano <steve@pearwood.info>
Date2016-06-24 02:43 +1000
Message-ID<576c1197$0$1597$c3e8da3$5496439d@news.astraweb.com>
In reply to#110418
On Thu, 23 Jun 2016 11:26 pm, Random832 wrote:

> On Thu, Jun 23, 2016, at 08:37, Steven D'Aprano wrote:
>> You keep saying that, but I've never seen it happen. I've seen cases
>> where people have been surprised by the unexpected truthiness of an
>> object ("I expected an exhausted iterator to be false, but it was
>> true"), but that's not what you seem to be describing.
> 
> I suspect that he's referring to cases like
> http://bugs.python.org/issue4945 where a set of flags that are expected
> to be bool under normal circumstances are interchangeably tested with
> ==, is, boolean checks, and the inversion of any of those.
> 
> If you test with "== True", then you treat 2 as non-truthy. If you test
> with "is True", then you treat 1 as non-truthy. And the reverse of
> either may treat 0 as truthy. If you mix and match any truth-test (e.g.
> "== True") with anything that is not its opposite ("!= True", not e.g.
> "== False") you may end up with situations where neither branch was
> taken and your result is an unexpected state.

Yeah, we can write crap code in Python if you try :-)

> I don't actually agree with him that the object being passed in can be
> blamed for this class of error.

Nor do I. I think that's a clear case where the solution is to stop writing
awful code.

We've all gone through a period were the nicest thing one might say about
our coding is "you don't really understand what you are doing". Some of my
earliest code was nearly as bad. 


> It also occurs to me you could conceivably run into problems if you use
> a passed-in mutable object as a flag to be tested multiple times.

Indeed, but I expect that's more of a theoretical risk than a practical
risk. And, who knows, somebody might find a use for it, to win a bet, for a
code golf competition, or just because they like writing "clever" code:

flag = []
if condition:
    flag.append(None)
else:
    flag.pop()

Could be useful. But beware of overly clever code.


>> The bottom line is, bools offer only a single major API[1]: are they
>> truthy, or falsey? What else can do you with them? Nothing. They
>> support conditional branches, and boolean operators "or" and "and".
>> That's all. They don't have methods to call, or attributes to set. You
>> can use a bool to take the if branch, or the else branch, and that's
>> effectively all.
> 
> Don't forget, they're integers valued 0 and 1. So you can multiply it by
> a number to get 0 or that number. I recently did so (in a code golf
> challenge, not serious code). You can sum an iterable of them to get a
> count of true items.

I would never forget they're also ints. I think I even mentioned that in the
footnote.




-- 
Steven

[toc] | [prev] | [next] | [standalone]


#110423

FromChris Angelico <rosuav@gmail.com>
Date2016-06-24 01:49 +1000
Message-ID<mailman.79.1466696968.11516.python-list@python.org>
In reply to#110414
On Thu, Jun 23, 2016 at 10:37 PM, Steven D'Aprano <steve@pearwood.info> wrote:
> I acknowledge, cheerfully, that there might be a mismatch between what you
> expect and what the object actually does. "I expect empty containers to be
> falsey, and non-empty ones to be truthy; but this RedBlackTree object is
> always false even if it has many items; and this SortedDict is always true
> even when it is empty."
>
> That's a nuisance and a pain when it happens, but it's arguably a bug in the
> object or at least a misfeature...

As evidenced by the change to time truthiness, yes, that's the
object's fault. If your RedBlackTree object were always *true*, I'd
call it a missing feature ("please add a __bool__ that distinguishes
empty trees from trees with content"), but always *false* would be a
bug. A SortedDict implies by its name that it should be extremely
dict-like, so that would be a strong argument for its truthiness to
follow a dict's. Either way, the misbehaviour gets pointed back at the
object in question.

ChrisA

[toc] | [prev] | [next] | [standalone]


#110498

FromMarko Rauhamaa <marko@pacujo.net>
Date2016-06-25 11:56 +0300
Message-ID<87a8i9r6ih.fsf@elektro.pacujo.net>
In reply to#110354
Steven D'Aprano <steve@pearwood.info>:

> So we have falsey values:
>
> - None
> - zeroes (0, 0.0, 0j, etc)
> - empty dict {}
> - empty sets and frozensets
> - empty strings '' and b'' (in Python 2: u'' and '')
> - empty lists, tuples and other sequences
>
> and truthy values:
>
> - object
> - non-zero numbers
> - non-empty dicts
> - non-empty sets and frozensets
> - non-empty strings
> - non-empty sequences

It might be more descriptive to call those polar opposites "naughty" and
"nice." Or maybe "hollow" and "puffy."


Marko

[toc] | [prev] | [next] | [standalone]


#110363

FromLawrence D’Oliveiro <lawrencedo99@gmail.com>
Date2016-06-22 21:47 -0700
Message-ID<3a840cef-24d2-4abb-8e5b-dc80bf48944d@googlegroups.com>
In reply to#110353
On Thursday, June 23, 2016 at 3:12:52 PM UTC+12, Larry Hudson wrote:
> On 06/22/2016 12:42 AM, Lawrence D’Oliveiro wrote:
>> * boolean operators don’t have to operate on boolean values. The
>>   language spec
>>   <https://docs.python.org/3/reference/expressions.html#boolean-operations>
>>   says:
>>
>>     “...the following values are interpreted as false: False, None, numeric
>>     zero of all types, and empty strings and containers (including strings,
>>     tuples, lists, dictionaries, sets and frozensets). All other values are
>>     interpreted as true.”
>>
>> I feel that’s a needlessly complicated rule. It would have been simpler if
>> boolean operators (and conditional expressions like in if-statements and
>> while-statements) only allowed values of boolean types. But that’s one of
>> the few warts in the design of Python...
> 
> Wart??  I *strongly* disagree.  I find it one of the strengths of Python,
> it enhances Python's expressiveness.

Tightening it up would rule out a whole class of common errors, from misunderstanding (or forgetting) the rule about what exactly gets interpreted as true and what as false <https://bugs.python.org/issue13936> <http://stackoverflow.com/questions/28116931/datetime-time0-0-evaluates-as-false-in-boolean-context>.

[toc] | [prev] | [next] | [standalone]


#110366

FromRustom Mody <rustompmody@gmail.com>
Date2016-06-22 22:00 -0700
Message-ID<f44b7071-a52b-44b2-bcbb-9d28f5fe7585@googlegroups.com>
In reply to#110363
On Thursday, June 23, 2016 at 10:17:16 AM UTC+5:30, Lawrence D’Oliveiro wrote:
> On Thursday, June 23, 2016 at 3:12:52 PM UTC+12, Larry Hudson wrote:
> > On 06/22/2016 12:42 AM, Lawrence D’Oliveiro wrote:
> >> * boolean operators don’t have to operate on boolean values. The
> >>   language spec
> >>   <https://docs.python.org/3/reference/expressions.html#boolean-operations>
> >>   says:
> >>
> >>     “...the following values are interpreted as false: False, None, numeric
> >>     zero of all types, and empty strings and containers (including strings,
> >>     tuples, lists, dictionaries, sets and frozensets). All other values are
> >>     interpreted as true.”
> >>
> >> I feel that’s a needlessly complicated rule. It would have been simpler if
> >> boolean operators (and conditional expressions like in if-statements and
> >> while-statements) only allowed values of boolean types. But that’s one of
> >> the few warts in the design of Python...
> > 
> > Wart??  I *strongly* disagree.  I find it one of the strengths of Python,
> > it enhances Python's expressiveness.
> 
> Tightening it up would rule out a whole class of common errors, from misunderstanding (or forgetting) the rule about what exactly gets interpreted as true and what as false <https://bugs.python.org/issue13936> <http://stackoverflow.com/questions/28116931/datetime-time0-0-evaluates-as-false-in-boolean-context>.

I would not support "tightening up"
But calling a wart a wart seems like a good idea to me
IOW making the docs a little more honest:
Along these lines:

There are two bool types in Python
A first class bool that is useful for amusement, confusion and one-upping noobs

A second class bool -- also called truthy and falsey -- that is used all the time

[toc] | [prev] | [next] | [standalone]


#110370

FromAndreas Röhler <andreas.roehler@online.de>
Date2016-06-23 08:34 +0200
Message-ID<mailman.55.1466663422.11516.python-list@python.org>
In reply to#110363

On 23.06.2016 06:47, Lawrence D’Oliveiro wrote:
> On Thursday, June 23, 2016 at 3:12:52 PM UTC+12, Larry Hudson wrote:
>> On 06/22/2016 12:42 AM, Lawrence D’Oliveiro wrote:
>>> * boolean operators don’t have to operate on boolean values. The
>>>    language spec
>>>    <https://docs.python.org/3/reference/expressions.html#boolean-operations>
>>>    says:
>>>
>>>      “...the following values are interpreted as false: False, None, numeric
>>>      zero of all types, and empty strings and containers (including strings,
>>>      tuples, lists, dictionaries, sets and frozensets). All other values are
>>>      interpreted as true.”
>>>
>>> I feel that’s a needlessly complicated rule. It would have been simpler if
>>> boolean operators (and conditional expressions like in if-statements and
>>> while-statements) only allowed values of boolean types. But that’s one of
>>> the few warts in the design of Python...
>> Wart??  I *strongly* disagree.  I find it one of the strengths of Python,
>> it enhances Python's expressiveness.
> Tightening it up would rule out a whole class of common errors, from misunderstanding (or forgetting) the rule about what exactly gets interpreted as true and what as false <https://bugs.python.org/issue13936> <http://stackoverflow.com/questions/28116931/datetime-time0-0-evaluates-as-false-in-boolean-context>.

Indeed, why should the result of 4 - 4 have a different truth-value than 
4 - 3 ?
This implementation seems to be a legacy from languages without boolean 
types.

[toc] | [prev] | [next] | [standalone]


#110373

FromMarko Rauhamaa <marko@pacujo.net>
Date2016-06-23 09:46 +0300
Message-ID<878txwtnbb.fsf@elektro.pacujo.net>
In reply to#110370
Andreas Röhler <andreas.roehler@online.de>:

> Indeed, why should the result of 4 - 4 have a different truth-value
> than 4 - 3 ? This implementation seems to be a legacy from languages
> without boolean types.

In Lisp, only nil (= the empty list) is accepted as false, everything
else is considered true.

In Scheme, only #f (= False) is accepted as false, everything else is
considered true even though there is also a dedicated #t for True.


Marko

[toc] | [prev] | [next] | [standalone]


Page 2 of 5 — ← Prev page 1 [2] 3 4 5  Next page →

Back to top | Article view | comp.lang.python


csiph-web