You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
masque/masque/traits/scalable.py

77 lines
1.4 KiB
Python

from typing import Self
from abc import ABCMeta, abstractmethod
from ..error import MasqueError
from ..utils import is_scalar
_empty_slots = () # Workaround to get mypy to ignore intentionally empty slots for superclass
class Scalable(metaclass=ABCMeta):
"""
Trait class for all scalable entities
"""
__slots__ = ()
#
# Methods
#
@abstractmethod
def scale_by(self, c: float) -> Self:
"""
Scale the entity by a factor
Args:
c: scaling factor
Returns:
self
"""
pass
class ScalableImpl(Scalable, metaclass=ABCMeta):
"""
Simple implementation of Scalable
"""
__slots__ = _empty_slots
_scale: float
""" scale factor for the entity """
#
# Properties
#
@property
def scale(self) -> float:
return self._scale
@scale.setter
def scale(self, val: float):
if not is_scalar(val):
raise MasqueError('Scale must be a scalar')
if not val > 0:
raise MasqueError('Scale must be positive')
self._scale = val
#
# Methods
#
def scale_by(self, c: float) -> Self:
self.scale *= c
return self
def set_scale(self, scale: float) -> Self:
"""
Set the sclae to a value
Args:
scale: absolute scale factor
Returns:
self
"""
self.scale = scale
return self