Source code for mutwo.generators.edwards

"""Algorithms which are related to British composer Michael Edwards."""

import functools
import itertools
import operator

from mutwo.generators import edwards_constants
from mutwo.utilities import tools

__all__ = ("ActivityLevel",)


[docs]class ActivityLevel(object): """Python implementation of Michael Edwards activity level algorithm. :param start_at: from which pattern per level shall be started (can be either 0, 1 or 2) Activity Levels is a concept derived from Michael Edwards. Quoting Michael Edwards, Activity Levels are an `"object for determining (deterministically) on a call-by-call basis whether a process is active or not (boolean). This is determined by nine 10-element lists (actually three versions of each) of hand-coded 1s and 0s, each list representing an 'activity-level' (how active the process should be). The first three 10-element lists have only one 1 in them, the rest being zeros. The second three have two 1s, etc. Activity-levels of 0 and 10 would return never active and always active respectively." <https://michael-edwards.org/sc/robodoc/activity-levels_lsp.html#robo23>`_. **Example:** >>> from mutwo.generators import edwards >>> activity_levels = edwards.ActivityLevel() >>> activity_levels(0) # activity level 0 will always return False False >>> activity_levels(10) # activity level 10 will always return True True >>> activity_levels(7) # activity level 7 will mostly return True True >>> tuple(activity_levels(7) for _ in range(10)) (True, False, True, True, False, True, True, False, True, True) """ _allowed_range = tuple(range(len(edwards_constants.ACTIVITY_LEVELS))) def __init__(self, start_at: int = 0) -> None: try: assert start_at in (0, 1, 2) except AssertionError: msg = "start_at has to be either 0, 1 or 2 and not {}, ".format(start_at) msg += "because there are only three different tuples defined per level." raise ValueError(msg) self._activity_level_cycles = tuple( itertools.cycle( functools.reduce( operator.add, tuple(tools.cyclic_permutations(levels))[start_at] ) ) for levels in edwards_constants.ACTIVITY_LEVELS ) def __repr__(self) -> str: return "ActivityLevel()"
[docs] def __call__(self, level: int) -> bool: """Return current state (is active or not) of entered activity level. :param level: the activity-level which current state shall be returned (should be from 0 to 10) :return: True if active and False if not active. """ try: assert level in self._allowed_range except AssertionError: msg = "level is '{}' but has to be in range '{}'!".format( level, self._allowed_range ) raise ValueError(msg) return bool(next(self._activity_level_cycles[level]))