import random
from bibliopixel.animation.animation import Animation
[docs]class Random(Animation):
"""
Randomly set the color
"""
def __init__(self, *args, distribution=None, every=0, count=0, levels=None,
**kwds):
super().__init__(*args, **kwds)
self.distribution = Distribution(**(distribution or {}))
self.count = count
self.every = every
self.levels = levels or [1, 1, 1]
[docs] def step(self, amt=1):
if not (self.every and self.cur_step % self.every):
indexes = range(len(self.color_list))
if self.count:
indexes = random.sample(indexes, self.count)
d = self.distribution
r, g, b = self.levels
for i in indexes:
self.color_list[i] = (r * d(), g * d(), b * d())
[docs]class Distribution:
MEMBERS = 'name', 'scale', 'vars'
def __init__(self, name='triangular', **kwds):
self.name = name
for k, v in kwds.items():
setattr(self, k, v)
def __call__(self):
return self.scale * self._function(**self._kwds)
def __getattribute__(self, key):
if key.startswith('_') or key in Distribution.MEMBERS:
return super().__getattribute__(key)
elif key in self._kwds:
return self._kwds[key]
else:
self._bad_key(key)
def __setattr__(self, key, value):
if key.startswith('_') or key in Distribution.MEMBERS:
super().__setattr__(key, value)
elif key in self._kwds:
self._kwds[key] = value
else:
self._bad_key(key)
def _bad_key(self, key):
params = ', '.join(sorted(self._kwds))
raise AttributeError(UNKNOWN_FIELD_ERROR % (params, key))
def __dir__(self):
return ['name', 'scale'] + list(self._kwds)
[docs] def vars(self):
return {k: getattr(self, k) for k in dir(self)}
@property
def name(self):
return self._function.__name__
@name.setter
def name(self, name):
dist = _Distribution.get(name)
self.scale = dist.scale
self._kwds = dict(dist.kwds)
self._function = dist.function
class _Distribution:
DISTRIBUTIONS = {}
def __init__(self, name, scale, **kwds):
self.function = getattr(random, name)
self.scale = scale
self.kwds = kwds
self.DISTRIBUTIONS[name] = self
@classmethod
def get(cls, name):
dist = cls.DISTRIBUTIONS.get(name)
if dist:
return dist
else:
raise ValueError(NOT_DISTRIBUTION_FUNCTION_ERROR % name)
_Distribution('betavariate', 256, alpha=1, beta=1)
_Distribution('expovariate', 256, lambd=0.5)
_Distribution('gauss', 1, mu=128, sigma=32)
_Distribution('lognormvariate', 3, mu=1, sigma=1)
_Distribution('normalvariate', 1, mu=128, sigma=32)
_Distribution('paretovariate', 1, alpha=1)
_Distribution('triangular', 1, low=0, high=256, mode=None)
_Distribution('uniform', 1, a=0, b=256)
_Distribution('vonmisesvariate', 42, mu=1, kappa=1)
_Distribution('weibullvariate', 32, alpha=1, beta=1)
NOT_DISTRIBUTION_FUNCTION_ERROR = """\
Function random.%s is not a distribution
Distribution functions are:
""" + ', '.join(_Distribution.DISTRIBUTIONS)
UNKNOWN_FIELD_ERROR = 'Expected one of function, %s, but got attribute "%s"'