niXforums Forum Index
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   PreferencesPreferences   Log in to check your private messagesLog in to check your private messages   Log inLog in 
·  nixdoc.net ·  man pages ·  Linux HOWTOs ·  FreeBSD Tips ·  Forums
navigation Forum index » Programming » python
Enumeration idioms: Values from different enumerations
Post new topic   Reply to topic Page 1 of 2 [28 Posts] View previous topic :: View next topic
Goto page:  1, 2 Next
Author Message
Steven D'Aprano
*nix forums Guru


Joined: 07 May 2005
Posts: 1020

PostPosted: Sat Dec 24, 2005 1:59 am    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

On Fri, 23 Dec 2005 23:51:22 +0200, Max wrote:

Quote:
Steven D'Aprano wrote:

They certainly don't look much further from being integers than
booleans do.


You think?

hamburger, steak, fish, chicken, pizza

What meaning do you give to steak**fish? Should that meaning change if I
happened to have written pizza first instead of last?

What meaning do you give to True**False?

Given that True == 1 and False == 0 in Python (which in my opinion is
unfortunate), then it is obviously 1.

True booleans don't support arithmetic operators like **, and neither
should enums.



--
Steven.
Back to top
Max
*nix forums addict


Joined: 17 Mar 2005
Posts: 74

PostPosted: Fri Dec 23, 2005 9:51 pm    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

Steven D'Aprano wrote:
Quote:

They certainly don't look much further from being integers than
booleans do.


You think?

hamburger, steak, fish, chicken, pizza

What meaning do you give to steak**fish? Should that meaning change if I
happened to have written pizza first instead of last?

What meaning do you give to True**False?

Quote:

The fact that they can be counted shouldn't fool you into thinking they
are numbers.




--Max
Back to top
Bengt Richter
*nix forums Guru


Joined: 25 Feb 2005
Posts: 711

PostPosted: Tue Dec 20, 2005 2:37 pm    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

On Tue, 20 Dec 2005 09:16:03 +1100, Ben Finney <bignose+hates-spam@benfinney.id.au> wrote:

Quote:
eswald@gmail.com writes:
Ben Finney wrote:
Is there some behaviour other than "evaluate to False" or "raise an
exception", that could indicate "not comparable"?

Yes: return NotImplemented. Note that the == operator automagically
returns False in this case.

"spam".__eq__("spam")
True
"spam".__eq__("ham")
False
"spam".__eq__(23)
NotImplemented

This way, the user could explicitly call __eq__ and check for
NotImplemented if he desires the exceptional behavior.

Thanks, I was unaware of the standard usage of NotImplemented. That
seems like a sensible solution.

URL:http://docs.python.org/ref/types.html#l2h-29

OTOH, that says the truth value is True, so this does not fail:


Quote:
assert 'spam'.__eq__(23)


Which seems counterintuitive. The explicit value test

Quote:
assert 'spam'.__eq__(23) is NotImplemented

would succeed irrespective of truth value,
but it seems contorted and unpythonic to have to write

Quote:
assert 'spam'.__eq__(23) is False
Traceback (most recent call last):

File "<stdin>", line 1, in ?
AssertionError
Quote:


to get the effect you might naively expect from

Quote:
assert 'spam'.__eq__(23)


I wonder what the rationale for the NotImplemented True truth value was, as opposed to False.

On the third hand, I recently posted an idea of using NotImplemented
as a (handy because predefined) logically true sentinel value to return
from a test function to distinguish not_applicable from applicable_and_ok
when desired, yet allowing assert testfun(...) to succeed either way.
That code would have to use another boolishly True sentinel if NotImplemented
were changed to have False truth value.

