title: NameError: global name 'profiles' is not defined
body: <pre><code>from pandas import DataFrame
  from itertools import permutations
  from collections import Counter
  import requests
  import json
  from math import *
  from numpy import *
  from multiprocessing.dummy import Pool as dPool
  from multiprocessing import Pool as Pool
  
  def to_dict(in_str):
      head2 = [x.split(":",1) for x in in_str.split("\n")]
      head3 = {x[0].strip():x[1].strip() for x in head2}
      return head3
  
  def get_session_id():
      out = '{"appName":"Grindr","appVersion":"2.1.3","authenticationToken":"c22d27b4c2e5b3083a2d42ad974f3294f22a008710a4e4dc247554ab12dc974b","deviceIdentifier":"","platformName":"Android","platformVersion":"19","profileId":"39724408"}'
      session_header = requests.post('https://primus.grindr.com/2.0/session',headers = to_dict("""Accept: application/json
      Content-Type: application/json; charset=utf-8
      Content-Length: 223
      User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.2; SAMSUNG-SM-G900A Build/KOT49H)
      Host: primus.grindr.com
      Connection: Keep-Alive
      Accept-Encoding: gzip"""),data=out).headers
      return session_header['session-id']
  
  def get_nearby_profiles(lati,longi,session_id= None,return_only_dist = True):
      if session_id ==None:
          session_id = get_session_id()
      out1 = '{"filter":{"onlineOnly":false,"page":1,"quantity":1000},"lat":LAT,"lon":LONG}'
      out1 = out1.replace('LAT',str(lati))
      out1 = out1.replace('LONG',str(longi))
      in1 = to_dict("""Accept: application/json
      Content-Type: application/json; charset=utf-8
      Content-Length: 91
      User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.2; SAMSUNG-SM-G900A Build/KOT49H)
      Host: primus.grindr.com
      Connection: Keep-Alive
      Accept-Encoding: gzip""")
      in1['Session-Id'] = session_id
      ret = json.loads( requests.post('https://primus.grindr.com/2.0/nearbyProfiles',headers = in1,data=out1).text)['profiles']
      if return_only_dist:
          return [x for x in ret if x.get('showDistance')]
      else:
          return ret
  
  def triangulate(three_pts):
      """
      Thanks to http://gis.stackexchange.com/users/50/wwnick
      ---&gt;&gt;&gt; http://gis.stackexchange.com/questions/66/trilateration-using-3-latitude-and-longitude-points-and-3-distances/415#415
      for this code
      """
      #assuming elevation = 0
      earthR = 6371
  
      LatA = three_pts[0][0]
      LonA = three_pts[0][1]
      DistA = three_pts[0][2]
  
      LatB = three_pts[1][0]
      LonB = three_pts[1][1]
      DistB = three_pts[1][2]
  
      LatC = three_pts[2][0]
      LonC = three_pts[2][1]
      DistC = three_pts[2][2]
  
      #using authalic sphere
      #if using an ellipsoid this step is slightly different
      #Convert geodetic Lat/Long to ECEF xyz
      #   1. Convert Lat/Long to radians
      #   2. Convert Lat/Long(radians) to ECEF
      xA = earthR *(math.cos(math.radians(LatA)) * math.cos(math.radians(LonA)))
      yA = earthR *(math.cos(math.radians(LatA)) * math.sin(math.radians(LonA)))
      zA = earthR *(math.sin(math.radians(LatA)))
  
      xB = earthR *(math.cos(math.radians(LatB)) * math.cos(math.radians(LonB)))
      yB = earthR *(math.cos(math.radians(LatB)) * math.sin(math.radians(LonB)))
      zB = earthR *(math.sin(math.radians(LatB)))
  
      xC = earthR *(math.cos(math.radians(LatC)) * math.cos(math.radians(LonC)))
      yC = earthR *(math.cos(math.radians(LatC)) * math.sin(math.radians(LonC)))
      zC = earthR *(math.sin(math.radians(LatC)))
  
      P1 = array([xA, yA, zA])
      P2 = array([xB, yB, zB])
      P3 = array([xC, yC, zC])
  
      #from wikipedia
      #transform to get circle 1 at origin
      #transform to get circle 2 on x axis
      ex = (P2 - P1)/(linalg.norm(P2 - P1))
      i = dot(ex, P3 - P1)
      ey = (P3 - P1 - i*ex)/(linalg.norm(P3 - P1 - i*ex))
      ez = cross(ex,ey)
      d = linalg.norm(P2 - P1)
      j = dot(ey, P3 - P1)
  
      #from wikipedia
      #plug and chug using above values
      x = (pow(DistA,2) - pow(DistB,2) + pow(d,2))/(2*d)
      y = ((pow(DistA,2) - pow(DistC,2) + pow(i,2) + pow(j,2))/(2*j)) - ((i/j)*x)
  
      # only one case shown here
      z = sqrt(pow(DistA,2) - pow(x,2) - pow(y,2))
  
      #triPt is an array with ECEF x,y,z of trilateration point
      triPt = P1 + x*ex + y*ey + z*ez
  
      #convert back to lat/long from ECEF
      #convert to degrees
      lat = math.degrees(math.asin(triPt[2] / earthR))
      lon = math.degrees(math.atan2(triPt[1],triPt[0]))
  
      return lat, lon
  
  def get_grid(left,right,num_pts):
      num_pts = num_pts/10
      ret = []
      x = linspace(left[0], right[0], num_pts)
      y = linspace(left[1], right[1], num_pts)
      for i in range(num_pts):
          for j in range(num_pts):
              ret.append([x[i],y[j]])
      return ret
  
  def get_requ(incoming):
      a,b = incoming
      while True:
          try:
              return get_nearby_profiles(a,b),incoming
          except:
              continue
  
  def triangulate_multiple(input_dist):
      o =[]
      for k in list(permutations(input_dist,3)):
          tria = triangulate(k)
          if not isnan(tria[0]) and not isnan(tria[1]):
              o.append(tria)
          if len(o)&gt;3:
              break
      return mean([x[0] for x in o]),mean([x[1] for x in o])
  
  
  def process_point(each_user):
      global profiles
      out = []
      values = seen[each_user]
      if len(values)&lt;3:
          return None
      else:
          loc = triangulate_multiple(values)
          if not isnan(loc[0]) and not isnan(loc[1]):
              obs = {}
              obs ['lat'] = loc[0]
              obs ['long'] = loc[1]
              obs ['name'] = profiles[each_user].get(u'displayName','')
              obs ['headline'] = profiles[each_user].get('headline','')
              obs ['image'] = 'http://cdns.grindr.com/images/profile/1024x1024/{}'.format(profiles[each_user].get(u'profileImageMediaHash'))
              return obs
  
  def create_profiles(unmerged_profiles):
      seen = {}
      for data,cord in unmerged_profiles:
          for each_person in data:
              ID = each_person[u'profileId']
              if each_person['showDistance']:
                  profiles[ID] = each_person
      return (seen,profiles)
  
  def download_grid(grid_pts,num_threads= 20):
      p1 = dPool(num_threads)
      ret = p1.map(get_requ,grid_pts)
      p1.close()
      return create_profiles(ret)
  
  def triangulate_profiles(seen, processes = 8):
      pool = Pool(processes)
      result_iterator = pool.imap_unordered(process_point,seen.keys())
      for i in result_iterator:
          if i !=None:
              yield i
  
  if __name__ == '__main__':
      # define GPS grid to search
      # left is GPS location ==&gt; bottom left bounding point
      # right is GPS location ==&gt; top right bounding point
      # different grids can be separated by new lines
      locations = """42.363612, -71.130838+42.363612, -71.130838""".split("\n")
      # locations = """42.363612, -71.130838+42.363612, -71.130838
      # 37.757727, -122.446204+37.791716, -122.393418""".split("\n")
  
      locations = [[[float(t.strip()) for t in y.split(",")] for y in x.split("+")] for x in locations]
  
      gps_pts_to_use_for_search = []
      for loc in locations:
          gps_pts_to_use_for_search+= get_grid(loc[0],loc[1],20)
  
      print "INFO: downloading {} GPS locations".format(len(gps_pts_to_use_for_search))
      seen_profiles,profiles = download_grid(gps_pts_to_use_for_search)
  
  
      print "INFO: creating GPS locations of {} observed users".format(len(profiles))
  
      all_pts = []
      for each_located_grindr in triangulate_profiles(seen_profiles):
          each_located_grindr['address']  = geo_locate(each_located_grindr['lat'],each_located_grindr['long'])
          print each_located_grindr
          all_pts.append(each_located_grindr)
      DataFrame(all_pts).to_csv('GPS.csv',index=False,encoding='utf-8')
  </code></pre>
  
  <p>When running it gives the error</p>
  
  <pre class="lang-none prettyprint-override"><code>NameError: global name 'profiles' is not defined
  </code></pre>
  
  <p>Any ideas?</p>