def append_features(self,features,facts): """Alters the features dictionary in place, adds: - age - gender - this instance's feature Args: features (dictionary): Dictionary of pyMC probability distributions. Raises: DuplicateFeatureException: If an identically named feature already exists that clashes with this instance """ #age: 0-100 if not 'factor_age' in features: p = np.ones(101) #flat prior p = p/p.sum() features['factor_age'] = pm.Categorical('factor_age',p); #gender: male or female if not 'factor_gender' in features: #flat prior features['factor_gender'] = pm.Categorical('factor_gender',np.array([0.5,0.5])); if self.featurename in features: raise DuplicateFeatureException('The "%s" feature is already in the feature list.' % self.featurename); seen = ohf.true_string(self.answer); features[self.featurename]=pm.Categorical(self.featurename, self.get_pymc_function(features), value=seen, observed=True)
def append_features(self, features, facts): """Alters the features dictionary in place, adds: - age - gender - this instance's feature Args: features (dictionary): Dictionary of pyMC probability distributions. Raises: DuplicateFeatureException: If an identically named feature already exists that clashes with this instance """ #age: 0-100 if not 'factor_age' in features: p = np.ones(101) #flat prior p = p / p.sum() features['factor_age'] = pm.Categorical('factor_age', p) #gender: male or female if not 'factor_gender' in features: #flat prior features['factor_gender'] = pm.Categorical('factor_gender', np.array([0.5, 0.5])) if self.featurename in features: raise DuplicateFeatureException( 'The "%s" feature is already in the feature list.' % self.featurename) seen = ohf.true_string(self.answer) features[self.featurename] = pm.Categorical( self.featurename, self.get_pymc_function(features), value=seen, observed=True)
def process_answer(cls, dataitem, detail, old_answer): # print "PROCESSING ANSWER" #this function may alter an answer to provide additional information, or reformat it into a standard format. answer = {} answer['response'] = old_answer if dataitem == 'incity': #if it's asking if we're in a particular city if ohf.true_string(old_answer): #and the answer's yes detail_data = json.loads(detail) answer['latitude'] = detail_data['latitude'] answer['longitude'] = detail_data['longitude'] answer['city'] = detail_data['city'] answer['know'] = True #we know where we are... else: answer['know'] = False return json.dumps(answer), detail if dataitem == 'city': #if they've been asked which city they're in... #load the city and stick details in the answer name = old_answer url = 'http://api.geonames.org/wikipediaSearchJSON?title=%s&username=lionfish' % name try: raw_json = urllib2.urlopen(url).readline( ) #TODO SECURITY VULNERABILITY: This json is from the net and needs sanitising before it goes in the db. json_loc = json.loads(raw_json) maxrank = 0 chosen_place = None for place in json_loc['geonames']: if 'countryCode' in place: if (place['countryCode'] == 'GB'): if (place['rank'] > maxrank): chosen_place = place maxrank = place['rank'] #TODO Handle not finding city if (chosen_place == None): answer['know'] = False else: answer['latitude'] = chosen_place['lat'] answer['longitude'] = chosen_place['lng'] answer['city'] = chosen_place['title'] answer['know'] = True #we know where we are... except urllib2.HTTPError: answer['know'] = False answer['error'] = True return json.dumps(answer), detail return old_answer, detail
def process_answer(cls, dataitem, detail, old_answer): # print "PROCESSING ANSWER" #this function may alter an answer to provide additional information, or reformat it into a standard format. answer = {} answer['response'] = old_answer if dataitem=='incity': #if it's asking if we're in a particular city if ohf.true_string(old_answer): #and the answer's yes detail_data = json.loads(detail) answer['latitude'] = detail_data['latitude'] answer['longitude'] = detail_data['longitude'] answer['city'] = detail_data['city'] answer['know'] = True #we know where we are... else: answer['know'] = False return json.dumps(answer), detail if dataitem=='city': #if they've been asked which city they're in... #load the city and stick details in the answer name = old_answer url = 'http://api.geonames.org/wikipediaSearchJSON?title=%s&username=lionfish' % name try: raw_json = urllib2.urlopen(url).readline() #TODO SECURITY VULNERABILITY: This json is from the net and needs sanitising before it goes in the db. json_loc = json.loads(raw_json) maxrank = 0 chosen_place = None for place in json_loc['geonames']: if 'countryCode' in place: if (place['countryCode']=='GB'): if (place['rank']>maxrank): chosen_place = place maxrank = place['rank'] #TODO Handle not finding city if (chosen_place==None): answer['know'] = False else: answer['latitude'] = chosen_place['lat'] answer['longitude'] = chosen_place['lng'] answer['city'] = chosen_place['title'] answer['know'] = True #we know where we are... except urllib2.HTTPError: answer['know'] = False answer['error'] = True return json.dumps(answer), detail return old_answer, detail
def pick_question(cls, questions_asked): #Picks a question to ask, using previous questions asked. #incity->yes #incity->no --> city->name #landmark->yes --> landmarkdist->distance #landmark->no --> landmark... #from the questions and answers so far given, do we... know_city = False #...know the city where they are? not_in_city = False #...know they aren't in the city we guessed (from their IP address)? failed = False city_details = {} outstanding_landmarks = [] #List of landmarks we know they know, but we don't know how far they are. landmarks_done_already = []; #List of landmarks we know the distance to already known_landmarks = []; #similar to landmarks_done_already but only includes ones we have answers for known_distances = []; #the distances to the landmarks (in the same order) for qa in questions_asked: if qa['dataset']=='where': #if it is a landmark->where question if qa['dataitem']=='incity': #and it's asking if we're in a particular city if qa['answer']=='no': not_in_city = True else: answerdata = json.loads(qa['answer']) #TODO Handle ValueError exception if answerdata['know']: #and the answer's yes city_details = answerdata know_city = True; else: not_in_city = True; if qa['dataitem']=='city': #if we've asked which city they are in... answerdata = json.loads(qa['answer']) if answerdata['know']: city_details = answerdata know_city = True; else: know_city = False failed = True #We've no idea where they are if qa['dataitem'] == 'landmark': if ohf.true_string(qa['answer']): outstanding_landmarks.append(int(qa['detail'])); landmarks_done_already.append(int(qa['detail'])); if qa['dataitem'] == 'landmarkdist': outstanding_landmarks.remove(int(qa['detail'])); known_distances.append(float(qa['answer'])); known_landmarks.append(int(qa['detail'])); if failed: return 'None', '' #Give up: we can't create any sensible questions if not know_city: #if we don't know the city we're in... if not_in_city: #if we're not in the place we guessed using their IP, ask their city return 'city','' else: #if we don't know that, we need to ask if they're where their IP is. url = 'https://freegeoip.net/json/'; try: raw_json = urllib2.urlopen(url,timeout=3).readline() #TODO SECURITY VULNERABILITY: This json is from the net and needs sanitising before it goes in the db. except urllib2.HTTPError: raw_json = '' return 'city','' except urllib2.URLError:#time out? raw_json = '' return 'city','' data = {} json_loc = json.loads(raw_json) data['latitude'] = json_loc['latitude'] data['longitude'] = json_loc['longitude'] data['city'] = json_loc['city'] #TODO: CACHE IN DB return 'incity',json.dumps(data) #at this point we should know the city. if (len(outstanding_landmarks)==0): #pick a new landmark to ask about... #print "Find a new landmark to ask about.." items = cls.overpass_query(city_details['latitude'],city_details['longitude'],0.4,'tourism', 'museum') new_item = None import trilateration # items,p,entropy = trilateration.sortLandmarks(items,known_landmarks,known_distances) items,p,entropy = trilateration.sortLandmarks(items,known_landmarks,known_distances,landmarks_done_already) #print items # for item in items: # if not item.id in landmarks_done_already: # new_item = item # break #TODO delete old code if (len(items)>0): new_item = items[0] if new_item == None: #no more places to ask about return 'None', '' return 'landmark',new_item.id else: return 'landmarkdist',outstanding_landmarks[0]