def add_relations(self, from_ids, to_ids, weights=1): """ Add relations to this Relationships from from_ids, to_ids, weights """ self.grouped = utils.merge_2_dicts( self.grouped, Relations.from_tuples(from_ids, to_ids, weights), lambda r1, r2: r1.plus(r2))
def description(self): """ note that value_merge_func passed here might not be optimal :return: serializable dict representing this generator, method and it's arguments """ return merge_2_dicts({ "type": "FakerGenerator", "method": self.method.__name__ }, self.fakerKwargs, value_merge_func=lambda x, y: y)
def remove_relations(self, from_ids, to_ids): """ Removes all relations between those from_ids and to_ids pairs (not combinatory: if each list is 10 elements, we removed 10 pairs). If the same relation was stored several times between two ids, this removes them all """ self.grouped = utils.merge_2_dicts( self.grouped, Relations.from_tuples(from_ids, to_ids, weights=0), lambda r1, r2: r1.minus(r2))
def __init__(self, name, initiating_population, member_id_field, activity_gen=ConstantGenerator(value=1.), states=None, timer_gen=ConstantDependentGenerator(value=-1), auto_reset_timer=True): """ :param name: name of this story :param initiating_population: population from which the operations of this story are started :param member_id_field: when building the story data, a field will be automatically inserted containing the member ids, with this name :param activity_gen: generator for the default activity levels of the population members for this story. Default: same level for everybody :param states: dictionary of states providing activity level for other states of the population + a probability level to transit back to the default state after each execution (NOT after each clock tick). Default: no supplementary states. :param timer_gen: timer generator: this must be a generator able to generate new timer values based on the activity level. Default: no such generator, in which case the timer never triggers this story. :param auto_reset_timer: if True, we automatically re-schedule a new execution for the same member id after at the end of the previous ont, by resetting the timer. """ self.name = name self.triggering_population = initiating_population self.member_id_field = member_id_field self.size = initiating_population.size self.time_generator = timer_gen self.auto_reset_timer = auto_reset_timer self.forced_to_act_next = pd.Series() # activity and transition probability parameters, for each state self.params = pd.DataFrame({("default", "activity"): 0}, index=initiating_population.ids) default_state = { "default": { "activity": activity_gen, "back_to_default_probability": ConstantGenerator(value=1.), } } for state, state_gens in merge_2_dicts(default_state, states).items(): activity_vals = state_gens["activity"].generate(size=self.size) probs_vals = state_gens["back_to_default_probability"].generate( size=self.size) self.params[("activity", state)] = activity_vals self.params[("back_to_default_probability", state)] = probs_vals # current state and timer value for each population member id self.timer = pd.DataFrame({ "state": "default", "remaining": -1 }, index=self.params.index) if self.auto_reset_timer: self.reset_timers() self.ops = self.StoryOps(self) # in case self.operations is not called, at least we have a basic # selection self.operation_chain = Chain()
def description(self): return merge_2_dicts({ "type": "NumpyRandomGenerator", "method": self.method }, self.numpy_parameters, value_merge_func=lambda x, y: y)
def generate(self, size): all_params = merge_2_dicts({"size": size}, self.numpy_parameters) return self.numpy_method(**all_params)
def test_merge_dict_to_itself_should_return_doubled_values(): d1 = {"a": 1, "b": 2} assert {"a": 2, "b": 4} == merge_2_dicts(d1, d1, lambda a, b: a + b)
def test_merge_two_empty_dict_should_return_empty_dict(): assert {} == merge_2_dicts({}, {})
def test_merge_non_overlapping_dict_should_return_all_values(): d1 = {"a": 1, "b": 2} d2 = {"c": 3, "d": 4} assert {"a": 1, "b": 2, "c": 3, "d": 4} == merge_2_dicts(d1, d2)
def test_merge_empty_with_dict_should_return_itself(): d1 = {"a": 1, "b": 2} assert d1 == merge_2_dicts(d1, {}) assert d1 == merge_2_dicts({}, d1)
def test_merging_none_with_one_dict_should_yield_dict(): d2 = {"a": 1, "b": 2} assert d2 == merge_2_dicts(None, d2)
def test_merging_one_dict_with_none_should_yield_dict(): d1 = {"a": 1, "b": 2} assert d1 == merge_2_dicts(d1, None)
def test_merge_two_none_dict_should_return_empty_dict(): assert {} == merge_2_dicts(None, None)