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


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

Re: Comparisons and sorting of a numeric class....

Started byAndrew Robinson <andrew3@r3dsolutions.com>
First post2015-01-12 17:59 -0800
Last post2015-01-23 11:00 -0700
Articles 20 on this page of 48 — 11 participants

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

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Comparisons and sorting of a numeric class.... Andrew Robinson <andrew3@r3dsolutions.com> - 2015-01-12 17:59 -0800
    Re: Comparisons and sorting of a numeric class.... Steven D'Aprano <steve@pearwood.info> - 2015-01-13 05:32 +0000
      Re: Comparisons and sorting of a numeric class.... Chris Angelico <rosuav@gmail.com> - 2015-01-13 17:13 +1100
      Re: Comparisons and sorting of a numeric class.... Terry Reedy <tjreedy@udel.edu> - 2015-01-13 05:49 -0500
        Re: Comparisons and sorting of a numeric class.... Marko Rauhamaa <marko@pacujo.net> - 2015-01-13 13:00 +0200
          Re: Comparisons and sorting of a numeric class.... Chris Angelico <rosuav@gmail.com> - 2015-01-13 22:20 +1100
          Re: Comparisons and sorting of a numeric class.... Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-13 11:56 -0700
          Re: Comparisons and sorting of a numeric class.... Chris Angelico <rosuav@gmail.com> - 2015-01-14 06:02 +1100
      Re: Comparisons and sorting of a numeric class.... Chris Angelico <rosuav@gmail.com> - 2015-01-13 21:56 +1100
      Re: Comparisons and sorting of a numeric class.... Andrew Robinson <andrew3@r3dsolutions.com> - 2015-01-13 16:12 -0800
      Re: Comparisons and sorting of a numeric class.... Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-14 01:31 -0700
      Re: Comparisons and sorting of a numeric class.... Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-14 22:26 -0700
        Re: Comparisons and sorting of a numeric class.... Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-01-16 22:23 +1300
      Re: Comparisons and sorting of a numeric class.... Andrew Robinson <andrew3@r3dsolutions.com> - 2015-01-14 23:23 -0800
        Re: Comparisons and sorting of a numeric class.... Steven D'Aprano <steve@pearwood.info> - 2015-01-15 08:41 +0000
          Re: Comparisons and sorting of a numeric class.... Andrew Robinson <andrew3@r3dsolutions.com> - 2015-01-15 17:45 -0800
            Re: Comparisons and sorting of a numeric class.... Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-16 18:33 +1100
            Re: Comparisons and sorting of a numeric class.... Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-01-17 00:07 +1300
            Re: Comparisons and sorting of a numeric class.... Rustom Mody <rustompmody@gmail.com> - 2015-01-16 03:22 -0800
            Re: Comparisons and sorting of a numeric class.... Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-17 23:27 +1100
          Re: Comparisons and sorting of a numeric class.... Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-01-16 02:27 +0000
          Re: Comparisons and sorting of a numeric class.... Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-15 22:01 -0700
          Re: Comparisons and sorting of a numeric class.... Chris Angelico <rosuav@gmail.com> - 2015-01-16 17:58 +1100
        Re: Comparisons and sorting of a numeric class.... Rob Gaddi <rgaddi@technologyhighland.invalid> - 2015-01-15 09:54 -0800
          Re: Comparisons and sorting of a numeric class.... Andrew Robinson <andrew3@r3dsolutions.com> - 2015-01-26 15:47 -0800
          Re: Comparisons and sorting of a numeric class.... Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-26 18:50 -0700
      Re: Comparisons and sorting of a numeric class.... Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-15 10:05 -0700
      Re: Comparisons and sorting of a numeric class.... Andrew Robinson <andrew3@r3dsolutions.com> - 2015-01-23 03:46 -0800
        Re: Comparisons and sorting of a numeric class.... Rustom Mody <rustompmody@gmail.com> - 2015-01-23 07:31 -0800
          Re: Comparisons and sorting of a numeric class.... Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-23 09:50 -0700
            Re: Comparisons and sorting of a numeric class.... Rustom Mody <rustompmody@gmail.com> - 2015-01-23 09:03 -0800
              Re: Comparisons and sorting of a numeric class.... Chris Angelico <rosuav@gmail.com> - 2015-01-24 04:23 +1100
                Re: Comparisons and sorting of a numeric class.... Rustom Mody <rustompmody@gmail.com> - 2015-01-23 09:29 -0800
              Re: Comparisons and sorting of a numeric class.... Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-23 11:04 -0700
                Re: Comparisons and sorting of a numeric class.... Rustom Mody <rustompmody@gmail.com> - 2015-01-23 19:13 -0800
                Re: Comparisons and sorting of a numeric class.... Rustom Mody <rustompmody@gmail.com> - 2015-01-23 19:21 -0800
              Re: Comparisons and sorting of a numeric class.... Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-24 16:01 +1100
                Re: Comparisons and sorting of a numeric class.... Chris Angelico <rosuav@gmail.com> - 2015-01-24 16:43 +1100
            Re: Comparisons and sorting of a numeric class.... Rustom Mody <rustompmody@gmail.com> - 2015-01-23 09:22 -0800
              Re: Comparisons and sorting of a numeric class.... Chris Angelico <rosuav@gmail.com> - 2015-01-24 04:37 +1100
                Re: Comparisons and sorting of a numeric class.... Rustom Mody <rustompmody@gmail.com> - 2015-01-23 09:45 -0800
                  Re: Comparisons and sorting of a numeric class.... Chris Angelico <rosuav@gmail.com> - 2015-01-24 05:03 +1100
                  Re: Comparisons and sorting of a numeric class.... Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-23 11:13 -0700
        Re: Comparisons and sorting of a numeric class.... Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-24 19:27 +1100
      Re: Comparisons and sorting of a numeric class.... Chris Angelico <rosuav@gmail.com> - 2015-01-23 22:58 +1100
      Re: Comparisons and sorting of a numeric class.... Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-01-23 12:07 +0000
      Re: Comparisons and sorting of a numeric class.... Terry Reedy <tjreedy@udel.edu> - 2015-01-23 11:17 -0500
      Re: Comparisons and sorting of a numeric class.... Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-23 11:00 -0700

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


#83853

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2015-01-16 02:27 +0000
Message-ID<mailman.17780.1421375252.18130.python-list@python.org>
In reply to#83802
On 16/01/2015 01:45, Andrew Robinson wrote:
>

[snipped as far too long to bother anybody with]

I hereby congratulate you on having made it to my Dream Team for having 
written the longest pile of drivel I've read in the 12 ish years I've 
been hanging around here.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

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


#83865

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-01-15 22:01 -0700
Message-ID<mailman.17785.1421384567.18130.python-list@python.org>
In reply to#83802
On Thu, Jan 15, 2015 at 6:45 PM, Andrew Robinson
<andrew3@r3dsolutions.com> wrote:
> Then I look at python development historically and look at the built in
> class's return values for compares; and I notice; they have over time become
> more and more tied to the 'type' bool.  I expect sometime in the future that
> python may implement an actual type check on all comparison operators so
> they can not be used to return anything but a bool.

Let's see what the documentation says about this:

"""
A rich comparison method may return the singleton NotImplemented if it
does not implement the operation for a given pair of arguments. By
convention, False and True are returned for a successful comparison.
However, these methods can return any value, so if the comparison
operator is used in a Boolean context (e.g., in the condition of an if
statement), Python will call bool() on the value to determine if the
result is true or false.
"""

https://docs.python.org/3/reference/datamodel.html#object.__lt__

So the docs explicitly promise that comparison methods can return any
value. Changing this would break backward compatibility (in particular
it would break a lot of DSLs), so it's not going to happen any time
soon, and you have nothing to worry about here.

> (eg:  I already noticed
> a type check on the return value of len() so that I can't return infinity,
> even when a method clearly is returning an infinitely long iterator -- such
> as a method computing PI dynamically.  That suggests to me that there is
> significant risk in python of having type checking on all __xx__ methods in
> the future. )  This inspection is what points me foremost to saying that
> very likely, I am going to want a bool or subtye of it (if possible) as a
> return type as self defense against future changes in Python -- although at
> present, I can still get away with returning other types if bool turns out
> to be impossible.

