-1

This is a recurrent topic, about function that are not iterable because python3 TypeError: 'function' object is not iterable

I do not know when I execute the code, it says

w,c= PRank.Prank(c,w,X[i,:],Y[i])

TypeError: 'NoneType' object is not iterable: Here is the code.

    import numpy as np


class PRank:



  def predict(X,w,c):
    rank = min(np.where(np.dot(X,w)-c<0)[0])
    return(rank)

  def Prank (c,w,x_t,y):

    l_t=np.zeros(len(c)-1)
    a_t=np.zeros(len(c)-1)
    y_t =min(np.where((np.dot(w,x_t)-c) < 0)[0]) 

    if y_t != y:
        for r in range(len(c)-1):
            if (y <= r): 
                    l_t[r] = -1
            else:
                    l_t[r] = 1
        for r in range(len(c)-1):
            if (((np.dot(w,x_t)-c[r])*l_t[r]) <= 0):
                a_t[r] = l_t[r]
            else:
                a_t[r] = 0


            w = w + sum(a_t)*x_t
            c_ = np.delete(c,len(c)-1)
            c_ = c_ - a_t
            c = np.append(c_,np.inf)


        else:
            w = w
            c = c

   def modelPRank(X,Y,maxrank=5,epsilon=0.02):

      N=np.shape(X)[0]
      feat=np.shape(X)[1]
      c=np.sort(np.random.uniform(size=(maxrank+1,1)),axis=0)
      c[0]=-np.inf
      c[-1]=np.inf
      w=np.zeros(feat)
      ypred=np.zeros(N)
      MSE=1
      j=0
      while MSE > epsilon:
            for i in range(np.shape(X)[0]):
                   w,c= PRank.Prank(c,w,X[i,:],Y[i])
            for i in range(np.shape(X)[0]):
               ypred[i]=min(np.where(np. dot(X[i,:],w)-c<0)[0])
            MSE=np.nanmean((ypred-Y)**2)
            print(MSE)
            j=j+1
      return[MSE,w,ypred,c]    
X=np.random.uniform(1,5,(5000,2))    

Wini=[0.35,0.65]
Y=np.round(np.dot(X,Wini))
PRank.modelPRank(X,Y)

If I do not use class, then the code works well. I do not know why it says that Prank is not iterable and how I can I fix it.

1 Answers1

2

You are telling Python to unpack the return value of the .Prank(...) call into two variables, w and c:

w,c= PRank.Prank(c,w,X[i,:],Y[i])

For Python to do that, whatever is produced on the right-hand side must be an iterable (like a list or a tuple or a string), and each element from that iterable is then used to assign values to your two names.

Your function call returns None, which is not an iterable; it can't be used to assign separate values to two different names.

Add a return statement at the end of the function to return two values in a tuple:

return w, c

This has nothing to do with using classes. You are not using your class correctly, you didn't create an instance, for example. All you did was move a function into a class object.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343