Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
201 views
in Technique[技术] by (71.8m points)

python - AttributeError 'class name' object has no attribute 'method'

import numpy as np
import math

class CellLinked ():

    def __init__ (self, box_len: float, r_cut: float) :
        """
        This class initialize with simulation box (L*L*L).
        Here, L=box_len and r_cut is a cut-off radius.
        no_cells is number of cell per axis
        """
        self.box_len = box_len
        self.r_cut = r_cut
        self.no_cells = math.floor (self.box_len/self.r_cut)

    def __call__ (self, postate: np.ndarray) :

        """ 
            Compute the head and list array using simulation box length, cut-off radius, and the position state.

            Parameters:
                postate (np.ndarray):       position of particles

            Returns
                head_arr (list):   head array in the linked list (head_arr.shape==number of cells)
                list_arr (list):   list array in the linked list (list_arr.shape==number of particles)
        """

        # Initialize a Head array with -1, size = the total number of cells
        head_arr = [-1] * self.no_cells*self.no_cells*self.no_cells

        # Initialize a list array with -1, size = the total number of particles
        list_arr = [-1] * postate.shape[0]

        for i in range (0, postate.shape[0]) :

            # calculate cell index of each particles based on the particle position
            index = self._cellindex (postate[i,:])

            # calculate list array
            list_arr [i] = head_arr [index]

            # calculate head array         
            head_arr [index] = i

        return head_arr, list_arr


            


    def _cellindex (self, postate) :

        """ Calculate the cell index based on the i, j, and k index
        """
        i = math.floor (postate[0]/self.r_cut)
        j = math.floor (postate[1]/self.r_cut)
        k = math.floor (postate[2]/self.r_cut)
        return int (k+j*self.no_cells+i*self.no_cells*self.no_cells)

    def _find_neighbor_index (self, cellind) :

        """
        calculate neighbor cell index based on the cell index
        """
        #  calculate i, j, and k index based on the cell index

        i_counter = math.floor (cellind/self.no_cells**2)
        j_counter = math.floor ((cellind - i_counter*self.no_cells**2)/self.no_cells)
        k_counter = math.floor (cellind - j_counter*self.no_cells - i_counter*self.no_cells**2)
      

        # calculate neighbor cell index for each cell index
        index = [-1,0,1]
        neighbor_cell_inx = []
        for ii in index :
            for jj in index :
                for kk in index :
                    if 0 <= ii + i_counter < self.no_cells and 0 <= jj + j_counter < self.no_cells and 0 <= kk + k_counter < self.no_cells :
                        new_index = (kk + k_counter) + (jj + j_counter) *self.no_cells + (ii + i_counter) *self.no_cells*self.no_cells
                        neighbor_cell_inx.append(new_index)
        return neighbor_cell_inx

    def _find_neighbor_cells (self, head_arr) :

        """
        calculate neighbor cells based on head array
        """

        neighbor_cells = []
        for j in range (0, len (head_arr)) :           
            neighbor_cell_inx = self._find_neighbor_index (j)           
            neighbor_cells.append(neighbor_cell_inx)

        return neighbor_cells
    
    def _find_particles_inside_neighbor_cells (self, list_arr, head_arr, neighbor_cells) :
    
        """
        find particles in each cell and neighbor cells are identified
        """
        new_head_arr =[]
        for i in neighbor_cells :
            new_head_arr.append (head_arr[i])
        temporary_state = np.zeros((1,3))

        for ii in new_head_arr:
            if ii > -1 :
                cell_state = np.zeros((1,3))
                cell_state = np.concatenate((cell_state, np.array ([postate[ii]])))
                while  list_arr[ii] != -1 :
                    cell_state = np.concatenate((cell_state, np.array ([postate[list_arr[ii]]])))
                    ii = list_arr[ii]

                cell_state = np.flip(cell_state[1:, :], 0)
                temporary_state = np.concatenate((temporary_state, cell_state))
        
        temporary_state = temporary_state[1:, :]
        return temporary_state




if __name__=="__main__":

    box_len=3
    r_cut= 1
    postate = box_len * np.random.random_sample((50, 3))
    model = CellLinked (box_len,  r_cut)
    head_arr, list_arr = model (postate)
    neighbor_cells = model._find_neighbor_cells(head_arr)
    neighbor_cells = neighbor_cells[13]
    temporary_state = model._find_particles_inside_neighbor_cells (list_arr, head_arr, neighbor_cells)

    mask = np.isin(postate, temporary_state)
    assert np.all(mask == True) == True, 'particles in neighbor cells has been indetified wrongly'

    print ("the head array is : 
 ", head_arr)
    print ("list array is : 
 ", list_arr)
 

Hi Guys, I have a silly problem when calling the "_find_particles_inside_neighbor_cells" by creating an object from this class. when I run this code here by using "if name=="main":", code run successfully. but when I want to import this class in another file in a python file like this :

import numpy as np
from cell_linked_list import CellLinked

box_len=3
r_cut= 1
postate = box_len * np.random.random_sample((50, 3))
model = CellLinked (box_len,  r_cut)
head_arr, list_arr = model (postate)
neighbor_cells = model._find_neighbor_cells(head_arr)
neighbor_cells = neighbor_cells[13]
temporary_state = model._find_particles_inside_neighbor_cells (list_arr, head_arr, neighbor_cells)

mask = np.isin(postate, temporary_state)
assert np.all(mask == True) == True, 'particles in neighbor cells has been indetified wrongly'
print ('
')
print ('--------------------------------------------------')
print ('the CellLinked class is verified by the given test')
print ('--------------------------------------------------')

While using the above test function, this error appears:

temporary_state = model._find_particles_inside_neighbor_cells (list_arr, head_arr, neighbor_cells)
AttributeError: 'CellLinked' object has no attribute '_find_particles_inside_neighbor_cells'

I would appreciate it if you take a look at this error and tell me how can I solve this error. Thanks


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The error is not what you are getting when I tried it on my machine.

It happens due to the fact that your global variable postate is defined inside the conditional if __name__ == "__main__": which won't be executed when you import this module in some other module. To overcome this, you have to define the postate variable outside your if conditional, at a global level in your module cell_linked_list, along with the variables box_len and r_cut.

box_len = 3
r_cut = 1
postate = box_len * np.random.random_sample((50, 3))

if __name__ == "__main__":
    # rest of your code (which won't be executed if this module is imported in some other file)

Also need to make changes in your second module since you need to update the global variables of your imported module cell_linked_list:

import numpy as np
import cell_linked_list as so
from cell_linked_list import CellLinked

so.box_len = 3
so.r_cut = 1
so.postate = so.box_len * np.random.random_sample((50, 3))
model = CellLinked(so.box_len, so.r_cut)
head_arr, list_arr = model(so.postate)
neighbor_cells = model._find_neighbor_cells(head_arr)
neighbor_cells = neighbor_cells[13]
temporary_state = model._find_particles_inside_neighbor_cells(
list_arr, head_arr, neighbor_cells)

mask = np.isin(so.postate, temporary_state)
assert np.all(
    mask ==
    True) == True, 'particles in neighbor cells has been indetified wrongly'
print('
')
print('--------------------------------------------------')
print('the CellLinked class is verified by the given test')
print('--------------------------------------------------')

One suggestion, you should have the variables box_len, r_cut and postate as your class's variables and initialize them in the class's constructor instead.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...