NameError:没有定义全局名称“profiles”

时间:2021-10-26 20:27:16
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
    --->>> 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)>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)<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 ==> bottom left bounding point
    # right is GPS location ==> 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')

When running it gives the error

当运行时,它会产生错误

NameError: global name 'profiles' is not defined

Any ideas?

什么好主意吗?

1 个解决方案

#1


0  

Just define the profiles variable outside of your if, our after the includes:

只要在您的if之外定义配置文件变量,我们的后面包括:

from multiprocessing import Pool as Pool

profiles = {}

def to_dict(in_str):

#1


0  

Just define the profiles variable outside of your if, our after the includes:

只要在您的if之外定义配置文件变量,我们的后面包括:

from multiprocessing import Pool as Pool

profiles = {}

def to_dict(in_str):