11

Writing some code in python to evaluate a basic function. I've got a 2d array with some values and I want to apply the function to each of those values and get a new 2-d array:

import numpy as N
def makeGrid(dim):
    ''' Function to return a grid of distances from the centre of an array.
    This version uses loops to fill the array and is thus slow.'''
    tabx = N.arange(dim) - float(dim/2.0) + 0.5
    taby = N.arange(dim) - float(dim/2.0) + 0.5
    grid = N.zeros((dim,dim), dtype='float')
    for y in range(dim):
        for x in range(dim):
            grid[y,x] = N.sqrt(tabx[x]**2 + taby[y]**2)
    return grid

import math

def BigGrid(dim):
    l= float(raw_input('Enter a value for lambda: '))
    p= float(raw_input('Enter a value for phi: '))
    a = makeGrid 
    b= N.zeros ((10,10),dtype=float) #Create an array to take the returned values
    for i in range(10):
        for j in range (10):
            b[i][j] = a[i][j]*l*p
    return b


if __name__ == "__main__":
    ''' Module test code '''
    size = 10 #Dimension of the array
    newGrid = BigGrid(size)
    newGrid = N.round(newGrid, decimals=2)
    print newGrid

But all i get is the error message

Traceback (most recent call last):
  File "sim.py", line 31, in <module>
    newGrid = BigGrid(size)
  File "sim.py", line 24, in BigGrid
    b[i][j] = a[i][j]*l*p
TypeError: 'function' object has no attribute '__getitem__'

Please help.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
user1887919
  • 829
  • 2
  • 9
  • 24
  • 3
    Some general remarks about your numpy code: 1) try to `import numpy as np`, as that's the numpy convention. 2) Use vector operations, ie: `a = b * l * p` instead of the double loop. It will be hundreds or thousands of times faster, and it's easier to read. 3) Don't index numpy arrays as `array[i][j]`, use this instead `array[i,j]` it's much faster, and shorter to write ;). To summarize, read a numpy tutorial. – jorgeca Dec 10 '12 at 17:59

3 Answers3

26

It appears you have forgotten a pair of parentheses:

a = makeGrid(dim)

What you have now:

a = makeGrid

just aliases the makeGrid function instead of calling it. Then, when you try to index into a, like so:

a[i]

it's trying to index into a function, which does not have the __getitem__ magic method needed for indexing with bracket notation.

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
5

As others have said, you need to call makeGrid properly.... just as an fyi, this is a fairly common error to see in Python, and it generally means that your variable is not the type that you thought it was (in this case, you were expecting a matrix, but got a function)

TypeError: 'function' object has no attribute '__getitem__'
Cameron Sparr
  • 3,925
  • 2
  • 22
  • 31
3

You're not calling makeGrid(), you're assigning the function object itself to a:

    a = makeGrid(dim) 
NPE
  • 486,780
  • 108
  • 951
  • 1,012