[Python-3000] Wither PEP 335 (Overloadable Boolean Operators)?

Giovanni Bajo rasky at develer.com
Sat May 19 21:21:58 CEST 2007


On 19/05/2007 19.12, Neil Toronto wrote:

> There's a fairly common one, actually, that comes up quite a lot in 
> Numpy. Currently, best practice is a wart. Here's some code of mine for 
> evaluating log probabilities from the Multinomial family:
> 
>     class Multinomial(DistFamily):
>         @classmethod
>         def logProb(cls, x, n, p):
>             x = scipy.asarray(x)
>             n = scipy.asarray(n)
>             p = scipy.asarray(p)
>             result = special.gammaln(n + 1) - special.gammaln(x + 
> 1).sum(-1) + (x * scipy.log(p)).sum(-1)
>             xsum = x.sum(-1)
>             psum = p.sum(-1)
>             return scipy.where((xsum != n) | (psum < 0.99999) | (psum > 
> 1.00001) | ~scipy.isfinite(result), -scipy.inf, result)
> 
> 
> That last bit is really confusing to new Numpy users, especially 
> figuring out how to do it in the first place. (Once you get it, it's not 
> *so* bad.) The parenthesis are required, by the way. With overloadable 
> booleans, it would become much more readable and newbie-friendly:
> 
>             return scipy.where(xsum != n or psum < 0.99999 or psum > 
> 1.00001 or not scipy.isfinite(result), -scipy.inf, result)

Probably it's better in the numpy contest, but surely it's a little confusing 
at first sight for a non-numpy savvy. In fact, as you said, I don't think the 
current best-practice is *that* bad after all. I'll keep my -0.

========================

Now for the fun side :)

Another workaround could be:

return scipy.where(
     "xsum != n or psum < 0.99999 or "
     "psum > 1.000001 or not scipy.isfinite(result)",
     -scipy.inf, result)

with the necessary magic to pull out variables from the stack frame. Parsing 
could be done only once of course. But I'm sure the numpy guys have already 
thought and discarded this solution as it's more complicated.

[[ In fact, numpy is actually trying to create a DSL with Python itself. I 
assume things like "x.sum(-1)" would have been probably spelled sum(x, -1), if 
  you could freely decide what to do without worrying about the implementation. ]]

Or, another workaround is something like this: 
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/384122, which could 
probably be extended to more "operators" that numpy can't simulate using the 
plain Python syntax.
-- 
Giovanni Bajo



More information about the Python-3000 mailing list