code: def process_results(self):
  		
  		self.stage += 1
  		
  		# collect all config_ids that need to be compared
  		config_ids = list(filter(lambda cid: self.data[cid].status == 'REVIEW', self.data.keys()))
  
  		if (self.stage >= len(self.num_configs)):
  			self.finish_up()
  			return
  
  		budgets = [self.data[cid].budget for cid in config_ids]
  		if len(set(budgets)) > 1:
  			raise RuntimeError('Not all configurations have the same budget!')
  		budget = self.budgets[self.stage-1]
  
  		losses = np.array([self.data[cid].results[budget]['loss'] for cid in config_ids])
  
  		advance = self._advance_to_next_stage(config_ids, losses)
  
  		for i, a in enumerate(advance):
  			if a:
  				self.logger.debug('ITERATION: Advancing config %s to next budget %f'%(config_ids[i], self.budgets[self.stage]))
  
  		for i, cid in enumerate(config_ids):
  			if advance[i]:
  				self.data[cid].status = 'QUEUED'
  				self.data[cid].budget = self.budgets[self.stage]
  				self.actual_num_configs[self.stage] += 1
  			else:
  				self.data[cid].status = 'TERMINATED'
docs: function that is called when a stage is completed and
  		needs to be analyzed befor further computations.
  
  		The code here implements the original SH algorithms by
  		advancing the k-best (lowest loss) configurations at the current
  		budget. k is defined by the num_configs list (see __init__)
  		and the current stage value.
  
  		For more advanced methods like resampling after each stage,
  		overload this function only.