# [Numpy-discussion] numpy migration

Duncan Smith buzzard@contactbox.co...
Tue Apr 24 20:26:57 CDT 2007

```
Timothy Hochberg wrote:
> On 4/23/07, Duncan Smith <buzzard@urubu.freeserve.co.uk> wrote:
>
>>
>> Hello,
>>      Since moving to numpy I've had a few problems with my existing
>> code.  It basically revolves around the numpy scalar types. e.g.
>>
>> ------------------------------------------------
>>
>> >>> import Numeric as N
>> >>> a = N.array([[0,1],[2,3]])
>> >>> a
>>
>> array([[0, 1],
>>        [2, 3]])
>>
>> >>> i = a[0,0]
>> >>> 1/i
>>
>>
>> Traceback (most recent call last):
>>   File "<pyshell#30>", line 1, in -toplevel-
>>     1/i
>> ZeroDivisionError: integer division or modulo by zero
>>
>> >>> b = a * 1.5
>> >>> b
>>
>> array([[ 0. ,  1.5],
>>        [ 3. ,  4.5]])
>>
>> >>> N.floor(b)
>>
>> array([[ 0.,  1.],
>>        [ 3.,  4.]])
>>
>> >>> ================================ RESTART
>>
>> ================================
>>
>> >>> import numpy as N
>> >>> a = N.array([[0,1],[2,3]])
>> >>> a
>>
>> array([[0, 1],
>>        [2, 3]])
>>
>> >>> i = a[0,0]
>> >>> 1/i
>>
>> 0
>
>
>
> You should be getting a warning here. Did one disappear in the cut and
> paste? Or are you using a nonstandard shell that eats warnings? Or an old
> version of numpy?
>

Python 2.5.1 / numpy 1.0.1 / IDLE (under Windows 2000).  No warning.

> In any event if you want an error rather than a warning for zero division,
> use:
>
>>>> 1/i
>
> Warning: divide by zero encountered in long_scalars
> 0
> SyntaxError: invalid syntax
>
>>>> N.seterr(divide='raise')
>
> {'over': 'print', 'divide': 'print', 'invalid': 'print', 'under': 'ignore'}
>
>>>> 1/i
>
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
> FloatingPointError: divide by zero encountered in long_scalars
>
> Although I'm not sure why that's a floating point error.
>

True, bug or feature?, I'm really looking for a ZeroDivisionError.

[snip]

> ----------------------------------------------
>
>>
>> An additional problem involves classes that have e.g. __rmul__ methods
>> defined and are sufficiently similar to numpy arrays that my classes'
>> __rmul__ methods are not invoked when using numpy scalars.
>
>
>
>
> Try adding "__array_priority__ = 10" or somesuch to your classes. This
> should tell numpy to back off and let your methods go first when doing
> mixed
> operations. Searching for "__array_priority__" will probably turn up some
> examples.
>

Yes, it did.  But for my classes it seems to have no effect.  Below is a
fairly minimal example.

-----------------example.py--------------------

from __future__ import division

import numpy

class MyClass(object):

def __init__(self, arr, labels):
self.arr = arr
self.labels = labels

def __repr__(self):
return numpy.array2string(self.arr, separator=', ') +
repr(self.labels)

def __len__(self):
return len(self.labels)

def __getitem__(self, key):
return self.arr[key]

def __setitem__(self, key, item):
self.arr[key] = item

def __mul__(self, other):
return self.__class__(self.arr * other, self.labels)

__rmul__ = __mul__

----------------------------------------------------

>>> import example
>>> import numpy as N
>>> ex = example.MyClass(N.array([[6,7],[8,9]]), ['axis0', 'axis1'])
>>> i = ex.arr[0,0]
>>> ex
[[6, 7],
[8, 9]]['axis0', 'axis1']
>>> ex * i
[[36, 42],
[48, 54]]['axis0', 'axis1']
>>> i * ex
array([[36, 42],
[48, 54]])
>>>

It seems that it requires having __len__, __setitem__ and __getitem__
defined to get the undesired behaviour.

[snip]

>
> I think you should be able to do everything you need, by using seterr at
> startup to make numpy picky about division errors and then using array
> priority to make your methods have precedence over numpy's.
>

Thanks Tim.  Unfortunately I really need it to raise a
ZeroDivisionError.  Homing in on the second issue, but I'm not sure I
can easily do away with the __len__ method (and I definitely need the
others).  Cheers.

Duncan
```