0
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?

Soviut
  • 88,194
  • 49
  • 192
  • 260

1 Answers1

0

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()))
Soviut
  • 88,194
  • 49
  • 192
  • 260
  • hey, by the way, do you know how to sort the result that produced by the cProfile.run()? such as the ncalls or tottime? – user6952870 Nov 27 '16 at 09:18