示例#1
0
 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)
示例#2
0
 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)
示例#3
0
    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
示例#4
0
    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
示例#5
0
    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]