Passed
Push — datapoints-package ( a11eff...a54cf8 )
by Konstantinos
02:20
created

DatapointsManager.datapoints()   A

Complexity

Conditions 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
"""Defines the DatapointsManager type (class); a centralized facility where all
2
datapoints objects should arrived and be retrieved from."""
3
import attr
4
from typing import Iterable, Optional
5
from so_magic.utils import Observer, Subject
6
7
8
@attr.s
9
class DatapointsManager(Observer):
10
    """Manage operations revolved around datapoints collection objects.
11
12
    Instances of this class are able to monitor (listener/observer pattern) the creation of 
13
    datapoints collection objects and store them in a dictionary structure. 
14
    They also provide retrieval methods to the client to "pick up" a datapoints object.
15
16
    Args:
17
        datapoints_objects (dict, optional): the initial structure that stores datapoints objects
18
    """
19
    datapoints_objects = attr.ib(init=True, default={})
20
    _last_key = attr.ib(init=False, default='')
21
22
    def update(self, subject: Subject):
23
        """Update our state based on the event/observation captured/made.
24
25
        Stores the datapoints object observed in a dictionary using a the Subject
26
        name attribute as key.
27
28
        Args:
29
            subject (Subject): the subject object observed; it acts as an event
30
31
        Raises:
32
            RuntimeError: in case there is no 'name' attribute on the subject or if it is an empty string ''
33
            RuntimeError: in case the 'name' attribute on the subject has already been used to store a datapoints object
34
        """
35
        datapoints_object = subject.state
36
        key = getattr(subject, 'name', '')
37
        if key == '':
38
            raise RuntimeError(f"Subject {subject} with state {str(subject.state)} resulted in an empty string as key (to use in dict/hash).")
39
        if key in self.datapoints_objects:
40
            raise RuntimeError(f"Attempted to register a new Datapoints object at the existing key '{key}'.")
41
        self.datapoints_objects[key] = datapoints_object
42
        self._last_key = key
43
44
    @property
45
    def state(self):
46
        """The latest (most recent) key used to store a datapoints object.
47
48
        Returns:
49
            str: the key under which we stored a datapoints object last time
50
        """
51
        return self._last_key
52
53
    @property
54
    def datapoints(self) -> Optional[Iterable]:  # indicates that the method can return an Iterable or None types
55
        """The most recently stored datapoints object.
56
57
        Returns:
58
            Optional[Iterable]: the reference to the datapoints object
59
        """
60
        try:
61
            return self.datapoints_objects[self._last_key]
62
        except KeyError as e:
63
            print(f"{e}. Requested datapoints with id '{self._last_key}', but was not found in registered [{', '.join(_ for _ in self.datapoints_objects.keys())}]")
64