Source code for machin.utils.helper_classes

import time


[docs]class Counter: def __init__(self, start=0, step=1): self._count = start self._start = start self._step = step
[docs] def count(self): """ Move counter forward by ``step`` """ self._count += self._step
[docs] def get(self): """ Get the internal number of counter. """ return self._count
[docs] def reset(self): """ Reset the counter. """ self._count = self._start
def __lt__(self, other): return self._count < other def __gt__(self, other): return self._count > other def __le__(self, other): return self._count <= other def __ge__(self, other): return self._count >= other def __eq__(self, other): return self._count == other def __repr__(self): return "%d" % self._count
[docs]class Switch: def __init__(self, state: bool = False): """ Args: state: Internal state, ``True`` for on, ``False`` for off. """ self._on = state
[docs] def flip(self): """ Inverse the internal state. """ self._on = not self._on
[docs] def get(self) -> bool: """ Returns: state of switch. """ return self._on
[docs] def on(self): """ Set to on. """ self._on = True
[docs] def off(self): """ Set to off. """ self._on = False
[docs]class Trigger(Switch):
[docs] def get(self): """ Get the state of trigger, will also set trigger to off. Returns: state of trigger. """ on = self._on if self._on: self._on = False return on
[docs]class Timer: def __init__(self): self._last = time.time()
[docs] def begin(self): """ Begin timing. """ self._last = time.time()
[docs] def end(self): """ Returns: Curent time difference since last ``begin()`` """ return time.time() - self._last
[docs]class Object: """ An generic object class, which stores a dictionary internally, and you can access and set its keys by accessing and seting attributes of the object. Attributes: data: Internal dictionary. """ def __init__(self, data=None, const_attrs=None): if data is None: data = {} if const_attrs is None: const_attrs = set() super(Object, self).__setattr__("const_attrs", const_attrs) super(Object, self).__setattr__("data", data) def __call__(self, *args, **kwargs): return self.call(*args, **kwargs)
[docs] def call(self, *args, **kwargs): """ the implementation of ``Object.__call__``, override it to customize call behavior. """ pass
def __getattr__(self, item): # This function will be called if python cannot find an attribute # Note: in order to make Object picklable, we must raise AttributeError # when looking for special methods, such that when pickler is looking # up a non-existing __getstate__ function etc, this class will # not return a None value because self.attr(item) will return None. if isinstance(item, str) and item[:2] == item[-2:] == '__': # skip non-existing special method lookups raise AttributeError("Failed to find attribute: {}" .format(item)) return self.attr(item) def __getitem__(self, item): return self.attr(item) def __setattr__(self, key, value): if (key != "data" and key != "attr" and key != "call" and key not in self.__dir__()): if key in self.const_attrs: raise RuntimeError("{} is const.".format(key)) self.attr(key, value, change=True) elif key == "call": super(Object, self).__setattr__(key, value) elif key == "data": if isinstance(value, dict): super(Object, self).__setattr__(key, value) else: raise ValueError("The data attribute must be a dictionary.") else: raise RuntimeError("You should not set the {} property of an " "Object. You can only set non-const keys " "in data and .data and .call attributes." .format(key)) def __setitem__(self, key, value): self.__setattr__(key, value)
[docs] def attr(self, item, value=None, change=False): if change: self.data[item] = value return self.data.get(item, None)