Andrew Cooke | Contents | Latest | RSS | Previous | Next

C[omp]ute

Welcome to my blog, which was once a mailing list of the same name and is still generated by mail. Please reply via the "comment" links.

Always interested in offers/projects/new ideas. Eclectic experience in fields like: numerical computing; Python web; Java enterprise; functional languages; GPGPU; SQL databases; etc. Based in Santiago, Chile; telecommute worldwide. CV; email.

Personal Projects

Choochoo Training Diary

Last 100 entries

Surprise Paradox; [Books] Good Author List; [Computing] Efficient queries with grouping in Postgres; [Computing] Automatic Wake (Linux); [Computing] AWS CDK Aspects in Go; [Bike] Adidas Gravel Shoes; [Computing, Horror] Biological Chips; [Books] Weird Lit Recs; [Covid] Extended SIR Models; [Art] York-based Printmaker; [Physics] Quantum Transitions are not Instantaneous; [Computing] AI and Drum Machines; [Computing] Probabilities, Stopping Times, Martingales; bpftrace Intro Article; [Computing] Starlab Systems - Linux Laptops; [Computing] Extended Berkeley Packet Filter; [Green] Mainspring Linear Generator; Better Approach; Rummikub Solver; Chilean Poetry; Felicitations - Empowerment Grant; [Bike] Fixing Spyre Brakes (That Need Constant Adjustment); [Computing, Music] Raspberry Pi Media (Audio) Streamer; [Computing] Amazing Hack To Embed DSL In Python; [Bike] Ruta Del Condor (El Alfalfal); [Bike] Estimating Power On Climbs; [Computing] Applying Azure B2C Authentication To Function Apps; [Bike] Gearing On The Back Of An Envelope; [Computing] Okular and Postscript in OpenSuse; There's a fix!; [Computing] Fail2Ban on OpenSuse Leap 15.3 (NFTables); [Cycling, Computing] Power Calculation and Brakes; [Hardware, Computing] Amazing Pockit Computer; Bullying; How I Am - 3 Years Post Accident, 8+ Years With MS; [USA Politics] In America's Uncivil War Republicans Are The Aggressors; [Programming] Selenium and Python; Better Walking Data; [Bike] How Fast Before Walking More Efficient Than Cycling?; [COVID] Coronavirus And Cycling; [Programming] Docker on OpenSuse; Cadence v Speed; [Bike] Gearing For Real Cyclists; [Programming] React plotting - visx; [Programming] React Leaflet; AliExpress Independent Sellers; Applebaum - Twilight of Democracy; [Politics] Back + US Elections; [Programming,Exercise] Simple Timer Script; [News] 2019: The year revolt went global; [Politics] The world's most-surveilled cities; [Bike] Hope Freehub; [Restaurant] Mama Chau's (Chinese, Providencia); [Politics] Brexit Podcast; [Diary] Pneumonia; [Politics] Britain's Reichstag Fire moment; install cairo; [Programming] GCC Sanitizer Flags; [GPU, Programming] Per-Thread Program Counters; My Bike Accident - Looking Back One Year; [Python] Geographic heights are incredibly easy!; [Cooking] Cookie Recipe; Efficient, Simple, Directed Maximisation of Noisy Function; And for argparse; Bash Completion in Python; [Computing] Configuring Github Jekyll Locally; [Maths, Link] The Napkin Project; You can Masquerade in Firewalld; [Bike] Servicing Budget (Spring) Forks; [Crypto] CIA Internet Comms Failure; [Python] Cute Rate Limiting API; [Causality] Judea Pearl Lecture; [Security, Computing] Chinese Hardware Hack Of Supermicro Boards; SQLAlchemy Joined Table Inheritance and Delete Cascade; [Translation] The Club; [Computing] Super Potato Bruh; [Computing] Extending Jupyter; Further HRM Details; [Computing, Bike] Activities in ch2; [Books, Link] Modern Japanese Lit; What ended up there; [Link, Book] Logic Book; Update - Garmin Express / Connect; Garmin Forerunner 35 v 230; [Link, Politics, Internet] Government Trolls; [Link, Politics] Why identity politics benefits the right more than the left; SSH Forwarding; A Specification For Repeating Events; A Fight for the Soul of Science; [Science, Book, Link] Lost In Math; OpenSuse Leap 15 Network Fixes; Update; [Book] Galileo's Middle Finger; [Bike] Chinese Carbon Rims; [Bike] Servicing Shimano XT Front Hub HB-M8010; [Bike] Aliexpress Cycling Tops; [Computing] Change to ssh handling of multiple identities?; [Bike] Endura Hummvee Lite II; [Computing] Marble Based Logic; [Link, Politics] Sanity Check For Nuclear Launch; [Link, Science] Entropy and Life

© 2006-2017 Andrew Cooke (site) / post authors (content).

Python's sad, unimaginative Enum

From: andrew cooke <andrew@...>

Date: Sat, 11 May 2013 11:03:33 -0400

