def update(self, **kwargs) -> 'Property': '''Updates the current value The method `update()` sets the property `current_value` as the output of the method `sample()`. Will only update once per resolve. Any object that implements the method `update()` will have it called. Returns ------- Property Returns itself. ''' if self.has_updated_since_last_resolve: return self self.has_updated_since_last_resolve = True if hasmethod(self.sampling_rule, "update"): self.sampling_rule.update(**kwargs) self.current_value = self.sample(self.sampling_rule, **kwargs) return self
def update(self, **kwargs) -> 'Property': '''Updates the current value The method `update()` sets the property `current_value` as the output of the method `sample()`. Will only update once per resolve. Any object that implements the method `update()` will have it called. Returns ------- Property Returns itself. ''' provided_key = kwargs.get("_update_key", False) or deeptrack.features._SESSION_STRUCT["update_key"] if self.last_update_id == provided_key: return self self.last_update_id = provided_key if hasmethod(self.sampling_rule, "update") and not isinstance(self.sampling_rule, dict): self.sampling_rule.update(**kwargs) self.current_value = self.sample(self.sampling_rule, **kwargs) return self
def update(self, **kwargs) -> 'Property': r'''Updates the current value The method `update()` sets the property `current_value` as the output of the method `sample()`. Returns ------- Property Returns itself. ''' if not kwargs.get("force_update", False) and self.has_updated_since_last_resolve: return self self.has_updated_since_last_resolve = True if hasmethod(self.sampling_rule, "update"): self.sampling_rule.update(**kwargs) self.current_value = self.sample(self.sampling_rule, **kwargs) return self
def sample(self, sampling_rule, **kwargs): '''Samples the sampling rule Returns a sampled instance of the `sampling_rule` field. The logic behind the sampling depends on the type of `sampling_rule`. These are checked in the following order of priority: 1. Any object with a callable `sample()` method has this method called and returned. 2. If the rule is a ``dict``, sample each value and combine the result into a new ``dict`` using the original keys. 3. If the rule is a ``list``, sample each element of the list and combine the result into a ne ``list``. 4. If the rule is an ``iterable``, return the next output. 5. If the rule is callable, call it with its accepted arguments. Example arguments can be the value of some other property. 6. If none of the above apply, return the rule itself. Parameters ---------- sampling_rule : any The rule to sample values from. **kwargs Arguments that will be passed on to functions that accepts them. Returns ------- any A sampled instance of the `sampling_rule`. ''' if hasmethod(sampling_rule, "sample"): # If the ruleset itself implements a sample method, # call it instead. return sampling_rule.sample(**kwargs) elif isinstance(sampling_rule, dict): # If the ruleset is a dict, return a new dict with each # element being sampled from the original dict. out = {} for key, val in self.sampling_rule.items(): out[key] = self.sample(val, **kwargs) return out elif isinstance(sampling_rule, list): return [self.sample(item, **kwargs) for item in sampling_rule] elif isinstance(sampling_rule, (tuple, np.ndarray)): # tuple and ndarrays are elementary return sampling_rule elif isiterable(sampling_rule): # If it's iterable, return the next value try: return next(sampling_rule) except StopIteration: return self.current_value elif callable(sampling_rule): # If it's a function, extract the arguments it accepts. function_input = {} # Get the kwarg arguments the function accepts for key in get_kwarg_names(sampling_rule): # If that name is among passed kwarg arguments if key in kwargs: if isinstance(kwargs[key], Property): # If it is a property, update it and pass the current value kwargs[key].update(**kwargs) if isinstance(kwargs[key], SequentialProperty): kwargs[key] = kwargs[key].current_value[ kwargs["sequence_step"]] else: kwargs[key] = kwargs[key].current_value function_input[key] = kwargs[key] return sampling_rule(**function_input) else: # Else, assume it's elementary. return sampling_rule
def sample(self, sampling_rule, **kwargs): r'''Samples the sampling rule Returns a sampled instance of the `sampling_rule` field. The logic behind the sampling depends on the type of `sampling_rule`. These are checked in the following order of priority: 1. Any object with a callable `sample()` method has this method called and returned. 2. If the rule is a ``dict``, the ``dict`` is copied and any value with has a callable sample method is replaced with the output of that call. 3. If the rule is a ``list`` or a 1-dimensional ``ndarray``, return 4. If the rule is an ``iterable``, return the next output. 5. If the rule is callable, return the output of a call with no input parameters. a single element drawn from that ``list``/``ndarray``. 6. If none of the above apply, return the rule itself. Returns ------- any A sampled instance of the `sampling_rule`. ''' if hasmethod(sampling_rule, "sample"): # If the ruleset itself implements a sample method, # call it instead. return sampling_rule.sample(**kwargs) elif isinstance(sampling_rule, dict): # If the ruleset is a dict, return a new dict with each # element being sampled from the original dict. out = {} for key, val in self.sampling_rule.items(): out[key] = self.sample(val, **kwargs) return out elif isinstance(sampling_rule, list): return [self.sample(item, **kwargs) for item in sampling_rule] elif isinstance(sampling_rule, (tuple, np.ndarray)): # tuple and ndarrays are elementary return sampling_rule elif isiterable(sampling_rule): # If it's iterable, return the next value try: return next(sampling_rule) except StopIteration: return self.current_value elif callable(sampling_rule): # If it's a function function_input = {} for key in get_kwarg_names(sampling_rule): if key in kwargs: if isinstance(kwargs[key], Property): kwargs[key].update(**kwargs) if isinstance(kwargs[key], SequentialProperty): kwargs[key] = kwargs[key].current_value[kwargs["sequence_step"]] else: kwargs[key] = kwargs[key].current_value function_input[key] = kwargs[key] return sampling_rule(**function_input) else: # Else, assume it's elementary. return sampling_rule
def test_hasmethod(self): self.assertTrue(utils.hasmethod(utils, "hasmethod")) self.assertFalse( utils.hasmethod(utils, "this_is_definetely_not_a_method_of_utils"))