I suspect the reason __len__ must return an int is largely historical.
Back before __iter__ existed, the way Python did iteration was by
calling __len__ and then calling __getitem__ for each index between 0
and the result. Obviously for this to work, the result had to be an
int, and infinite iterators didn't exist in this era either.

Nowadays, that sort of iteration is non-standard, but Python will
still fall back on it if __iter__ isn't defined.

> So, your first alternative is the most at risk of future problems due to
> constraints likely to be placed on comparison return types ; and as I don't
> want to do much maintenance on my library in the future -- I don't think
> that is a very good choice for making my library with.

Except that the risk you describe is fictitious.

>>> One example: It can also be a union.
>>
>> I don't understand what you think this means. I know what *I* think it
>> means, but "subclass = union" doesn't make sense to me, so wonder what
>> you think it means.
>
>
> It's a fringe use-case in Python that I don't think many people use/know
> about.  I was just being thorough in listing it.
>
> I haven't seen it used in actual python code myself -- but I know from the
> literature I've read on Python that it is occasionally used in a manner
> analogous to that of C/C++.
>
> In C/C++ unions are a datatype that allow two (or more) different types of
> data to be defined as held by one object, but only one of them is allowed to
> be initialized at a time because their location in computer memory which
> overlaps.  C places no restrictions on the compatibility of the datatypes --
> which is different than Python, but Python has a similar ability.
>
> In Python, when multiple inheritance is invoked -- it does some kind of
> check on the base types for compatibility; but still appears to be able / or
> simply does overlap the allocated memory for the different base types; eg:
> according to several sources I have read (at least on C-python internals).
>
> So one can semantically instantiate a subclass of one subtype without
> semantically instantiating the other.
>
> ALl I know about it is what I have seen it in Python literature -- and I
> tested the examples I was shown to see if they still work, and they do --
> and noted that at least at one time Guido apparently thought it was a good
> idea ; but I haven't pursued it beyond that.

Do you have a link? I have no idea what you're referring to, and I
suspect that you're confused. You can't do multiple inheritance from
types that would internally have overlapping memory.  For example:

>>> class Foo(list, dict): pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: multiple bases have instance lay-out conflict

> I'm getting the message that the reason Guido though this was important was
> because the historical meaning of bool is more important than the idea that
> metastability is an issue to be dealt with at the same time as the data
> value -- like electrical engineers do regularly.

Maybe because Python wasn't written for electrical engineers. It's a
general purpose boolean algebra for a general purpose programming
language.

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


#83869

FromChris Angelico <rosuav@gmail.com>
Date2015-01-16 17:58 +1100
Message-ID<mailman.17788.1421391492.18130.python-list@python.org>
In reply to#83802
On Fri, Jan 16, 2015 at 12:45 PM, Andrew Robinson
<andrew3@r3dsolutions.com> wrote:
>>> I don't have a setting on my email to turn off html.  Sorry. Can't help.
>>
>> You are using Thunderbird. You certainly do have such a setting.
>
> It's nice to know that you read and believe what you see in an email header.
> Note: Headers are sometimes modified by sysadmins who actually care about
> security.
>
> PPS: If there is a way to turn off HTML in this email program -- it is not
> obvious -- and I have looked.
> I've done my best not to push any HTML enhancement buttons...

You do have another option: Change email programs. Or lean on whoever
is in charge of this one, saying that it's failing in a significant
way.

Also, what security do your sysadmins gain by lying about mail
clients? Stripping the header would gain just as much. Lying just
makes your network uncooperative at best, and possibly will be seen as
malicious. If you're using a mail client with known vulnerabilities,
*FIX THAT*, don't try to hide behind a fallacious header. Otherwise
it's not security, it's laziness.

ChrisA

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


#83840

FromRob Gaddi <rgaddi@technologyhighland.invalid>
Date2015-01-15 09:54 -0800
Message-ID<20150115095452.072d5763@rg.highlandtechnology.com>
In reply to#83799
On Wed, 14 Jan 2015 23:23:54 -0800
Andrew Robinson <andrew3@r3dsolutions.com> wrote:

> 
> > Boolean algebra has two values: true and false, or 1 and 0, or humpty
> > and dumpty, or whatever you like to call them.
> You're speaking to an Electrical engineer.  I know there are 10 kinds of 
> people, those who know binary and those who don't.  But you're way off 
> base if you think most industrial quality code for manipulating boolean 
> logic uses (or even can be restricted to use) only two values and still 
> accomplish their tasks correctly and within a finite amount of time.
> 

[snip]

Absolutely it does and can.  You store anything that's non-boolean in a
non-boolean value, and keep it as fuzzy as you like.  But at the end of
the day, an if statement has no "kinda".  You do, or you don't.  1 or
0.  And so you must ultimately resolve to a Boolean decision.

> >
> > Can you name any other language that *does* allow subclassing of
> > booleans or creation of new boolean values?
> Yes. Several off the top of my head -- and I have mentioned these 
> before.  They generally come with the extra subclasses pre-created and 
> the user doesn't get to create the classes, but only use them; none the 
> less -- they have more than two values with which to do logic equations 
> with.
> 
> VHDL, Verilog, HDL, Silos III, and there are IEEE variants also.
> C/C++ historically allowed you to do it with instances included, 
> although I am not sure it still does.
> 

Incorrect, at least in VHDL.  If I've got "signal x : boolean;", then x
is defined on the range (true, false).  I can ask VHDL "if x then; ...;
end if;"

What you're talking about is not at all a subclass of boolean, it's a
std_logic.  It's a separate enumerated type, with a set of resolution
rules defined in a function the source of which is available in
std_logic_1164.vhd.  And according to the strict rules of VHDL (up
until VHDL2008 decided to forfeit some purity for simplicity's), you
can't simply have:

	signal x: std_logic
	...
	if x then

You have to ask

	if x = '1'
or
	if (x = '1') or (x = 'H')

Because you are comparing one value of an enumerated type against
others, the result of that '=' operation being, in fact, a boolean,
defined again on the range (true, false).

> [snip]
> 
> We've discovered that we live in a quantum-mechanical universe -- yet 
> people still don't grasp the pragmatic issue that basic logic can be 
> indeterminate at least some of the time ?!
> 

But actions can't be. You're not asking the software about it's
feelings, you're telling it to follow a defined sequence of
instructions.  Do this, or don't do this.

> I don't know what you mean about composition vs. sub-classing.
> Would you care to show an example of how it would solve the problem and 
> still allow hierarchical sorting ?
> 
> I don't see how you can get pre-existing python functions (like sort, 
> max, and min) to accept a complex bool value and have that value 
> automatically revert to a True or False in an intelligent manner without 
> overloading the operators defined in some class -- somewhere -- to 
> operate on the data the class contains.
> 
> How do you intend to achieve that with this -- composition -- thing you 
> mentioned ?
> 
> 

You'd do it something like this.

class _clogic(object):
	"""Represents 'continuous' logic.  For any given instance,
there is a threshold value between 0 and 1 that delineates True from
False, with 0 being entirely False and 1 being entirely True.
	"""
	
	def __init__(self, value, threshold=0.5):
		self.value = value
		self.threshold = threshold
		
	def __bool__(self):
		return value > threshold
	__nonzero__ = __bool__
	
	def __eq__(self, other):
		if other in (True, False):
			return bool(self) == other
			
		try:
			return self.value == other.value
		except AttributeError:
			return self.value == other
		
	def __and__(self, other):
		return self.__class__(
			min(self.value, other.value),
			self.threshold)

	def __or__(self, other):
		return self.__class__(
			max(self.value, other.value),
			self.threshold)

No need to subclass bool, you just use the __bool__ (or __nonzero__)
methods to say "Alright, well when you do finally have to make a
decision on this thing, here's how you make it.  And obviously, you can
add on as many additional data members to carry additional information
as your heart desires.

-- 
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order.  See above to fix.

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


#84623

