passing arguments to a function - do I need type ?
Steven D'Aprano
steve at REMOVETHIScyber.com.au
Sun Jul 10 17:33:39 CEST 2005
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.
More information about the Python-list
mailing list