[Numpy-discussion] why a[0][0].__mul__(a[0][0]) where a is np.array, gives 'missing 1 required positional argument'?

Sebastian Berg sebastian at sipsolutions.net
Tue Jun 27 13:36:45 EDT 2017


On Tue, 2017-06-27 at 04:54 -0500, Larry Evans wrote:
> The following code:
> 
> --{--cut here--
> #Purpose:
> #  Demonstrate class with __add__ and __mult__ methods
> #  to demonstrate shortestPath calculations.
> #OriginalSource:
> #  ./shortestPath.py
> #References:
> #  [1] 
> http://www.marinamele.com/2014/04/modifying-add-method-of-python-clas
> s.html
> #  [2] 
> https://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures
> .html#c.PyArray_Descr
> #  [3] 
> https://www.abebooks.com/book-search/title/graphs-networks/author/car
> re-bernard/
> #      Table 3.1, path algebra P2.
> #  [4] https://docs.python.org/3/library/abc.html
> ###########################################
> import numpy as np
> from abc import ABCMeta, abstractmethod
> class PathAbstract(metaclass=ABCMeta):
>      @abstractmethod
>      def __repr__(self):
>          pass
>      @abstractmethod
>      def __add__(self, other):
>          pass
>      @abstractmethod
>      def __radd__(self, other):
>          pass
>      @abstractmethod
>      def __mul__(self, other):
>          pass
>      @abstractmethod
>      def __rmul__(self, other):
>          pass
> 
> class ShortestNull(PathAbstract):
>      '''Null object in ShortestPath algebra[3]'''
>      def __str__(self):
>          return "<0>"
>      def __repr__(self):
>          return self.__str__()
>      def __addreal__(self, other):
>          return other
>      def __add__(self, other):
>          return other
>      def __radd__(self, other):
>          return other
>      def __mulreal__(self, other):
>          return self
>      def __mul__(self, other):
>          return self
>      def __rmul__(self, other):
>          return self
> 
> class ShortestUnit(PathAbstract):
>      '''Unit object in ShortestPath algebra[3]'''
>      def __str__(self):
>          return "<1>"
>      def __repr__(self):
>          return self.__str__()
>      def __addreal__(self, other):
>          return self
>      def __add__(self, other):
>          return self
>      def __radd__(self, other):
>          return self
>      def __mulreal__(self, other):
>          return other
>      def __mul__(self, other):
>          return other
>      def __rmul__(self, other):
>          return other
> 
> class ShortestPath(PathAbstract):
>      def __init__(self, distance):
>          self.distance = distance
>      def __str__(self):
>          return "{0:4.1f}".format(self.distance)
>      def __repr__(self):
>          return self.__str__()
>      def __addreal__(self, other):
>          #paths composed of following shortest of self path or other
> path.
>          min_dist=min(self.distance,other.distance)
>          return ShortestPath(min_dist)
>      def __add__(self, other):
>          #paths composed of following shortest of self path or other
> path.
>          if(other == 0):
>              n=ShortestNull()
>              return n.__addreal__(self)
>          else:
>              return other.__addreal__(self)
>      def __radd__(self, other):
>          return self.__add__(other)
>      def __mulreal__(self, other):
>          #path composed of self path followed by other path.
>          min_dist=self.distance+other.distance
>          return ShortestPath(min_dist)
>      def __mul__(self, other):
>          return other.__mulreal__(self)
>      def __rmul__(self, other):
>          return other.__mulreal__(self)
> 
> 
> d0=ShortestNull()
> d1=ShortestUnit()
> d2=ShortestPath(3)
> d3=ShortestPath(6)
> print(' d0=',d0,' d1=',d1,' d2=',d2,' d3=',d3)
> print(' type(d0)=',type(d0).__name__)
> d4=d0+d2+d3
> print('d4=',d4)
> d5=d2*d3
> print('d5=',d5)
> d6=d0*d2
> print('d6=',d6)
> d7=d1*d2
> print('d7=',d7)
> d8=d2*d0
> print('d8=',d8)
> d9=d2*d1
> print('d9=',d9)
> a=np.array([[ShortestNull,ShortestPath(12)],[ShortestPath(12),Shortes
> tNull()]],dtype=object)
> print('a=',a,sep='\n')
> print('a[0]=',a[0],sep='\n')
> print('a[0][0]=',a[0][0],sep='\n')
> #a00mul=a[0][0]*a[0][0]
> a00mul=a[0][0].__mul__(a[0][0])
> print('a00mul=',a00mul,sep='\n')
> #at=a.transpose()
> #print('at=',at,sep='\n')
> #aat=a.dot(at)
> print('aat=',aat,sep='\n')
> #mp=np.matmul(a,at)#this gives error about Object arrays not
> supported.
> #print('mp=',mp)
> --}--cut here--
> 
> 
> When run by make, gives this result:
> 
> 
> --{--cut here--
> make -k
> python3 shortestPathABC.py
>   d0= <0>  d1= <1>  d2=  3.0  d3=  6.0
>   type(d0)= ShortestNull
> d4=  3.0
> d5=  9.0
> d6= <0>
> d7=  3.0
> d8= <0>
> d9=  3.0
> a=
> [[<class '__main__.ShortestNull'> 12.0]
>   [12.0 <0>]]
> a[0]=
> [<class '__main__.ShortestNull'> 12.0]
> a[0][0]=
> <class '__main__.ShortestNull'>
> Traceback (most recent call last):
>    File "shortestPathABC.py", line 123, in <module>
>      a00mul=a[0][0].__mul__(a[0][0])
> TypeError: __mul__() missing 1 required positional argument: 'other'
> Makefile:7: recipe for target 'all' failed
> make: *** [all] Error 1
> --}--cut here--
> 
> I don't understand why.  Apparently, a[0][0] is not a ShortestNull 
> because otherwise, the .__mul__ would have the positional argument,
> 'other' equal to a[0][0].
> 


I don't think debugging support really suits the list, but.... how
about you see why in your result:
[[<class '__main__.ShortestNull'> 12.0]
  [12.0 <0>]]

a[0, 0] and a[1, 1] do not show up as the same thing?


- Sebastian


> What am I missing?
> 
> TIA.
> 
> -regards,
> Larry
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at python.org
> https://mail.python.org/mailman/listinfo/numpy-discussion
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: This is a digitally signed message part
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20170627/25629e10/attachment.sig>


More information about the NumPy-Discussion mailing list