Maybe it would be useful to have a couple of builtin sentinels like TrueSentinel
and FalseSentinel (or sentinel_t and sentinel_f or pick some names Wink so we
wouldn't be tempted to misuse unique builtins like NotImplemented and Exception etc.

Regards,
Bengt Richter
Back to top
Ben Finney
*nix forums Guru Wannabe


Joined: 10 May 2005
Posts: 240

PostPosted: Mon Dec 19, 2005 10:16 pm    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

eswald@gmail.com writes:
Quote:
Ben Finney wrote:
Is there some behaviour other than "evaluate to False" or "raise an
exception", that could indicate "not comparable"?

Yes: return NotImplemented. Note that the == operator automagically
returns False in this case.

"spam".__eq__("spam")
True
"spam".__eq__("ham")
False
"spam".__eq__(23)
NotImplemented

This way, the user could explicitly call __eq__ and check for
NotImplemented if he desires the exceptional behavior.

Thanks, I was unaware of the standard usage of NotImplemented. That
seems like a sensible solution.

<URL:http://docs.python.org/ref/types.html#l2h-29>

--
\ "My doctor told me to stop having intimate dinners for four. |
`\ Unless there are three other people." -- Orson Welles |
_o__) |
Ben Finney
Back to top
eswald@gmail.com
*nix forums beginner


Joined: 19 Dec 2005
Posts: 1

PostPosted: Mon Dec 19, 2005 6:03 pm    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

Ben Finney wrote:
Quote:
Antoon Pardon wrote:
I just downloaded your enum module for python [from the Cheeseshop]
and played a bit with it. IMO some of the behaviour makes it less
usefull.
[...]
I also think it would be more usefull if enums from different
enumerations just tested unequal.
[...]

However, I'm aware that this is not how other Python types behave:

23 == 23
True
42 == 23
False
"spam" == 23
False

Is there a semantic difference between these cases? Is that difference
enough to want different behaviour?

Is there some behaviour other than "evaluate to False" or "raise an
exception", that could indicate "not comparable"?

Yes: return NotImplemented. Note that the == operator automagically
returns False in this case.

Quote:
"spam".__eq__("spam")
True
"spam".__eq__("ham")
False
"spam".__eq__(23)
NotImplemented


This way, the user could explicitly call __eq__ and check for
NotImplemented if he desires the exceptional behavior.

- Eric
Back to top
Steven D'Aprano
*nix forums Guru


Joined: 07 May 2005
Posts: 1020

PostPosted: Mon Dec 19, 2005 2:41 pm    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

On Mon, 19 Dec 2005 05:30:11 -0800, Ben Sizer wrote:

Quote:
Enums are not conceptually subclasses of integers. Integers just happen to
be a useful method to implement enumerations.

Aren't they? They have discrete values, can be ordered and compared for
equality, etc.

Just like:

mammal, reptile, amphibian, bird, fish

They are discrete values, they can be ordered in many different ways
(alphabetically, by biological clade, by average number of genes, etc),
and compared for equality (fish is not bird). But they aren't numbers.

It is true that you can create a one-to-one mapping from integers to
enums, but then you can also create a one-to-one mapping from William
Shakespeare's sonnets to enums. That second implementation is,
unfortunately, rather impractical.


Quote:
I think the 'numerate' part of 'enumeration' is a hint
here.

It certainly is a hint, but not of what you think. It means they are
countable, not that they are numbers. You could try looking "enumerate"
up in the dictionary: it means to count, as in "by the time she finished
enumerating all my flaws, I felt three inches high".

Quote:
They certainly don't look much further from being integers than
booleans do.

You think?

hamburger, steak, fish, chicken, pizza

What meaning do you give to steak**fish? Should that meaning change if I
happened to have written pizza first instead of last?

The fact that they can be counted shouldn't fool you into thinking they
are numbers.



--
Steven.
Back to top
Ben Sizer
*nix forums addict


Joined: 01 Mar 2005
Posts: 93

PostPosted: Mon Dec 19, 2005 1:30 pm    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

Steven D'Aprano wrote:
Quote:
On Fri, 16 Dec 2005 02:43:35 -0800, Ben Sizer wrote:
Is it possible to make it have the following sort of behaviour? :

ShirtSize.small == AppleSize.small
True

Okay, so I was wrong to say that nobody was seriously suggesting that sort
of behaviour.

I was working under what looks to have been an incorrect assumption
that someone was looking for a way to do the above. After all, it was
mentioned in what seemed like seriousness. I can't think of a use case
for it, myself.

Quote:
It works for comparing a boolean (True) vs. an integer (1), so it has
some sort of precedent. (Especially if you make the tenuous assumption
that True,False are language-supported 'enums' for 0 and 1.)

Enums are not conceptually subclasses of integers. Integers just happen to
be a useful method to implement enumerations.

Aren't they? They have discrete values, can be ordered and compared for
equality, etc. I think the 'numerate' part of 'enumeration' is a hint
here. They certainly don't look much further from being integers than
booleans do. But, if nobody actually needs the behaviour I described
before, this point is irrelevant.

--
Ben Sizer
Back to top
Ben Finney
*nix forums Guru Wannabe


Joined: 10 May 2005
Posts: 240

PostPosted: Sat Dec 17, 2005 12:42 am    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

"Ben Sizer" <kylotan@gmail.com> writes:
Quote:
Transitivity within any single enumeration plus transivity of
equivalence across multiple enumerations, should be enough for most
needs, no?

+1 to transitivity within an enumeration. -1 to transitivity across
enumerations. If they're supposed to be equivalent, why are you
separating them into different enumerations at all?

The whole point of an enumeration, as I see it, is to have a set of
values that are only meaningfully equal or sequenced within that
enumeration.

--
\ "You've got the brain of a four-year-old boy, and I'll bet he |
`\ was glad to get rid of it." -- Groucho Marx |
_o__) |
Ben Finney
Back to top
Ben Finney
*nix forums Guru Wannabe


