On Sun, 10 Jul 2005 11:19:31 +0100, Philipp H. Mohr wrote: > Hello, > I got a newbie question, I have written the following distance function:
Great. Now, how about you tell us what you expect it to do? I assume it calculates the Euclidean distance between two points. (If you don't know what Euclidean distance is, don't worry about it -- it is basically just the "normal" distance.) Should it calculate the distance between points on a line? 2-D points on a plane? 3-D points in space? Higher dimensions? I'm going to assume you want your function to operate on any number of dimensions. > def distance(self,element1, element2): You don't need "self" unless it is a method of a class. > dist = 0 > for n in range(len(element1)): > dist = dist + pow((element1[n] - element2[n]),2) > print 'dist' + dist Why are you printing the SQUARE of the distance? > return sqrt(dist) Okay, here is a simpler method, complete with comments: def distance(point1, point2): """Return the distance between two points in N-dimensional space. Example: if the points are (a,b) and (c,d) respectively, returns the Euclidean distance d = sqrt( (c-a)**2 + (d-b)**2 ) Both points should have the same number of coordinates, each of which is a float or int. Points can be given as lists or tuples. """ sum_sq = 0 # sum of squares of the differences if len(point1) != len(point2): # check for errors here because they might not be picked # up later if we don't raise ValueError("Points have different number of dimensions") for i in range(len(point1)): x, y = point1[i], point2[i] # extract the next two ordinates sum_sq = sum_sq + (y-x)**2 # and add the square of the difference return sum_sq**0.5 If you really care about accuracy, you should use the sqrt function from the math module rather than **0.5. Here is another version, using zip. def distance(point1, point2): if len(point1) != len(point2): raise ValueError("Points have different number of dimensions") L = zip(point1, point2) sum_sq = 0 for x,y in L: sum_sq = sum_sq + (y-x)**2 return sum_sq**0.5 And finally, a one-liner using list comprehensions and no error-checking. def distance(point1, point2): return sum([(y-x)**2 for x,y in zip(point1, point2)])**0.5 > and in order to be able to use len() and index element1[] the function > needs to know that the arguments element1 and element2 are both listst > or doesn't it ? No. Lots of things can be passed to len() and indexed. > I get the following error msg: > > Traceback (most recent call last): > File "Memory.py", line 105, in ? > start.inputVector(inP2) > File "Memory.py", line 97, in inputVector > allDimensions[0].newAttribute(vector) > File "Memory.py", line 56, in newAttribute > dist = self.distance(n.getCenter,newElement) > File "Memory.py", line 75, in distance > for n in range(len(element1)): > TypeError: len() of unsized object And what is element1 when you get that error message? That's the first thing I would look at. > AND if I take len out I get: > > > Traceback (most recent call last): > File "Memory.py", line 105, in ? > start.inputVector(inP2) > File "Memory.py", line 97, in inputVector > allDimensions[0].newAttribute(vector) > File "Memory.py", line 56, in newAttribute > dist = self.distance(n.getCenter,newElement) > File "Memory.py", line 76, in distance > dist = dist + pow((element1[n] - element2[n]),2) > TypeError: unsubscriptable object Firstly, you seem to have a lot of modules there. What happens when you call distance directly? Can you get it to work then? Secondly, what are the values for element1 and element2? -- Steven. -- http://mail.python.org/mailman/listinfo/python-list