FromAndrew Robinson <andrew3@r3dsolutions.com>
Date2015-01-26 15:47 -0800
Message-ID<mailman.18161.1422316025.18130.python-list@python.org>
In reply to#83840
Hi, Rob.
Sorry I'm so slow in getting back to you.... there's too much to read 
and I can't catch up with the backlog.  But I wanted to reply to you, at 
least as I think you made some very good points that make more sense to 
me than other people's replies.

On 01/15/2015 09:54 AM, Rob Gaddi wrote:
> On Wed, 14 Jan 2015 23:23:54 -0800
> Andrew Robinson <andrew3@r3dsolutions.com> wrote:
>
>>> Boolean algebra has two values: true and false, or 1 and 0, or humpty
>>> and dumpty, or whatever you like to call them.
>> You're speaking to an Electrical engineer.  I know there are 10 kinds of
>> people, those who know binary and those who don't.  But you're way off
>> base if you think most industrial quality code for manipulating boolean
>> logic uses (or even can be restricted to use) only two values and still
>> accomplish their tasks correctly and within a finite amount of time.
>>
> [snip]
>
> Absolutely it does and can.  You store anything that's non-boolean in a
> non-boolean value, and keep it as fuzzy as you like.  But at the end of
> the day, an if statement has no "kinda".  You do, or you don't.  1 or
> 0.  And so you must ultimately resolve to a Boolean decision.

Yes -- at the *point* of decision; a logic expression always collapses 
to a True or False value.
metastability must always resolve to a final value, or else the system 
will malfunction.
(Although cache branch prediction can choose to take both paths, one of 
them eventually gets flushed).
That's the same in digital circuitry as well,  even with uncertainty 
meta information appended to it.

>
> You have to ask
>
> 	if x = '1'
> or
> 	if (x = '1') or (x = 'H')
>
> Because you are comparing one value of an enumerated type against
> others, the result of that '=' operation being, in fact, a boolean,
> defined again on the range (true, false).
That's fine, too.   An enumerated type is still a semantic subtype, if 
not a formal one recognized by type().
So -- I don't see that you are arguing the two types must be 
semantically distinct until the if statement is actually executed, at 
which point a true/false decision must be made.  I totally agree, 
digital systems must make a final decision at some point.

Your example, here, BTW: is almost exactly what I was talking about in 
the original few posts of the thread;  Eg: a way to comparing the 
uncertainty value returned by a float's subtype's compare -- against an 
enumerated bool meta-type to resolve that value to a final True or False 
for an if statement.

>
>> [snip]
>>
>> We've discovered that we live in a quantum-mechanical universe -- yet
>> people still don't grasp the pragmatic issue that basic logic can be
>> indeterminate at least some of the time ?!
>>
> But actions can't be. You're not asking the software about it's
> feelings, you're telling it to follow a defined sequence of
> instructions.  Do this, or don't do this.

Right!
And, in quantum mechanics -- a wave packet 'collapses' to one and only 
one final decision.
So, I agree with you; and let me get your opinion:

I admit, there can be good reasons to prevent direct subtyping; I know, 
for example, that in C++ no base class is allowed to be subtyped -- but 
not because of OOP concerns or ideology about bool; I'm fairly sure the 
reason had something to do with difficulties in implementing base class 
overloading in the compiler due to compile time binding issues.

But that's useless reasoning with an interpreter like Python which 
*already* allows subtyping of at least some base classes and does 
runtime type() tests instead of compile time tests.

So: The major question I have been asking about is 'when' must the 
decision be made, and 'why' (besides oversight / copying other 
languages) is the a bool variable/object in Python designed in such a 
way as to force the decision to be made early, rather than late -- and 
prevent bool from carrying extended information about the bool itself; 
eg: meta information -- so that the final decision can be delayed until 
an 'if' statement is actually used, and the context is known:

eg:

x = a > b  # x is an uncertain compare that generates meta data along 
with a boolean True or False.
# this value 'x' can be used in two ways:

if x > bool_meta_threshold:  # if statement's branch chosen by meta data.
if x:  # If statement's branch chosen by default/base bool value 
contained in x, meta data is ignored.

>
>> I don't know what you mean about composition vs. sub-classing.
>> Would you care to show an example of how it would solve the problem and
>> still allow hierarchical sorting ?
>>
>> I don't see how you can get pre-existing python functions (like sort,
>> max, and min) to accept a complex bool value and have that value
>> automatically revert to a True or False in an intelligent manner without
>> overloading the operators defined in some class -- somewhere -- to
>> operate on the data the class contains.
>>
>> How do you intend to achieve that with this -- composition -- thing you
>> mentioned ?
>>
>>
> You'd do it something like this.
>
> class _clogic(object):
> 	"""Represents 'continuous' logic.  For any given instance,
> there is a threshold value between 0 and 1 that delineates True from
> False, with 0 being entirely False and 1 being entirely True.
> 	"""
> 	
> 	def __init__(self, value, threshold=0.5):
> 		self.value = value
> 		self.threshold = threshold
> 		
> 	def __bool__(self):
> 		return value > threshold
> 	__nonzero__ = __bool__
> 	
> 	def __eq__(self, other):
> 		if other in (True, False):
> 			return bool(self) == other
> 			
> 		try:
> 			return self.value == other.value
> 		except AttributeError:
> 			return self.value == other
> 		
> 	def __and__(self, other):
> 		return self.__class__(
> 			min(self.value, other.value),
> 			self.threshold)
>
> 	def __or__(self, other):
> 		return self.__class__(
> 			max(self.value, other.value),
> 			self.threshold)
>
> No need to subclass bool, you just use the __bool__ (or __nonzero__)
> methods to say "Alright, well when you do finally have to make a
> decision on this thing, here's how you make it.  And obviously, you can
> add on as many additional data members to carry additional information
> as your heart desires.
>

Hmmm....  That's not much different than the tuple object I made as a 
container and which Ian complained about.  In fact, you did overload the 
comparison operators, just like I did...

