I am wondering if there are patterns, references or useful resources about how to implement objects that may have several equivalent representations. For example:
Suppose I want to implement a
Rectangle, and I will instantiate it using its
class Rectangle: def __init__(self, length, width): self.length = length self.width = width
and suppose now I also want to have the possibility to instantiate the
Rectangle using its
area. My main concern is that I don't want to store redundant information in the object (in this case, these four properties), only the bare minimum possible to define it.
Suppose too I might want to retrieve one set of properties having created the
Rectangle using another:
r = Rectangle(length=3, width=4) assert r.diagonal == 5
This is what I've tried so far:
class Rectangle: def __init__(self, **kwargs): params = set(kwargs.keys()) if params == set(['length', 'width']): self._length = kwargs['length'] self._width = kwargs['width'] elif params == set(['area', 'diagonal']): self._area = kwargs['area'] self._diagonal = kwargs['diagonal'] else: raise ValueError('Invalid input arguments') @property def length(self): if hasattr(self, '_length'): return self._length elif hasattr(self, '_area') and hasattr(self, '_diagonal'): length, width = ad2lw(self._area, self._diagonal) #r = Rectangle(length=length, width=width) #return r._length return length else: raise NotImplementedError('No converter available') # Same with other three properties def ad2lw(area, diagonal): # Obscure math return l, w
Is this any known pattern or is there a standard way to do it?