Python is about to get an Enum.  See http://www.python.org/dev/peps/pep-0435/

And it's sad.

It's not awful.  It just fails to do anything particularly well - it's an
awkward compromise whose only real achievement is not doing anything new.

What would you expect a Pythonic enum to look like?

  class Colour(Enum):
      red
      green

  > print(Colour.red == Colour.green)
  false

That's about the minimum, right?  But it doesn't do that.  The above would
require new syntax, so instead you have to define values:

  class Colour(Enum):
      red = 1
      green = 1

Still, at least the mistake above would raise an error.  Wouldn't it?  Nope.
That's a feature.  If you mess up on the non-optional values then you get
"aliases".  Because that's something I've waited all my life for, while I
never make mistakes...  Or something.  The something being that they are
smoking fucking crack.

But you could just as well type:

  class Colour:
      red = 1
      green = 2

so what does Enum get you?  It provides a bit of metaclass goop to let you
iterate over values, etc.  Whoop.

So, you go hunting around in the docs to see if there's any way at all of
avoiding the need to assign values manually.  And there is:

  Colour = Enum('Colour', 'red, green')

which suffers from the same problems as namedtuples:
  - you need to repeat the class name (in a string, which your IDE is
    unlikely to check)
  - the parameters are themselves in a string, which your IDE is 
    unlikely to parse and provide in auto-complete (they can be separate
    strings, in a sequence, but that doesn't really help).

Now if two potentially useful library classes are suffering from the same
problems than isn't that a BIT OF A HINT to try make things better?  Nope.  It
just shows how important it is to not be imaginative.  Or something (crack).

And it gets worse.  What values do you think the above provides?

Strings?  That would makes sense (red = 'red'), in that it would display
nicely and is going to provide easy to debug values.  So nope.

Integers from zero?  I mean that's how Python counts indices and there's "only
one way to do it" so that's how Python counts enums, right?  Nope.

OK, so bit fields?  That way we can do cool Colour.red | Colour.green and
make the C programmers feel at home?  Nope.

Give up?  I'll tell you.  It counts from 1.  Presumably because it's really
common to use the "if not enum" idiom.  In someone's crack-addled dreams.


Like I said at the start.  None of this is really awful.  It's just lame.
It's design by committee that finds the least offensive, least imaginative,
least useful solution.

One big pile of meh.

Andrew

Enum

From: Peter Norvig <pnorvig@...>

Date: Sat, 11 May 2013 11:37:40 -0700

If you don't like writing "red = 1; green = 2" etc you can just do

Colour = Enum('Colour', 'red green blue ...')

this is fucking useless

From: Bryce <bryce.culhane@...>

Date: Sat, 11 May 2013 14:55:56 -0700

whatever happened to 'There should be one-- and preferably only one
--obvious way to do it.'

Re: Enum

From: andrew cooke <andrew@...>

Date: Sat, 11 May 2013 15:12:27 -0400

I can't believe who I am saying this to... but dude, read the article before
you comment.

Andrew

What would be imaginative?

From: andrew cooke <andrew@...>

Date: Sat, 11 May 2013 15:33:53 -0400

Maybe Python needs to start considering something like atoms?  That would
address the need to hde names in strings and might also provide a more
suitable value type for enums.

Is there some (new?) syntax that could give a named scope, to avoid the need
to repeat class names?

It seems like there are underlying language issues that need a more
imaginative solution...

Andrew

I agree with you #nt

From: Luigi Monaco <monaco@...>

Date: Sat, 11 May 2013 22:03:37 +0200

no text

Frustration Understood

From: Ethan Furman <ethan@...>

Date: Sun, 12 May 2013 05:03:32 -0700

I certainly understand your frustrations, and I share some of them, but I feel your characterization is a bit unfair. 
(Disclaimer, I'm the author of the Enum code.)

The driving goal was to make something useful, that would meet 90%+ of the use cases out there, while allowing for 
fairly easy subclassing so the special cases could be (relatively) easily handled.

For example, the auto numbering Enum (which I like to have myself) with easy cast to int is:

     class AutoNumber(Enum):
         def __new__(cls):
             value = len(cls.__members__) + 1
             obj = object.__new__(cls)
             obj._value = value
             return obj
         def __int__(self):
             return self._value

     class Color(AutoNumber):
         red = ()
         green = ()
         blue = ()

And if you don't want it to start at one (again, something I tend to agree with, although I also understand Barry's 
feeling that enums are something rather than nothing) just take out the + 1 on the value line.

Some good feedback here

From: Nick Coghlan <ncoghlan@...>

Date: Sun, 12 May 2013 21:18:45 +1000

I believe your concerns about aliasing and the values assigned by the
functional API are well founded, so I've taken the liberty of turning
those into proposals on the issue tracker as aspects we should revisit
once the basic enum implementation is in place.

Regarding the lack of magic in the definition syntax, that's driven
largely by the way we plan to use them in the standard library. I've
written more about the design in general at
http://python-notes.boredomandlaziness.org/en/latest/python3/enum_creation.html

Cheers,
Nick.

--
Nick Coghlan   |   ncoghlan@...   |   Brisbane, Australia

Atoms in python

From: Jonathan Hunt <j@...>

Date: Mon, 13 May 2013 00:34:26 -0700

I'm not so pessimitic about enums in python, but I think atoms are an
interesting idea.

You can do something easily just by wrapping a string.
http://www.me.net.nz/blog/atoms-slash-symbols-in-python/

About "Python's sad, unimaginative Enum"

From: "Yves Daoust" <yves.daoust@...>

Date: Mon, 13 May 2013 09:05:50 +0200

I don't want to be as harsh as Andrew, but I don't love the declaration
syntax of these Enums either.

 

Explicit numbering is tedious an error prone, so auto-numbering is an
absolute must.

 

(In my understanding, the true purpose of enums is to define symbolic
values, whatever their internal representation; practical needs have called
for the support for bit-field masks, hardware-defined constants or
enforcement of other "hard-coded" values, which should remain the
exception.)

 

I find the syntax for auto-numbering too heavy: one equal sign, two
parenthesis and a newline per item at too much to my taste (at least four
keystrokes, of which two are shifted). A single coma would be far enough
(the unimaginative way J).

 

By the way, some notation for compact representation of bit-field masks
could be welcome, like Mask= :5 and Mask = :5:7, instead of obscure
0x00000020, 0x000000E0 or similar.

 

Regards,

 

                Yves Daoust

Re: Python's sad, unimaginative Enum

From: Duncan Booth <kupuguy@...>

Date: Fri, 17 May 2013 15:19:04 +0100

While most of what you wrote is subjective, you are wrong on one factual point:

> What would you expect a Pythonic enum to look like?
>
>   class Colour(Enum):
>       red
>       green
>
>   > print(Colour.red == Colour.green)
>   false

> That's about the minimum, right?  But it doesn't do that.  The above would
> require new syntax

No, that is syntactically valid, and it is even easy to implement
something that behaves in the way you expect, however the PEP authors
chose not to go that way (probably for very good reasons):

>>> import collections, itertools
>>> class AutoEnum(type):
    @classmethod
    def __prepare__(metacls, name, bases):
        return collections.defaultdict(itertools.count().__next__)
    def __new__(cls, name, bases, classdict):
        result = type.__new__(cls, name, bases, dict(classdict))
        return result

>>> class Enum(metaclass=AutoEnum): pass

>>> class MyClass(Enum):
    a
    b

>>> MyClass.a
1
>>> MyClass.b
2

An alternative.

From: Francisco Mota <fmota91@...>

Date: Sun, 23 Jun 2013 22:08:36 +0100

If you want to work with the standard Enum and still have automatic
counting, the easiest (IMO) way is to declare an Enum as follows:

import itertools
_count = itertools.count()

class Color(Enum):
    red     = _count.next()
    green   = _count.next()
    blue    = _count.next()
    fuchsia = _count.next()
    ...

Python 2 and 3 compatible alternative.

From: John Hagen <hagen_06@...>

Date: Wed, 10 Jun 2015 22:02:44 -0400

Francisco Mota's answer does not work on Python 3.  .next() is no longer de=
fined on itertools.count()
For a version that works on both Python 2 (presuming you have installed enu=
m34) and Python 3:
import enumimport itertools_enum_value =3D itertools.count(1)

class Color(enum.Enum):    red =3D next(_enum_value)    green =3D next(_enu=
m_value)    blue =3D next(_enum_value)    fuchsia =3D next(_enum_value) 		 =
	   		  =

autoenum on PyPI

From: John Hagen <hagen_06@...>

Date: Sun, 10 Apr 2016 20:27:55 +0000

Another alternative is to use autoenum from PyPI: https://pypi.python.org/p=
ypi/autoenum/1.0.1

What ended up there

From: "Angerer, Philipp" <Philipp.Angerer@...-soft.com>

Date: Fri, 17 Aug 2018 10:25:14 +0000

SXTigJlzIGFjdHVhbGx5IG5vdCBiYWQgYXQgYWxsLiBKdXN0IHVzZSBhdXRvKCk6DQoNCmZyb20g
ZW51bSBpbXBvcnQgRW51bSwgYXV0bw0KDQpjbGFzcyBNeUVudW0oRW51bSk6DQogICAgYSA9IGF1
dG8oKQ0KICAgIGIgPSBhdXRvKCkNCg0KYXNzZXJ0IE15RW51bS5hIGlzIG5vdCBNeUVudW0uYg0K
DQpBbmQgcGVvcGxlIGNvbXBhcmUgZW51bSBlbnRyaWVzIHdpdGgg4oCcaXPigJ0sIGp1c3QgbGlr
ZSB0aGUgb25lIHRydWUgd2F5IGlzIOKAnGlmIGZvbyBpcyBOb25l4oCdIGluc3RlYWQgb2Yg4oCc
aWYgZm9vID09IE5vbmXigJ0uDQo=

Comment on this post