Let's see: Ian first complained that I wasn't subclassing in one 
example, and then he next complained that he thought I was subclassing  
*too quickly*  (like he forgot that I didn't subclass before) because of 
something to do with 'bool' -- and then he mentioned I wasn't using 
composition....

But now --I wonder why it didn't click with him that I avoided 
subclassing bool in my tuple example (at all)  -- because I was clearly 
making a general purpose container (composition pattern) to hold a bool 
and uncertainty value.

So -- I really don't think there is anything wrong with what I already 
did, except perhaps the name of the class was misleading; for it is 
really capable of being general purpose.... not just 'bool'...

In any event, thanks for the example; but it still leaves me with the 
distinct feeling that I'm damned if I do -- and damned if I don't...

LOL.

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


#84628

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-01-26 18:50 -0700
Message-ID<mailman.18162.1422323459.18130.python-list@python.org>
In reply to#83840
On Mon, Jan 26, 2015 at 4:47 PM, Andrew Robinson
<andrew3@r3dsolutions.com> wrote:
> Hmmm....  That's not much different than the tuple object I made as a
> container and which Ian complained about.  In fact, you did overload the
> comparison operators, just like I did...

Yeah, I know I said I was done with this thread, but since you call me
out by name I'll take a moment to respond.

> Let's see: Ian first complained that I wasn't subclassing in one example,

No. What I suggested was that for Python 2 you should explicitly name
a base class of object, i.e. the base class of *everything*. That's
not "you should use subclassing here", but rather "here's a tip for
writing good, Pythonic code".

> and then he next complained that he thought I was subclassing  *too quickly*
> (like he forgot that I didn't subclass before) because of something to do
> with 'bool' -- and then he mentioned I wasn't using composition....

I actually wrote about your tuple subclass "This seems fine," so don't
try to spin my words into something that they aren't. My criticism was
centered on your needless subclassing of tuple (nothing to do with
'bool'), resulting in a boolean class that supports nonsensical
operations like:

>>> len(MostlyFalse)
2

and even:

>>> isinstance(MostlyFalse, Sequence)
True

You may also notice that Rob's example which you compare to your own
doesn't do this.

> But now --I wonder why it didn't click with him that I avoided subclassing
> bool in my tuple example (at all)  -- because I was clearly making a general
> purpose container (composition pattern) to hold a bool and uncertainty
> value.

This is not an example of composition. By subclassing tuple, you are
effectively declaring that your boolean type IS a type of tuple.
Instead of aggressively and arrogantly defending poor code, why don't
you take my criticism as the learning opportunity that it was offered
as? Here would be a good place to start:

http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance

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


#83836

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-01-15 10:05 -0700
Message-ID<mailman.17769.1421341604.18130.python-list@python.org>
In reply to#83661
On Thu, Jan 15, 2015 at 12:23 AM, Andrew Robinson
<andrew3@r3dsolutions.com> wrote:
> Can you name any other language that *does* allow subclassing of
> booleans or creation of new boolean values?
>
> Yes. Several off the top of my head -- and I have mentioned these before.
> They generally come with the extra subclasses pre-created and the user
> doesn't get to create the classes, but only use them; none the less -- they
> have more than two values with which to do logic equations with.
>
> VHDL, Verilog, HDL, Silos III, and there are IEEE variants also.
> C/C++ historically allowed you to do it with instances included, although I
> am not sure it still does.

Sorry, let me rehprase my question. Of course there will be
special-purpose languages that allow you to do interesting things with
the logic values and operators. Can you name any other
*general-purpose* language that allows subclassing of booleans or
creation of new boolean values? If not, it seems rather unfair to
single out Python and marvel that this isn't allowed when it's
actually quite normal to disallow it. Unless you care to provide an
example, I am fairly sure your claim of C/C++ is wrong. The bool type
in C++ is a primitive type, none of which can be inherited from. C
doesn't even have a bool type; at most you have macros for true and
false to 1 and 0, so the "booleans" there are just ordinary integers.

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


#84338

FromAndrew Robinson <andrew3@r3dsolutions.com>
Date2015-01-23 03:46 -0800
Message-ID<mailman.18030.1422013652.18130.python-list@python.org>
In reply to#83661
On 01/15/2015 09:05 AM, Ian Kelly wrote:
> On Thu, Jan 15, 2015 at 12:23 AM, Andrew Robinson
> <andrew3@r3dsolutions.com> wrote:
>> Can you name any other language that *does* allow subclassing of
>> booleans or creation of new boolean values?
>>
>> Yes. Several off the top of my head -- and I have mentioned these before.
>> They generally come with the extra subclasses pre-created and the user
>> doesn't get to create the classes, but only use them; none the less -- they
>> have more than two values with which to do logic equations with.
>>
>> VHDL, Verilog, HDL, Silos III, and there are IEEE variants also.
>> C/C++ historically allowed you to do it with instances included, although I
>> am not sure it still does.
> Sorry, let me rehprase my question. Of course there will be
> special-purpose languages that allow you to do interesting things with
> the logic values and operators. Can you name any other
> *general-purpose* language that allows subclassing of booleans or
> creation of new boolean values? If not, it seems rather unfair to
> single out Python and marvel that this isn't allowed when it's
> actually quite normal to disallow it. Unless you care to provide an
> example, I am fairly sure your claim of C/C++ is wrong. The bool type
> in C++ is a primitive type, none of which can be inherited from. C
> doesn't even have a bool type; at most you have macros for true and
> false to 1 and 0, so the "booleans" there are just ordinary integers.
Ian,
I agree with you mostly; there is good reason to pick on other 
languages, too, with respect to what a bool is.

Although, I have to laugh -- Verilog can syntheze a CPU -- implement 
memory -- and then load a program and run python on the virtual 
machine.   When the pentium was first developed, I watched as Intel 
actually booted up MS-DOS under using Xilinx chips to run the verilog 
program's output they could physically run anything a pentium processor 
could run.  That's *IS* what I consider "general purpose".

But you're sort of confounding my need for type information in my new 
class as a way to advertise compatability with bool, with subclassing -- 
which is only one way that I was exploring to get the 'type' name 
attached to the new object;  That's a mistake that D'Aprano seems to be 
repetitively making as well.
But please note: Type checking for 'bool' is only needed for 
legacy/compatability reasons -- but new code can use any type; so 
subtyping is not strictly necessary if there is another way to get the 
'bool' type attached to my return object for advertising purposes; for 
what I am interested in is an object who presents as bool for legacy 
code, but new code can convert it to anything at all..

C++ *DOES* allow the necessary kind of type checking and subclassing for 
what I need to do in spite of not having a subclass mechanism built into 
the language for base types; eg: C++ allows a semantic subclass to be 
constructed which can be typecast to a bool for compatibility, but 
otherwise presents extra data and the type the enhanced object reports 
is irrelevant.  As I've mentioned before, people can do object oriented 
programming in C,  So, to satisfy your curiosity -- I'll show you a 
mixed C/C++ example, where I make a semantic subclass that has five 
values AllFalse, PartFalse, Uncertain, PartTrue, True ; and these five 
values will have a typeid() of bool and be 100% compatible with legacy 
C++ bool; but upon request, they these 'bool' types will re-cast into a 
semantic subtype that provides additional certainty data.

See the program at end of e-mail.  It compiles with gcc 4.8.2 with no 
warnings;  g++ filename.cc ; ./a.out

But let me explain a bit more why I'm picking on Python:  For even if we 
set the electronic engineering concerns aside that I've raised (and they 
are valid, as OOP is supposed to model reality, not reality be bent to 
match OOP) -- People's facile explanations about why Python's version of 
bool is the way it is -- still bothers me here in the python mail list 
-- because people seem to have a very wrong idea about bool's nature as 
a dualton being somehow justified solely by the fact that there are only 
two values in Boolean logic; For, singletons style programming is not 
justified by the number of values an object has in reality -- And I know 
Charles bool didn't use singletons in his algebra,  -- just read his 
work and you'll see he never mentions them or describes them, but he 
does actually use dozens of *instances* of the True and False objects he 
was talking about -- for the obvious reason that he would have needed 
special mirrors, dichroic or partially silvered, to be even able to 
attempt to make one instance of True written on paper show up in 
multiple places; And that's silly to do when there's no compelling 
reason to do it.

Yet -- people here seem to want to insist that the bool type with only 
two *instances* is some kind of pure re-creation of what Charles Bool 
did -- when clearly it isn't.  It's a amalgamation of enhancements such 
as binary words instead of just True/False and many other things 
(operators that work on words rather than single bits.).  So -- I don't 
see that Python's implementation of Bool is justified by either a purist 
appeal to Charles bool, or by ignoring pragmatic concerns that have been 
attached to Bool's work for years by Electrical Engineers in order to 
make it more useful for *practical* computer problems.  Yet these two 
things are what this python list has sort of harped on.

That brings me to your point about other languages;  I think following 
other languages restrictions arbitrarily is potentially a lemmings 
approach, eg: just because 'everyone' is doing it statistically does not 
mean that it is good to do it that way; If many languages do something, 
there is excellent cause to examine and look for reasons 'why' they do 
that (and I'd love to hear your opinions) but Python has a different set 
of constraints as an interpreter, as opposed to a compiler, and many 
other differences which cause unintended side effects when mimicking 
other programming languages. It's the unintended side effects and 
surprises when a hasty decision is made that's the issue here.

Where python is different from other languages regarding bool -- and 
deserves a little extra picking on, is that Guido has imposed four 
constraints *simultaneously* to bool which together cause a conflict 
that I don't think (offhand) I've ever encountered in another language;  
Definitely not in C/C++!

The four things are: 1 -- he cut off subtyping and created no alternate 
method of doing type checking of duck-types,  2 -- he does not allow 
multiple instances,  3 -- he himself did not implement bool using the 
standard alternative methodology to subclassing -- eg: as a composite 
structure with delegation. 4.  and he has made bool into the default 
return type for base type comparison operators; which means that general 
programmers expect a bool for base types and may check for it, even if 
Python's built in functions do not.

If any one of these four things had not been done, I would not have 
reason to complain about bool in Python; because there would be a way 
for me to easily work with people expecting a bool as a return type from 
comparison operators, using standard OOP techniques and a little 
creativity to make something perfectly compatible; rather than having to 
dig through manuals endlessly with conflicting notions, pep's, and 
subtleties that make for an extremely steep learning curve and lots of 
time spent making only slight progress when there's not much *reasoning* 
behind what Guido did which is consistent and useable as a guideline...

As far a subtyping goes; The very fact that Guido used subtyping to 
create bool in the first place (subtype of int), precludes any real 
claim that bool should not itself be subclassable just because bools 
only have two values;  I mean, seriously --  Guido's 'strict' Bool is 
already an impure form of OOP that is borderline hypocrisy, as it can 
'+' to 2 or 3... and many other things;  and worse I've just come across 
a couple of papers which suggest that Guido doesn't like subclassing 
when Composite object structures could be used instead to replace the 
subclass 'is' relationship with a 'has a' relationship.  So -- if that's 
the case, why isn't bool a composite to begin with ?  eg: Guido's 
programming guides must be read with a caveat 'do what Guido says and 
not what Guido does' ?!

Now to your last point -- I need to point out that  C++ does not have 
all four restrictions I've mentioned so it doesn't have the problem 
Python does;  In C++, there are instances of bool, and therefore I can 
easily encode extra information in a bool object without changing the 
object itself.

Here's a skeleton example, where I only implement one operator '<' on 
the semantic subclass, but the example shows the principle of how to 
extend the bool type via typecasting to bool.  There are better ways of 
doing this, and there are some problems with how I implemented esp. as 
many use cases are not properly covered -- but it serves to show that 
C/C++ CAN encode new subtypes (semantic subtypes only not C++ subtypes) 
while using only the base type itself to transmit data in a perfectly 
backwards compatible way.  In Python, however, it's pretty close to 
hopeless...

#include <iostream>
#include <typeinfo>
using namespace std;

// Create a new super-bool type which is semantically a subtype of bool,
// But have it masquerade as a bool for compatability, unless new code
// explicity typecasts it and access its subtype members.

struct _SBool {
     bool basebool;
     int certainty;
};

class SBool: public _SBool {
public:
     SBool( const bool& );
     bool operator < (const SBool &);
};

// Create all 4 of the statistical uncertainty values as penta-ton.
const _SBool bools[5] = {{false,0},{false,1},{false,2},{false,3},{true,4}};

// Create 4 global alias bool names having full compatability with bool
// for legacy code, but useable in mixed or advanced compares.

const bool & AllFalse  = bools[0].basebool; // uncertainty 0
const bool & PartFalse = bools[1].basebool; // uncertainty 1
const bool & Uncertain = bools[2].basebool; // uncertainty 2
const bool & PartTrue  = bools[3].basebool; // uncertainty 3
const bool & True      = bools[4].basebool; // uncertainty 4

// Create the typecast method.
SBool::SBool( const bool &b ) {
     const void* that = &b;
     if ((that >= bools) && (that < bools+5)) *this=*(const SBool*)that;
     else *this=*(const SBool*)(const void*) &(b?True:AllFalse);

bool SBool::operator < (const SBool &other ) {
     return this->certainty < other.certainty;
}

// ------------------------------------  Test harness.
int main(void) {
     cout << "type match=" <<  (typeid(bool) == typeid(AllFalse)) << endl;
     cout << "testing as bool "       << AllFalse << PartFalse << 
Uncertain << PartTrue << True << endl;
     cout << "testing as SBool "      << SBool(PartFalse).certainty << 
endl;
     cout << "testing up-cast false " << SBool(false).certainty << endl;
     cout << "testing up-cast true "  << SBool(true).certainty << endl;
     cout << "testing advanced compare (should be true)" << 
(SBool(AllFalse) < PartFalse) << endl;
     cout << "testing legacy compare (should be false) " << (AllFalse < 
PartFalse) << endl;
     return 0;
}

//------------------------------------ End of program, Test output 
follows -------------------

type match=1
testing as bool 00001
testing as SBool 1
testing up-cast false 0
testing up-cast true 4
testing advanced compare (should be true)1
testing legacy compare (should be false) 0bash-4.2$












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


#84346

FromRustom Mody <rustompmody@gmail.com>
Date2015-01-23 07:31 -0800
Message-ID<bad017ab-490f-4daa-a552-33591c559398@googlegroups.com>
In reply to#84338
On Friday, January 23, 2015 at 5:18:32 PM UTC+5:30, Andrew Robinson wrote:
> On 01/15/2015 09:05 AM, Ian Kelly wrote:
> > On Thu, Jan 15, 2015 at 12:23 AM, Andrew Robinson wrote:
> >> Can you name any other language that *does* allow subclassing of
> >> booleans or creation of new boolean values?
> >>
> >> Yes. Several off the top of my head -- and I have mentioned these before.
> >> They generally come with the extra subclasses pre-created and the user
> >> doesn't get to create the classes, but only use them; none the less -- they
> >> have more than two values with which to do logic equations with.
> >>
> >> VHDL, Verilog, HDL, Silos III, and there are IEEE variants also.
> >> C/C++ historically allowed you to do it with instances included, although I
> >> am not sure it still does.
> > Sorry, let me rehprase my question. Of course there will be
> > special-purpose languages that allow you to do interesting things with
> > the logic values and operators. Can you name any other
> > *general-purpose* language that allows subclassing of booleans or
> > creation of new boolean values? If not, it seems rather unfair to
> > single out Python and marvel that this isn't allowed when it's
> > actually quite normal to disallow it. Unless you care to provide an
> > example, I am fairly sure your claim of C/C++ is wrong. The bool type
> > in C++ is a primitive type, none of which can be inherited from. C
> > doesn't even have a bool type; at most you have macros for true and
> > false to 1 and 0, so the "booleans" there are just ordinary integers.
> Ian,
> I agree with you mostly; there is good reason to pick on other 
> languages, too, with respect to what a bool is.
> 
> Although, I have to laugh -- Verilog can syntheze a CPU -- implement 
> memory -- and then load a program and run python on the virtual 
> machine.   When the pentium was first developed, I watched as Intel 
> actually booted up MS-DOS under using Xilinx chips to run the verilog 
> program's output they could physically run anything a pentium processor 
> could run.  That's *IS* what I consider "general purpose".
> 
> But you're sort of confounding my need for type information in my new 
> class as a way to advertise compatability with bool, with subclassing -- 
> which is only one way that I was exploring to get the 'type' name 
> attached to the new object;  That's a mistake that D'Aprano seems to be 
> repetitively making as well.
> But please note: Type checking for 'bool' is only needed for 
> legacy/compatability reasons -- but new code can use any type; so 
> subtyping is not strictly necessary if there is another way to get the 
> 'bool' type attached to my return object for advertising purposes; for 
> what I am interested in is an object who presents as bool for legacy 
> code, but new code can convert it to anything at all..
> 
> C++ *DOES* allow the necessary kind of type checking and subclassing for 
> what I need to do in spite of not having a subclass mechanism built into 
> the language for base types; eg: C++ allows a semantic subclass to be 
> constructed which can be typecast to a bool for compatibility, but 
> otherwise presents extra data and the type the enhanced object reports 
> is irrelevant.  As I've mentioned before, people can do object oriented 
> programming in C,  So, to satisfy your curiosity -- I'll show you a 
> mixed C/C++ example, where I make a semantic subclass that has five 
> values AllFalse, PartFalse, Uncertain, PartTrue, True ; and these five 
> values will have a typeid() of bool and be 100% compatible with legacy 
> C++ bool; but upon request, they these 'bool' types will re-cast into a 
> semantic subtype that provides additional certainty data.
> 
> See the program at end of e-mail.  It compiles with gcc 4.8.2 with no 
> warnings;  g++ filename.cc ; ./a.out
> 
> But let me explain a bit more why I'm picking on Python:  For even if we 
> set the electronic engineering concerns aside that I've raised (and they 
> are valid, as OOP is supposed to model reality, not reality be bent to 
> match OOP) -- People's facile explanations about why Python's version of 
> bool is the way it is -- still bothers me here in the python mail list 
> -- because people seem to have a very wrong idea about bool's nature as 
> a dualton being somehow justified solely by the fact that there are only 
> two values in Boolean logic; For, singletons style programming is not 
> justified by the number of values an object has in reality -- And I know 
> Charles bool didn't use singletons in his algebra,  -- just read his 
> work and you'll see he never mentions them or describes them, but he 
> does actually use dozens of *instances* of the True and False objects he 
> was talking about -- for the obvious reason that he would have needed 
> special mirrors, dichroic or partially silvered, to be even able to 
> attempt to make one instance of True written on paper show up in 
> multiple places; And that's silly to do when there's no compelling 
> reason to do it.
> 
> Yet -- people here seem to want to insist that the bool type with only 
> two *instances* is some kind of pure re-creation of what Charles Bool 
> did -- when clearly it isn't.  It's a amalgamation of enhancements such 
> as binary words instead of just True/False and many other things 
> (operators that work on words rather than single bits.).  So -- I don't 
> see that Python's implementation of Bool is justified by either a purist 
> appeal to Charles bool, or by ignoring pragmatic concerns that have been 
> attached to Bool's work for years by Electrical Engineers in order to 
> make it more useful for *practical* computer problems.  Yet these two 
> things are what this python list has sort of harped on.
> 
> That brings me to your point about other languages;  I think following 
> other languages restrictions arbitrarily is potentially a lemmings 
> approach, eg: just because 'everyone' is doing it statistically does not 
> mean that it is good to do it that way; If many languages do something, 
> there is excellent cause to examine and look for reasons 'why' they do 
> that (and I'd love to hear your opinions) but Python has a different set 
> of constraints as an interpreter, as opposed to a compiler, and many 
> other differences which cause unintended side effects when mimicking 
> other programming languages. It's the unintended side effects and 
> surprises when a hasty decision is made that's the issue here.
> 
> Where python is different from other languages regarding bool -- and 
> deserves a little extra picking on, is that Guido has imposed four 
> constraints *simultaneously* to bool which together cause a conflict 
> that I don't think (offhand) I've ever encountered in another language;  
> Definitely not in C/C++!
> 
> The four things are: 1 -- he cut off subtyping and created no alternate 
> method of doing type checking of duck-types,  2 -- he does not allow 
> multiple instances,  3 -- he himself did not implement bool using the 
> standard alternative methodology to subclassing -- eg: as a composite 
> structure with delegation. 4.  and he has made bool into the default 
> return type for base type comparison operators; which means that general 
> programmers expect a bool for base types and may check for it, even if 
> Python's built in functions do not.
> 
> If any one of these four things had not been done, I would not have 
> reason to complain about bool in Python; because there would be a way 
> for me to easily work with people expecting a bool as a return type from 
> comparison operators, using standard OOP techniques and a little 
> creativity to make something perfectly compatible; rather than having to 
> dig through manuals endlessly with conflicting notions, pep's, and 
> subtleties that make for an extremely steep learning curve and lots of 
> time spent making only slight progress when there's not much *reasoning* 
> behind what Guido did which is consistent and useable as a guideline...
> 
> As far a subtyping goes; The very fact that Guido used subtyping to 
> create bool in the first place (subtype of int), precludes any real 
> claim that bool should not itself be subclassable just because bools 
> only have two values;  I mean, seriously --  Guido's 'strict' Bool is 
> already an impure form of OOP that is borderline hypocrisy, as it can 
> '+' to 2 or 3... and many other things;  and worse I've just come across 
> a couple of papers which suggest that Guido doesn't like subclassing 
> when Composite object structures could be used instead to replace the 
> subclass 'is' relationship with a 'has a' relationship.  So -- if that's 
> the case, why isn't bool a composite to begin with ?  eg: Guido's 
> programming guides must be read with a caveat 'do what Guido says and 
> not what Guido does' ?!
> 
> Now to your last point -- I need to point out that  C++ does not have 
> all four restrictions I've mentioned so it doesn't have the problem 
> Python does;  In C++, there are instances of bool, and therefore I can 
> easily encode extra information in a bool object without changing the 
> object itself.
> 
> Here's a skeleton example, where I only implement one operator '<' on 
> the semantic subclass, but the example shows the principle of how to 
> extend the bool type via typecasting to bool.  There are better ways of 
> doing this, and there are some problems with how I implemented esp. as 
> many use cases are not properly covered -- but it serves to show that 
> C/C++ CAN encode new subtypes (semantic subtypes only not C++ subtypes) 
> while using only the base type itself to transmit data in a perfectly 
> backwards compatible way.  In Python, however, it's pretty close to 
> hopeless...
> 
> #include <iostream>
> #include <typeinfo>
> using namespace std;
> 
> // Create a new super-bool type which is semantically a subtype of bool,
> // But have it masquerade as a bool for compatability, unless new code
> // explicity typecasts it and access its subtype members.
> 
> struct _SBool {
>      bool basebool;
>      int certainty;
> };
> 
> class SBool: public _SBool {
> public:
>      SBool( const bool& );
>      bool operator < (const SBool &);
> };
> 
> // Create all 4 of the statistical uncertainty values as penta-ton.
> const _SBool bools[5] = {{false,0},{false,1},{false,2},{false,3},{true,4}};
> 
> // Create 4 global alias bool names having full compatability with bool
> // for legacy code, but useable in mixed or advanced compares.
> 
> const bool & AllFalse  = bools[0].basebool; // uncertainty 0
> const bool & PartFalse = bools[1].basebool; // uncertainty 1
> const bool & Uncertain = bools[2].basebool; // uncertainty 2
> const bool & PartTrue  = bools[3].basebool; // uncertainty 3
> const bool & True      = bools[4].basebool; // uncertainty 4
> 
> // Create the typecast method.
> SBool::SBool( const bool &b ) {
>      const void* that = &b;
>      if ((that >= bools) && (that < bools+5)) *this=*(const SBool*)that;
>      else *this=*(const SBool*)(const void*) &(b?True:AllFalse);
> 
> bool SBool::operator < (const SBool &other ) {
>      return this->certainty < other.certainty;
> }
> 
> // ------------------------------------  Test harness.
> int main(void) {
>      cout << "type match=" <<  (typeid(bool) == typeid(AllFalse)) << endl;
>      cout << "testing as bool "       << AllFalse << PartFalse << 
> Uncertain << PartTrue << True << endl;
>      cout << "testing as SBool "      << SBool(PartFalse).certainty << 
> endl;
>      cout << "testing up-cast false " << SBool(false).certainty << endl;
>      cout << "testing up-cast true "  << SBool(true).certainty << endl;
>      cout << "testing advanced compare (should be true)" << 
> (SBool(AllFalse) < PartFalse) << endl;
>      cout << "testing legacy compare (should be false) " << (AllFalse < 
> PartFalse) << endl;
>      return 0;
> }
> 
> //------------------------------------ End of program, Test output 
> follows -------------------
> 
> type match=1
> testing as bool 00001
> testing as SBool 1
> testing up-cast false 0
> testing up-cast true 4
> testing advanced compare (should be true)1
> testing legacy compare (should be false) 0bash-4.2$

Can you tell me what of the following code does not satisfy your requirements?
[Needs python 3.4]


>>> from enum import IntEnum
>>> class B4(IntEnum):
	F1 = 0
	F2 = 0
	F3 = 0
	T  = 1

In words:
Thats a type of 4-valued boolean
Of which F1/2/3 behave falsey in standard python bool-expecting contexts
T behaves truey (or truish)
[Check with bool(B4.F1) for example]

If you get fed up with typing B4.blah make global variables (actually constants)
F2 = B4.F2

If you need to distinguish the falsey ones, its a bit of a headache
dict(B4.__members__)
should contain all the info you need to make these distinctions

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


#84353

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-01-23 09:50 -0700
Message-ID<mailman.18039.1422031903.18130.python-list@python.org>
In reply to#84346
On Fri, Jan 23, 2015 at 8:31 AM, Rustom Mody <rustompmody@gmail.com> wrote:
> Can you tell me what of the following code does not satisfy your requirements?
> [Needs python 3.4]
>
>
>>>> from enum import IntEnum
>>>> class B4(IntEnum):
>         F1 = 0
>         F2 = 0
>         F3 = 0
>         T  = 1

This strikes me as a potential problem:

>>> B4.F1 is B4.F2 is B4.F3
True
>>> list(B4)
[<B4.F1: 0>, <B4.T: 1>]

Enum members with the same values are just aliases for one another,
not distinct entities.

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


#84355

FromRustom Mody <rustompmody@gmail.com>
Date2015-01-23 09:03 -0800
Message-ID<5a785a32-3855-457f-be3f-76066dfb20c8@googlegroups.com>
In reply to#84353
On Friday, January 23, 2015 at 10:22:06 PM UTC+5:30, Ian wrote:
> On Fri, Jan 23, 2015 at 8:31 AM, Rustom Mody wrote:
> > Can you tell me what of the following code does not satisfy your requirements?
> > [Needs python 3.4]
> >
> >
> >>>> from enum import IntEnum
> >>>> class B4(IntEnum):
> >         F1 = 0
> >         F2 = 0
> >         F3 = 0
> >         T  = 1
> 
> This strikes me as a potential problem:
> 
> >>> B4.F1 is B4.F2 is B4.F3
> True
> >>> list(B4)
> [<B4.F1: 0>, <B4.T: 1>]
> 
> Enum members with the same values are just aliases for one another,
> not distinct entities.

Yeah....

The only workaround I have been able to come up with is:

class B4(IntEnum):
>         F1 = 0
>         F2 = ""
>         F3 = None
>         T  = 1 

which is not bad; its ridiculous
[Like going around with a broken broom searching for falsey objects :-) ]

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


#84363

FromChris Angelico <rosuav@gmail.com>
Date2015-01-24 04:23 +1100
Message-ID<mailman.18043.1422033834.18130.python-list@python.org>
In reply to#84355
On Sat, Jan 24, 2015 at 4:03 AM, Rustom Mody <rustompmody@gmail.com> wrote:
> The only workaround I have been able to come up with is:
>
> class B4(IntEnum):
>>         F1 = 0
>>         F2 = ""
>>         F3 = None
>>         T  = 1
>
> which is not bad; its ridiculous

It's ridiculous because you declared an IntEnum and then started using
non-integer values that boolify to the same value (and don't intify).
If that even works, it's a total hack, and it might stop working in a
future version... for example, it doesn't seem to work on my Python
3.5:

>>> class B4(IntEnum):
...  F1=0
...  F2=""
...  F3=None
...  T=1
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/enum.py", line 152, in __new__
    enum_member = __new__(enum_class, *args)
ValueError: invalid literal for int() with base 10: ''

Using Enum instead of IntEnum does work, but it's still hardly a
normal use of an enumeration.

ChrisA

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


#84364

FromRustom Mody <rustompmody@gmail.com>
Date2015-01-23 09:29 -0800
Message-ID<4f8bb3c3-212a-4fe4-83fa-87c27939550e@googlegroups.com>
In reply to#84363
On Friday, January 23, 2015 at 10:54:06 PM UTC+5:30, Chris Angelico wrote:
> On Sat, Jan 24, 2015 at 4:03 AM, Rustom Mody wrote:
> > The only workaround I have been able to come up with is:
> >
> > class B4(IntEnum):
> >>         F1 = 0
> >>         F2 = ""
> >>         F3 = None
> >>         T  = 1
> >
> > which is not bad; its ridiculous
> 
> It's ridiculous because you declared an IntEnum and then started using
> non-integer values that boolify to the same value (and don't intify).
> If that even works, it's a total hack, and it might stop working in a
> future version... for example, it doesn't seem to work on my Python
> 3.5:
> 
> >>> class B4(IntEnum):
> ...  F1=0
> ...  F2=""
> ...  F3=None
> ...  T=1
> ...
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "/usr/local/lib/python3.5/enum.py", line 152, in __new__
>     enum_member = __new__(enum_class, *args)
> ValueError: invalid literal for int() with base 10: ''
> 
> Using Enum instead of IntEnum does work, but it's still hardly a
> normal use of an enumeration.
> 
> ChrisA

I mis-cut-n-pasted.
Should have been Enum not IntEnum

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


#84377

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-01-23 11:04 -0700
Message-ID<mailman.18051.1422036308.18130.python-list@python.org>
In reply to#84355
On Fri, Jan 23, 2015 at 10:03 AM, Rustom Mody <rustompmody@gmail.com> wrote:
> On Friday, January 23, 2015 at 10:22:06 PM UTC+5:30, Ian wrote:
>> On Fri, Jan 23, 2015 at 8:31 AM, Rustom Mody wrote:
>> > Can you tell me what of the following code does not satisfy your requirements?
>> > [Needs python 3.4]
>> >
>> >
>> >>>> from enum import IntEnum
>> >>>> class B4(IntEnum):
>> >         F1 = 0
>> >         F2 = 0
>> >         F3 = 0
>> >         T  = 1
>>
>> This strikes me as a potential problem:
>>
>> >>> B4.F1 is B4.F2 is B4.F3
>> True
>> >>> list(B4)
>> [<B4.F1: 0>, <B4.T: 1>]
>>
>> Enum members with the same values are just aliases for one another,
>> not distinct entities.
>
> Yeah....
>
> The only workaround I have been able to come up with is:
>
> class B4(IntEnum):
>>         F1 = 0
>>         F2 = ""
>>         F3 = None
>>         T  = 1
>
> which is not bad; its ridiculous
> [Like going around with a broken broom searching for falsey objects :-) ]

How about something like this:

>>> from enum import Enum
>>> class B4(Enum):
...     F1 = (False, 1)
...     F2 = (False, 2)
...     F3 = (False, 3)
...     T = (True, 4)
...     def __bool__(self):
...         return self.value[0]
...
>>> B4.F1 is B4.F2
False
>>> bool(B4.F1)
False
>>> bool(B4.T)
True

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


#84427

FromRustom Mody <rustompmody@gmail.com>
Date2015-01-23 19:13 -0800
Message-ID<970f0828-0d39-4b0c-9102-bbc8a42800fc@googlegroups.com>
In reply to#84377
On Friday, January 23, 2015 at 11:35:49 PM UTC+5:30, Ian wrote:
> On Fri, Jan 23, 2015 at 10:03 AM, Rustom Mody wrote:
> > On Friday, January 23, 2015 at 10:22:06 PM UTC+5:30, Ian wrote:
> >> On Fri, Jan 23, 2015 at 8:31 AM, Rustom Mody wrote:
> >> > Can you tell me what of the following code does not satisfy your requirements?
> >> > [Needs python 3.4]
> >> >
> >> >
> >> >>>> from enum import IntEnum
> >> >>>> class B4(IntEnum):
> >> >         F1 = 0
> >> >         F2 = 0
> >> >         F3 = 0
> >> >         T  = 1
> >>
> >> This strikes me as a potential problem:
> >>
> >> >>> B4.F1 is B4.F2 is B4.F3
> >> True
> >> >>> list(B4)
> >> [<B4.F1: 0>, <B4.T: 1>]
> >>
> >> Enum members with the same values are just aliases for one another,
> >> not distinct entities.
> >
> > Yeah....
> >
> > The only workaround I have been able to come up with is:
> >
> > class B4(IntEnum):
> >>         F1 = 0
> >>         F2 = ""
> >>         F3 = None
> >>         T  = 1
> >
> > which is not bad; its ridiculous
> > [Like going around with a broken broom searching for falsey objects :-) ]
> 
> How about something like this:
> 
> >>> from enum import Enum
> >>> class B4(Enum):
> ...     F1 = (False, 1)
> ...     F2 = (False, 2)
> ...     F3 = (False, 3)
> ...     T = (True, 4)
> ...     def __bool__(self):
> ...         return self.value[0]
> ...
> >>> B4.F1 is B4.F2
> False
> >>> bool(B4.F1)
> False
> >>> bool(B4.T)
> True

‼Perfect‼
For the OP you may like to read the following:

[And if you dont short version is use __bool__ in python3 __nonzero__ in python2
]

http://stackoverflow.com/questions/8909932/how-to-overload-pythons-bool-method
http://stackoverflow.com/questions/2233786/overriding-bool-for-custom-class
https://docs.python.org/2/reference/datamodel.html#object.__nonzero__

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


#84428

FromRustom Mody <rustompmody@gmail.com>
Date2015-01-23 19:21 -0800
Message-ID<0eec1312-9674-4edc-b65d-5a2801ff4730@googlegroups.com>
In reply to#84377
On Friday, January 23, 2015 at 11:35:49 PM UTC+5:30, Ian wrote:
> On Fri, Jan 23, 2015 at 10:03 AM, Rustom Mody  wrote:
> > On Friday, January 23, 2015 at 10:22:06 PM UTC+5:30, Ian wrote:
> >> On Fri, Jan 23, 2015 at 8:31 AM, Rustom Mody wrote:
> >> > Can you tell me what of the following code does not satisfy your requirements?
> >> > [Needs python 3.4]
> >> >
> >> >
> >> >>>> from enum import IntEnum
> >> >>>> class B4(IntEnum):
> >> >         F1 = 0
> >> >         F2 = 0
> >> >         F3 = 0
> >> >         T  = 1
> >>
> >> This strikes me as a potential problem:
> >>
> >> >>> B4.F1 is B4.F2 is B4.F3
> >> True
> >> >>> list(B4)
> >> [<B4.F1: 0>, <B4.T: 1>]
> >>
> >> Enum members with the same values are just aliases for one another,
> >> not distinct entities.
> >
> > Yeah....
> >
> > The only workaround I have been able to come up with is:
> >
> > class B4(IntEnum):
> >>         F1 = 0
> >>         F2 = ""
> >>         F3 = None
> >>         T  = 1
> >
> > which is not bad; its ridiculous
> > [Like going around with a broken broom searching for falsey objects :-) ]
> 
> How about something like this:
> 
> >>> from enum import Enum
> >>> class B4(Enum):
> ...     F1 = (False, 1)
> ...     F2 = (False, 2)
> ...     F3 = (False, 3)
> ...     T = (True, 4)
> ...     def __bool__(self):
> ...         return self.value[0]
> ...
> >>> B4.F1 is B4.F2
> False
> >>> bool(B4.F1)
> False
> >>> bool(B4.T)
> True

Simpler (though less general)

class B4(Enum):
	F1 = 1
	F2 = 2
	F3 = 3
	T  = 4
	def __bool__(self): return self.value == 4

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


#84435

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-01-24 16:01 +1100
Message-ID<54c32716$0$13009$c3e8da3$5496439d@news.astraweb.com>
In reply to#84355
Rustom Mody wrote:

> On Friday, January 23, 2015 at 10:22:06 PM UTC+5:30, Ian wrote:
>> On Fri, Jan 23, 2015 at 8:31 AM, Rustom Mody wrote:
>> > Can you tell me what of the following code does not satisfy your
>> > requirements?
>> > [Needs python 3.4]
>> >
>> >
>> >>>> from enum import IntEnum
>> >>>> class B4(IntEnum):
>> >         F1 = 0
>> >         F2 = 0
>> >         F3 = 0
>> >         T  = 1
>> 
>> This strikes me as a potential problem:
>> 
>> >>> B4.F1 is B4.F2 is B4.F3
>> True
>> >>> list(B4)
>> [<B4.F1: 0>, <B4.T: 1>]
>> 
>> Enum members with the same values are just aliases for one another,
>> not distinct entities.
> 
> Yeah....
> 
> The only workaround I have been able to come up with is:
> 
> class B4(IntEnum):
>>         F1 = 0
>>         F2 = ""
>>         F3 = None
>>         T  = 1
> 
> which is not bad; its ridiculous
> [Like going around with a broken broom searching for falsey objects :-) ]


It certainly is. But fortunately it is not necessary.

# Untested
class B4(IntEnum):
    F1 = 0
    F2 = 1
    F3 = 2
    T  = 3
    def __bool__(self):
        return self is B4.T
    def __str__(self):
        if self is B4.F1: return "Certainly False"
        if self is B4.F2: return "Maybe False"
        if self is B4.F3: return "Maybe True"
        if self is B4.T: return "Certainly True"



-- 
Steven

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


#84438

FromChris Angelico <rosuav@gmail.com>
Date2015-01-24 16:43 +1100
Message-ID<mailman.18075.1422078215.18130.python-list@python.org>
In reply to#84435
On Sat, Jan 24, 2015 at 4:01 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> # Untested
> class B4(IntEnum):
>     F1 = 0
>     F2 = 1
>     F3 = 2
>     T  = 3
>     def __bool__(self):
>         return self is B4.T
>     def __str__(self):
>         if self is B4.F1: return "Certainly False"
>         if self is B4.F2: return "Maybe False"
>         if self is B4.F3: return "Maybe True"
>         if self is B4.T: return "Certainly True"

I keep expecting to hear Bluebottle asking about why we didn't figure
this out B4... anyway.

class B4(IntEnum):
    CertainlyFalse = 0
    MaybeFalse = 1
    MaybeTrue = 2
    CertainlyTrue  = 3
    def __bool__(self):
        return self is B4.CertainlyTrue

Now you don't need a __str__ function. :)

ChrisA

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


#84362

FromRustom Mody <rustompmody@gmail.com>
Date2015-01-23 09:22 -0800
Message-ID<bb5f6854-5ae9-48e5-bb89-4870a552a00f@googlegroups.com>
In reply to#84353
On Friday, January 23, 2015 at 10:22:06 PM UTC+5:30, Ian wrote:
> On Fri, Jan 23, 2015 at 8:31 AM, Rustom Mody  wrote:
> > Can you tell me what of the following code does not satisfy your requirements?
> > [Needs python 3.4]
> >
> >
> >>>> from enum import IntEnum
> >>>> class B4(IntEnum):
> >         F1 = 0
> >         F2 = 0
> >         F3 = 0
> >         T  = 1
> 
> This strikes me as a potential problem:
> 
> >>> B4.F1 is B4.F2 is B4.F3
> True

Thanks for pointing that out
I saw the problem but not where/why/how

Strikes me that making enumerations is-equal rather than just
=-equal is a bit heavy-handed and unnecessary
What do you think?
[BTW Changing IntEnum to (plain) Enum does not help]

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


#84365

FromChris Angelico <rosuav@gmail.com>
Date2015-01-24 04:37 +1100
Message-ID<mailman.18044.1422034655.18130.python-list@python.org>
In reply to#84362
On Sat, Jan 24, 2015 at 4:22 AM, Rustom Mody <rustompmody@gmail.com> wrote:
> Strikes me that making enumerations is-equal rather than just
> =-equal is a bit heavy-handed and unnecessary
> What do you think?

*Normal* use of an enumeration does make sense for them to be
identical. Classic use would be like this:

class AnsiColor(IntEnum):
    black = 0
    red = 1
    green = 2
    orange = 3
    # ... blue, magenta, cyan, white
    bold_black = 8
    bold_red = 9
    # etc etc etc
    bold_orange = 11
    yellow = 11 # On many screens, bold orange looks more yellow

There is absolutely no difference between the ANSI color "bold orange"
and the ANSI color "yellow". So you would expect them to be identical:

>>> AnsiColor.yellow
<AnsiColor.bold_orange: 11>
>>> AnsiColor.yellow is AnsiColor.bold_orange
True

And they are. There's simply no use-case for equal-but-distinct
tokens, when you're primarily using this to give names to numbers. For
another example, you could localize all the color names, or use
"bright" instead of "bold", or drop the underscores; but ultimately,
if you send "\e[11m" to the console, you're going to get the same
color, whether that 11 was called "bold_orange" or "jaune".

What you're trying to do here is a hack, so it's no surprise that the
system doesn't properly support it.

ChrisA

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


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

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


csiph-web