Joined: 10 May 2005
Posts: 240

PostPosted: Sat Dec 17, 2005 12:37 am    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

Paul Rubin <http://phr.cx@NOSPAM.invalid> writes:
Quote:
All in all, comparing by object identity doesn't sound too good.
Maybe you want to have the enum contain its own name internally, and
do a string comparison.

The "__eq__ compares identity" was a glib pseudo-implementation; I
didn't think it through. The existing 'enum' implementation doesn't
use identity, and future ones won't either.

The intended meaning was more like:

class EnumValue(object):
# ...
def __eq__(self, other):
result = compare_attribute_values(self, other)
return result

In other words, identity doesn't matter, but every value from every
enumeration will compare inequal to each other. If an EnumValue
instance is copied, the copies will compare equal.

--
\ "Remember men, we're fighting for this woman's honour; which is |
`\ probably more than she ever did." -- Groucho Marx |
_o__) |
Ben Finney <http://www.benfinney.id.au/>
Back to top
Steven D'Aprano
*nix forums Guru


Joined: 07 May 2005
Posts: 1020

PostPosted: Sat Dec 17, 2005 12:23 am    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

On Fri, 16 Dec 2005 02:43:35 -0800, Ben Sizer wrote:

Quote:
Ben Finney wrote:
The problem with "is the same value" as an explanation for '==' is
that it doesn't help in cases such as::

ShirtSize = Enum('small', 'medium', 'large')
AppleSize = Enum('small', 'large')

What should be the result of this comparison::

ShirtSize.small == AppleSize.small

Are they "the same value"? They're both "small" (and they both coerce
to the same string value, and in this case the same integer value).

Is it possible to make it have the following sort of behaviour? :

ShirtSize.small == AppleSize.small
True

Okay, so I was wrong to say that nobody was seriously suggesting that sort
of behaviour.

Quote:
It works for comparing a boolean (True) vs. an integer (1), so it has
some sort of precedent. (Especially if you make the tenuous assumption
that True,False are language-supported 'enums' for 0 and 1.)

Enums are not conceptually subclasses of integers. Integers just happen to
be a useful method to implement enumerations.


--
Steven.
Back to top
Steven D'Aprano
*nix forums Guru


Joined: 07 May 2005
Posts: 1020

PostPosted: Sat Dec 17, 2005 12:17 am    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

On Fri, 16 Dec 2005 19:45:51 +1100, Ben Finney wrote:

Quote:
The problem with "is the same value" as an explanation for '==' is
that it doesn't help in cases such as::

ShirtSize = Enum('small', 'medium', 'large')
AppleSize = Enum('small', 'large')

What should be the result of this comparison::

ShirtSize.small == AppleSize.small

Are they "the same value"? They're both "small" (and they both coerce
to the same string value, and in this case the same integer value).

I don't think anyone seriously intends to argue that ShirtSize.small
should test equal to AppleSize.small.



Quote:
If not, is 'False' the right way to indicate that?

Why not? The intuitive answer is that they are "not equal".

In the case of apples and shirts, the intuitive answer can be misleading
because if you had a small enough shirt (say, for a Barbi doll) one might
be tempted to say "Yes, they are the same size".

A better example might be StringLength.long == BookSize.long. Both coerce
to the same string, but one measures physical length and the other
measures number of words. They are incompatible measures, and can't be
ordered. A strict physicist might argue that asking "is five kilograms
equal to three metres?" is a nonsensical question, but that's not the
Python way.

(And an even better physicist will answer that kilograms and metres can
not only be tested for equality, but can be ordered -- there are
mathematical transformations, common in relativistic physics, where all
physical quantities including time and mass, are transformed into lengths.
These physicists calculated *everything* in terms of dimensionless values
and multiples of length, length squared, length cubed, etc.)



Quote:
Or is it an error to even try comparing them?

Perhaps there are unusual cases where comparing strings and ints for
equality should be an error. There may even be unusual cases where
comparing ints and floats should be an error. But I don't believe that
this should be the default behaviour, and it isn't the Python way.

Likewise for enums from different enumerations. By default they should
evaluate unequal, not raise an exemption.


--
Steven.
Back to top
Steven D'Aprano
*nix forums Guru


Joined: 07 May 2005
Posts: 1020

PostPosted: Fri Dec 16, 2005 11:44 pm    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

On Thu, 15 Dec 2005 23:53:36 -0500, Peter Hansen wrote:

Quote:
Ben Finney wrote:
These are valid concerns. I can't see how to reconcile these against
the desire for values from different enums to fail comparison.

Am I alone in my tri-state view of enumeration value comparisons? Can
anyone else defend why values from different enumerations should not
compare?

While I'm largely a disinterested bystander, it occurs to me that if you
look at the reasons behind wanting enumerations in the first place, you
might find a good reason to defend this view.

For example, if enumerations are intended to reduce the likelihood of
certain types of errors (where the use of typical XXXX=3 "constants"
might be more prone to errors), then perhaps this suggests that passing
errors silently is bad. That is, trying to compare enumerations that
should not be compared *is* an error (raising an exception) *because*
the whole point of enumerations is to avoid errors in such cases.


In my opinion, rather than make all enums fail equality testing, two
better solutions would be:

(1) sub-class Enum to have StrictEnum. Enum allows equality testing for
normal Pythonic behaviour. StrictEnum fails equality testing for extra B&D
behaviour.

(2) Expect the user to make an explicit test when they want the stricter
testing. At the moment two different enumerations have the same class, but
Ben could (perhaps) hash the enumeration values to get a unique ID that
distinguishes one enumeration from another. Or some other strategy that
would allow something like:

if value.from_same_enumeration(other) and value == other

for value and other both enums.

Of the two, I suspect that (1) is far less work for both Ben and the
people using his class, although for introspection purposes it might be
nice to have some sort of unique enumeration ID. That could even be
something as simple as a tuple of the enumeration values.


--
Steven.
Back to top
Steven D'Aprano
*nix forums Guru


Joined: 07 May 2005
Posts: 1020

PostPosted: Fri Dec 16, 2005 11:31 pm    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

On Fri, 16 Dec 2005 15:16:08 +1100, Ben Finney wrote:

Quote:
As can be seen from the above, you raise an exception when one wants
to compare Enums from different enumarations, but it seems a bit
strange that different enumerations belong to the same type.

This does seem a point that could be confusing. Would it be better if
every Enum instance had its own unique subclass of EnumValue, that was
used to instantiate values for that enumeration?

That seems to be creating complication for its own sake.


Quote:
I also think it would be more usefull if enums from different
enumerations just tested unequal.

My rationale for this is: The only purpose of an enumeration is to
have a set of arbitrary unique values within that enumeration. The
values make no sense in the context of a different enumeration, so I
see three different comparison results:

Weekday.mon == Weekday.mon
True
Weekday.fri == Weekday.mon
False
Colour.blue == Weekday.mon
[...]
enum.EnumValueCompareError: Not values from the same enumeration

However, I'm aware that this is not how other Python types behave:

23 == 23
True
42 == 23
False
"spam" == 23
False

Is there a semantic difference between these cases? Is that difference
enough to want different behaviour?

I don't believe so.

It seems reasonable to me for other comparisons such as __lt__ etc.
to fail unless the objects belong to the same enumeration. But equality
and inequality are special. Unordered objects support equality testing.

The question whether Mohammad is greater than or less than the mountain
has no answer, because we don't know how to order the two (by height? by
mass? by religious belief? by economic value? by importance to human
history?). But we can certainly answer the question is Mohammad equal to
the mountain -- the answer is certainly no, no matter how we order them.


Quote:
Because as it is you can't put elements from different enumerations
in a list and check with the in operator if a specific enum value is
in the list.

It could also cause problems for dictionaries, since keys in
dictionaries can be tested against a key giving in a subscription.

These are valid concerns. I can't see how to reconcile these against
the desire for values from different enums to fail comparison.

Perhaps you are just being over-strict -- soon you'll be writing in Pascal
:-)

Failing order comparisons is reasonable, but why refuse to test for
equality? If you ask "is Monday equal to Blue?" the intuitive answer is
"no", not "my brain just crashed trying to evaluate the answer!".


--
Steven.
Back to top
Mike Meyer
*nix forums Guru


Joined: 21 Feb 2005
Posts: 1044

PostPosted: Fri Dec 16, 2005 4:28 pm    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

Ben Finney <bignose@polar.local> writes:
Quote:
Mike Meyer <mwm@mired.org> writes:
Peter Hansen <peter@engcorp.com> writes:
That is, [perhaps] trying to compare enumerations that should not
be compared *is* an error (raising an exception) *because* the
whole point of enumerations is to avoid errors in such cases.
Except it might not be an error. For instance, if I've got a list of
enum objects taken from various types (say I've got one set of enums
for days of the week, another for months of the year, and so on, and
which I use depends on whether the user wants to select days of the
week, months of the year, etc), it makes perfect sense to want to know
if a specific enum value is in the list, and the obvious way to check
it is with "my_value in enum_list". That won't work if you raise an
exception - it takes a relatively convoluted bit of code to make this
test.
What's being discussed here is what happens when comparing the *values*
from the enumeration.

That's what I thought I was discussing, but apparently I wasn't clear
enough. Let me try again.

I think it's perfectly reasonable to store enum values from different
enums in a list, and check for a specific value being in that list. If
comparing two enum values can raise an exception, then doinng this
become problematic, as you may get an exception. According to what you
say below, this isn't true for any builtin type or any type in the
standard library.

Quote:
Python generally uses '==' to mean "is the same value". To do that,
a simple true/false return is enough. In raising an exception,
you're making '==' carry an extra meaning (I'm not sure *what* that
is, though).
The problem with "is the same value" as an explanation for '==' is
that it doesn't help in cases such as::
ShirtSize = Enum('small', 'medium', 'large')
AppleSize = Enum('small', 'large')

Actually, it provides a very explicit guideline for these cases. The
guidelines is by no means obvious, as witness languages like LISP,
which have multiple equality operators.

Quote:
What should be the result of this comparison::
ShirtSize.small == AppleSize.small
Are they "the same value"? They're both "small" (and they both coerce
to the same string value, and in this case the same integer value).

That depends on the semantics you want to place on the values of
enums. Reasonable arguments can be made for anything from "they're
exactly like small integers" to "the values are an implementation
detail, and you shouldn't worry about them." That they coerce to the
same string is irreleevant, at least in python, which doesn't coerce
strings to

Quote:
Do any python builtins behave that way? How about anything in the
python standard library?
No to both; I believe this may be a defining property of
enumerations. Am I wrong?

There are enum implementations that don't treat comparing enum values
from different enums as an error, so I'd say you're wrong. In Python's
case, comparing two objects for identity never raises an exception for
any type that comes with the language, so I'd say that that was a
defining property of python.

<mike
--
Mike Meyer <mwm@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Back to top
Skip Montanaro
*nix forums Guru


Joined: 28 Feb 2005
Posts: 403

PostPosted: Fri Dec 16, 2005 3:37 pm    Post subject: Re: Enumeration idioms: Values from different enumerations Reply with quote

Quote:
ShirtSize = Enum('small', 'medium', 'large')
AppleSize = Enum('small', 'large')

Ben> What should be the result of this comparison::

Quote:
ShirtSize.small == AppleSize.small

False. They are values from different objects. Just make __eq__ map to
"is". I think you'll be fine.

Ben> Or is it an error to even try comparing them?

As someone else pointed out containment tests become difficult with your
current formulation.

Quote:
Do any python builtins behave that way? How about anything in the
python standard library?

Ben> No to both; I believe this may be a defining property of
Ben> enumerations. Am I wrong?

I think so. <0.5 wink>. I think you should be able to compare any two
objects. I think the complex types give you a little wiggle room on the
size comparisons (<, <=, >, >=), but I think == and != really ought to work.

Skip
Back to top
Google

Back to top
Display posts from previous:   
Post new topic   Reply to topic Page 1 of 2 [28 Posts] Goto page:  1, 2 Next
View previous topic :: View next topic
The time now is Tue Jan 06, 2009 7:21 pm | All times are GMT
navigation Forum index » Programming » python
Jump to:  

Similar Topics
Topic Author Forum Replies Last Post
No new posts does the default constructor initialize values? NewToCPP C++ 12 Thu Jul 20, 2006 3:37 pm
No new posts converting array values to monomaniac21 PHP 11 Thu Jul 20, 2006 10:17 am
No new posts Must GET/POST Parameters Have Values? (And What is the Sy... David T. Ashley PHP 2 Wed Jul 19, 2006 1:10 am
No new posts number of distinct values in tsearch2 gist index Kevin Murphy PostgreSQL 0 Tue Jul 18, 2006 5:24 pm
No new posts How to pass array of values to a pgplsql function Curtis Scheer PostgreSQL 3 Tue Jul 18, 2006 4:27 pm

Credit Counseling | Learn real Kung Fu | Loan | Credit Cards | Loans
Copyright © 2004-2005 DeniX Solutions SRL
 
Other DeniX Solutions sites: Unix/Linux blog |  electronics forum |  medicine forum |  science forum | 
Privacy Policy


Powered by phpBB © 2001, 2005 phpBB Group
[ Time: 0.4979s ][ Queries: 16 (0.2899s) ][ GZIP on - Debug on ]