def __init__(self, init_dict={}): """ Create a new organism from a dictary of parameters. The dictionary is specified in blossom.default_fields. """ # Set up defaults based on organism parameters for (field, default) in default_fields.organism_fields.items(): setattr(self, field, init_dict.get(field, default)) # Set up custom fields provided in initialization dictionary init_keys = set(init_dict.keys()) default_keys = set(default_fields.organism_fields.keys()) for custom_field in (init_keys - default_keys): setattr(self, custom_field, init_dict[custom_field]) # Set unique id for organism if self.organism_id is None: # self.organism_id = str(uuid.uuid4()) self.organism_id = self.get_new_id() # Set current water level for uninitialized organism if self.drinking_type is not None and self.water_current is None: self.water_current = self.water_initial # Set current food level for uninitialized organism if self.eating_type is not None and self.food_current is None: self.food_current = self.food_initial # Import custom modules / paths if self.custom_module_fns is not None: self._custom_modules = [] for i, path in enumerate(cast_to_list(self.custom_module_fns)): temp_module = imp.load_source('%s' % i, path) self._custom_modules.append(temp_module)
def request_translation(translator, sentences, source_language, target_language): """ Request a MachineTranslator to perform a translation. The request process is implemented based on the type of MachineTranslator. For example, a SERVERLAND type uses a MT Server Land to request a translation. Preconditions: translator: A MachineTranslator object. sentences: A list of strings. Exceptions: UnsupportedLanguagePair:The target translator doesn't support the language pair. UndefinedTranslator: When looking up the ServerlandHost for a MachineTranslator, if none exists (this should not happen). ServerlandConfigError: The ServerlandHost has an error. """ # Make sure that the translator supports the language pair if not translator.is_language_pair_supported(source_language, target_language): raise UnsupportedLanguagePair(translator, source_language, target_language) # Generate a request id request_id = utils.generate_request_id() # Make sure that sentences is a list. sentences = utils.cast_to_list(sentences) # if not isinstance(sentences, list): # print "Retrieved only one sentence." # sentences = [sentences] # One sentence per line, to make it easier for the translator to do its job. text = "\n".join(sentence for sentence in sentences) # Determine the machine translator type. if translator.type == SERVERLAND: # Get the ServerlandHost try: # TODO: Change this host reference. Currently, only one ServerLand host is allowed. serverland_host = translator.serverlandhost_set.all()[0] except IndexError: raise UndefinedTranslator(translator) source_file_id = "%s-%s-%s" % (request_id, source_language.code, target_language.code) try: # print "Requesting the translation" # print serverland_host.token, request_id, translator.shortname # print utils.get_iso639_2(source_language.code), utils.get_iso639_2(target_language.code) # print source_file_id # print text # Request the translation. proxy = xmlrpclib.ServerProxy(serverland_host.url) result = proxy.create_translation( serverland_host.token, # Authentication token request_id, # Custom request ID translator.shortname, # MT ServerLand worker utils.get_iso639_2(source_language.code ), # Source language (in bibliographic) utils.get_iso639_2(target_language.code ), # Target language (in bibliographic) source_file_id, # Composite id text) # Sentence(s) to translate # TODO: For now, just print the results. print result # TODO: Return the request_id return request_id except xmlrpclib.Fault as ex: raise ServerlandConfigError(serverland_host, ex)
def fetch_translations(self): proxy = xmlrpclib.ServerProxy(self.url) # Fetch the translation requests (and make sure the result is a list) requests = utils.cast_to_list(proxy.list_requests(self.token)) # Retrieve the translation requests that are "ready" completedRequests = [ request for request in requests if request['ready'] ] # Process the completed requests for completedRequest in completedRequests: # Get the result result = proxy.list_results(self.token, completedRequest['request_id']) # Get the external request id and sentences external_request_id = completedRequest['shortname'] result_sentences = utils.clean_string( result['result'].strip()).split('\n') # FIXME: Add exception handling when the translation request is not found. try: # Look up the original translation request request = TranslationRequest.objects.get_by_external_id( external_request_id) # TODO: Should we delete the translations, or filter them some way in Serverland to prevent re-retrieving translations? This could get expensive... if requst.status == STATUS_FINISHED: # Only update if the translation isn't marked as finished. continue # Fetch the Pootle store for the corresponding translation project and fill in the translations. store = Store.objects.get( translation_project=request.translation_project) # Get all of the units units = store.unit_set.all() # Make sure that len(units) matches len(result) # print units[0].source # print result_sentences[0] # print "----" # print units[len(units) - 1].source # print result_sentences[len(result_sentences)-1] # print result_sentences[len(result_sentences)-2] # If the sentence length doesn't match, then we don't have a one-to-one correspondence # between sentences. Mark the translation request with an error if (len(units) != len(result_sentences)): request.status = STATUS_ERROR print "An error occurred with request %s" % request else: # Start adding the translations to Pootle (lazy). for i in range(0, len(units)): # units[i].target = multistring(result_sentences[i]) units[i].target = result_sentences[i] units[i].state = pootle_store.util.FUZZY units[i].save() # Set the status of the current TranslationRequest as completed request.status = STATUS_FINISHED request.save() except ObjectDoesNotExist as ex: pass
def act(self, population_dict, world, position_hash_table=None): """ Method that decides and calls an action for the current timestep. Searches through custom methods and built-in movement methods. The action method specifically selects an action to take, from "move", "reproduce", "drink", and "eat". Then the appropriate instance method from this class is executed to yield the final list of affect organisms. Parameters ---------- population_dict : dict of Organisms Dict of organisms, with which this organism may interact. world : World World, with which this organism may interact. position_hash_table : dict Dictionary mapping positions to available organisms. Returns ------- affected_organisms : Organisms, or list of Organisms Organism or list of organisms affected by this organism's action. """ action_name = None try: if self.custom_module_fns is not None: for custom_module in self._custom_modules: if hasattr(custom_module, self.action_type): action_name = getattr(custom_module, self.action_type)( self, population_dict, world, position_hash_table=position_hash_table) if action_name is None: action_name = getattr(action, self.action_type)( self, population_dict, world, position_hash_table=position_hash_table) except AttributeError as e: raise AttributeError( str(e) + '. Check that \'%s\' method is indeed ' % self.action_type + 'contained within the provided custom modules and that the ' + 'method is written correctly.').with_traceback( sys.exc_info()[2]) self.last_action = action_name affected_organisms = cast_to_list( getattr(self, action_name)(population_dict, world, position_hash_table=position_hash_table)) # Ensure this organism is included in affected_organisms already_included = False for org in affected_organisms: if org.organism_id == self.organism_id: already_included = True if not already_included: # e.g. unknown reason for exlusion, so default to death self.die('unknown', in_place=True) affected_organisms.append(self) return self, affected_organisms
def request_translation(translator, sentences, source_language, target_language): """ Request a MachineTranslator to perform a translation. The request process is implemented based on the type of MachineTranslator. For example, a SERVERLAND type uses a MT Server Land to request a translation. Preconditions: translator: A MachineTranslator object. sentences: A list of strings. Exceptions: UnsupportedLanguagePair:The target translator doesn't support the language pair. UndefinedTranslator: When looking up the ServerlandHost for a MachineTranslator, if none exists (this should not happen). ServerlandConfigError: The ServerlandHost has an error. """ # Make sure that the translator supports the language pair if not translator.is_language_pair_supported(source_language, target_language): raise UnsupportedLanguagePair(translator, source_language, target_language) # Generate a request id request_id = utils.generate_request_id() # Make sure that sentences is a list. sentences = utils.cast_to_list(sentences) # if not isinstance(sentences, list): # print "Retrieved only one sentence." # sentences = [sentences] # One sentence per line, to make it easier for the translator to do its job. text = "\n".join(sentence for sentence in sentences) # Determine the machine translator type. if translator.type == SERVERLAND: # Get the ServerlandHost try: # TODO: Change this host reference. Currently, only one ServerLand host is allowed. serverland_host = translator.serverlandhost_set.all()[0] except IndexError: raise UndefinedTranslator(translator) source_file_id = "%s-%s-%s" % (request_id, source_language.code, target_language.code) try: # print "Requesting the translation" # print serverland_host.token, request_id, translator.shortname # print utils.get_iso639_2(source_language.code), utils.get_iso639_2(target_language.code) # print source_file_id # print text # Request the translation. proxy = xmlrpclib.ServerProxy(serverland_host.url) result = proxy.create_translation(serverland_host.token, # Authentication token request_id, # Custom request ID translator.shortname, # MT ServerLand worker utils.get_iso639_2(source_language.code), # Source language (in bibliographic) utils.get_iso639_2(target_language.code), # Target language (in bibliographic) source_file_id, # Composite id text) # Sentence(s) to translate # TODO: For now, just print the results. print result # TODO: Return the request_id return request_id except xmlrpclib.Fault as ex: raise ServerlandConfigError(serverland_host, ex)
def fetch_translations(self): proxy = xmlrpclib.ServerProxy(self.url) # Fetch the translation requests (and make sure the result is a list) requests = utils.cast_to_list(proxy.list_requests(self.token)) # Retrieve the translation requests that are "ready" completedRequests = [request for request in requests if request['ready']] # Process the completed requests for completedRequest in completedRequests: # Get the result result = proxy.list_results(self.token, completedRequest['request_id']) # Get the external request id and sentences external_request_id = completedRequest['shortname'] result_sentences = utils.clean_string(result['result'].strip()).split('\n') # FIXME: Add exception handling when the translation request is not found. try: # Look up the original translation request request = TranslationRequest.objects.get_by_external_id(external_request_id) # TODO: Should we delete the translations, or filter them some way in Serverland to prevent re-retrieving translations? This could get expensive... if requst.status == STATUS_FINISHED: # Only update if the translation isn't marked as finished. continue # Fetch the Pootle store for the corresponding translation project and fill in the translations. store = Store.objects.get(translation_project = request.translation_project) # Get all of the units units = store.unit_set.all() # Make sure that len(units) matches len(result) # print units[0].source # print result_sentences[0] # print "----" # print units[len(units) - 1].source # print result_sentences[len(result_sentences)-1] # print result_sentences[len(result_sentences)-2] # If the sentence length doesn't match, then we don't have a one-to-one correspondence # between sentences. Mark the translation request with an error if (len(units) != len(result_sentences)): request.status = STATUS_ERROR print "An error occurred with request %s" % request else: # Start adding the translations to Pootle (lazy). for i in range(0, len(units)): # units[i].target = multistring(result_sentences[i]) units[i].target = result_sentences[i] units[i].state = pootle_store.util.FUZZY units[i].save() # Set the status of the current TranslationRequest as completed request.status = STATUS_FINISHED request.save() except ObjectDoesNotExist as ex: pass
def load_species_from_param_files(fns, init_world, custom_module_fns=None): """ Load all available species parameter files. Parameters ---------- fns : list of str Input filenames of species parameter files. Different species get different species parameter files, from which the individual organisms are initialized. init_world : World Initial World instance for this Universe. custom_module_fns : list of str List of external Python scripts containing custom organism behaviors. :mod:`blossom` will search for methods within each filename included here. Returns ------- population_dict : dict of Organisms A dict of Organism objects constructed from the parameter file. """ # Find organism filenames, can be a list of patterns fns = cast_to_list(fns) org_files = [fn for pattern in fns for fn in glob.glob(pattern)] # Initialize list of dictionaries to hold all organism parameters # Each dictionary contains parameters for a single species population_dict = {} for i, org_file in enumerate(org_files): # Initialize temporary dict to store species parameters species_init_dict = {} # Parameters that must be str or None param_str = [ 'species_name', 'movement_type', 'reproduction_type', 'drinking_type', 'action_type', 'eating_type' ] # Parameters that must be int param_int = ['population_size', 'dna_length'] # Parameters that must be int or 'None' or 'inf' param_int_none_inf = [ 'max_age', 'max_time_without_food', 'max_time_without_water', 'mutation_rate', 'food_capacity', 'food_initial', 'food_metabolism', 'food_intake', 'water_capacity', 'water_initial', 'water_metabolism', 'water_intake' ] # Parameters that must be float param_float = [ 'proportion_m', 'proportion_f', 'proportion_a', 'proportion_h' ] # Parameters that must be bool param_bool = ['can_mutate'] # Load from config file config_org = configparser.ConfigParser() config_org.read(org_file) # Cycle through all parameters in the config file, # converting them to proper types as specifed above for section in config_org.sections(): for (key, val) in config_org.items(section): if key in param_str: pass elif key in param_int: val = int(val) elif key in param_int_none_inf: if val != 'None' and type(val) not in [int, float]: val = float(val) elif key in param_float: val = float(val) elif key in param_bool: val = (val == 'True') else: print(key, val) raise NameError('Key is not a valid parameter') # ensure 'None' parameters are set to None if val == 'None': val = None species_init_dict[key] = val # Track custom method file paths species_init_dict['custom_module_fns'] = custom_module_fns species_organism_list = create_organisms(species_init_dict, init_world) # Populate population dict with relevant bulk stats and organism lists population_dict[species_init_dict['species_name']] = { 'statistics': { 'total': species_init_dict['population_size'], 'alive': species_init_dict['population_size'], 'dead': 0 }, 'organisms': species_organism_list } return population_dict
def load_species_from_dict(init_dicts, init_world, custom_module_fns=None): """ Create a list of organisms loaded from Python dicts. Parameters ---------- init_dicts : list of dict Input species dictionaries from which the individual organisms are initialized. Each dictionary is for a different species. init_world : World Initial World instance for this Universe. custom_module_fns : list of str List of external Python scripts containing custom organism behaviors. :mod:`blossom` will search for methods within each filename included here. Returns ------- population_dict : dict of Organisms A dict of Organism objects constructed from the parameter file. """ init_dicts = cast_to_list(init_dicts) population_dict = {} for init_dict in init_dicts: species_init_dict = {} # Set up defaults based on species parameters for (field, default) in default_fields.species_fields.items(): species_init_dict[field] = init_dict.get(field, default) # Set up custom fields provided in initialization dictionary init_keys = set(init_dict.keys()) default_keys = set(default_fields.species_fields.keys()) for custom_field in (init_keys - default_keys): species_init_dict[custom_field] = init_dict[custom_field] assert 'population_size' in init_dict population_size = init_dict['population_size'] assert type(population_size) is int species_init_dict['population_size'] = population_size assert type(species_init_dict['species_name']) == str for field in [ 'movement_type', 'reproduction_type', 'drinking_type', 'eating_type', 'action_type' ]: assert (species_init_dict[field] is None or type(species_init_dict[field]) is str) for field in ['dna_length']: assert type(species_init_dict[field]) is int if species_init_dict['drinking_type']: assert (species_init_dict['water_capacity'] is not None and species_init_dict['water_initial'] is not None and species_init_dict['water_metabolism'] is not None and species_init_dict['water_intake'] is not None and species_init_dict['max_time_without_water'] is not None) if species_init_dict['eating_type']: assert (species_init_dict['food_capacity'] is not None and species_init_dict['food_initial'] is not None and species_init_dict['food_metabolism'] is not None and species_init_dict['food_intake'] is not None and species_init_dict['max_time_without_food'] is not None) for field in [ 'max_age', 'max_time_without_food', 'max_time_without_water', 'mutation_rate', 'food_capacity', 'food_initial', 'food_metabolism', 'food_intake', 'water_capacity', 'water_initial', 'water_metabolism', 'water_intake' ]: if type(species_init_dict[field]) is list: assert (len(species_init_dict[field]) == population_size) elif type(species_init_dict[field]) in [int, float]: species_init_dict[field] = ([species_init_dict[field]] * population_size) else: assert species_init_dict[field] is None if not species_init_dict['custom_module_fns']: # Track custom method file paths species_init_dict['custom_module_fns'] = custom_module_fns if 'initial_positions' in init_dict: assert len(init_dict['initial_positions']) == population_size for position in init_dict['initial_positions']: assert len(position) == init_world.dimensionality species_init_dict['initial_positions'] \ = init_dict['initial_positions'] species_organism_list = create_organisms(species_init_dict, init_world) # Populate population dict with relevant bulk stats and organism lists population_dict[species_init_dict['species_name']] = { 'statistics': { 'total': population_size, 'alive': population_size, 'dead': 0 }, 'organisms': species_organism_list } return population_dict