user6952870 user6952870 - 10 days ago 9
Python Question

Why do I get a TypeError when I call cProfile.run()?

import math
import random
import cProfile
import pstats
from goody import irange


def partition(alist, left, right):
def swap(i,j): alist[i],alist[j] = alist[j],alist[i]
pivot = alist[right]
i = left
for j in range(left,right):
if alist[j] <= pivot:
swap(i,j)
i += 1
swap(i,right)
return I

def select(alist, n):
left,right = 0, len(alist)-1
while True:
if left == right:
return alist[left]
pivot_index = partition(alist, left, right)
if n == pivot_index:
return alist[n]
elif n < pivot_index:
right = pivot_index - 1
else:
left = pivot_index + 1

def closest_2d(alist):
def dist(p1,p2): return math.sqrt( (p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
def min_none(*args): return min([x for x in args if x != None])
if len(alist) < 2:
return None # +infinity
if len(alist) == 2:
return dist(alist[0],alist[1])

m = select([x for (x,_) in alist],len(alist)//2)
s1,s2,s3 = [],[],[]
for v in alist:
if v[0] == m:
s3.append(v)
else:
(s1 if v[0] < m else s2).append(v)
if s1 == []:
s1.append(s3[0])
s2.extend(s3[1:])
else:
s2.append(s3[0])
s1.extend(s3[1:])


d1 = closest_2d(s1)
d2 = closest_2d(s2)
d = min_none(d1,d2)

s1.sort(key = lambda p : p[1])
s2.sort(key = lambda p : p[1])
i,j = 0,0
d3 = None # +infinity
while True:
while i != len(s1) and j != len(s2) and abs(s1[i][1]-s2[j][1]) > d:
if s1[i][1] < s2[j][1]:
i += 1
else:
j += 1

if i == len(s1) or j ==len(s2):
break;

j1 = j
while j1 < len(s2) and abs(s1[i][1]-s2[j1][1]) < d:
if d3 == None or dist(s1[i],s2[j1]) < d3:
d3 = dist(s1[i],s2[j1])
j1 += 1

i += 1
return min_none(d1,d2,d3)

# My code

a = []
for i in range(128000):
a.append((random.random,random.random))

cProfile.run('closest_2d(a)')


I am trying to write a script that uses the cProfile module to profile all the functions called when the
closest_2d
function is run first on a random list with 128,000 coordinate. Generate the random list, and then call
cProfile.run
so that it runs
closest_2d
on that list; also specify a second argument, which is the file to put the results in (and the file on which to call
pstats.Stats
) to print the results.

I got the following error:

Traceback (most recent call last):
cProfile.run('closest_2d(a)')
return _pyprofile._Utils(Profile).run(statement, filename, sort)
prof.run(statement)
return self.runctx(cmd, dict, dict)
exec(cmd, globals, locals)
m = select([x for (x,_) in alist],len(alist)//2)
pivot_index = partition(alist, left, right)
if alist[j] <= pivot:
TypeError: unorderable types: builtin_function_or_method() <= builtin_function_or_method()


How can I fix it?

Answer

Your question title is misleading, cProfile is being called since it's right at the top of your stack trace.

The problem is, you're getting a TypeError because you're trying to compare a two functions instead of their return values on this line:

if alist[j] <= pivot:

This is because your didn't call random.random() when you were populating your list, instead you put random.random. This places a reference to the random function rather than a random value.

a.append((random.random,random.random))

Should be:

a.append((random.random(), random.random()))