Source code for mutwo.common_generators.edwards
"""Algorithms which are related to British composer Michael Edwards."""
import functools
import itertools
import operator
from mutwo import common_generators
from mutwo import common_utilities
from mutwo import core_utilities
__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 = tuple(
range(len(common_generators.constants.ACTIVITY_LEVEL_TUPLE))
)
def __init__(self, start_at: int = 0) -> None:
if start_at not in (0, 1, 2):
raise common_utilities.InvalidStartAtValueError(start_at)
self._activity_level_cycle_tuple = tuple(
itertools.cycle(
functools.reduce(
operator.add,
tuple(core_utilities.cyclic_permutations(level_tuple))[start_at],
)
)
for level_tuple in common_generators.constants.ACTIVITY_LEVEL_TUPLE
)
def __repr__(self) -> str:
return "ActivityLevel()"
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.
"""
if level not in self._allowed_range_tuple:
raise common_utilities.InvalidActivityLevelError(
level, self._allowed_range_tuple
)
return bool(next(self._activity_level_cycle_tuple[level]))