Passed
Push — dev ( 6a1e3c...3c73d5 )
by Konstantinos
01:31
created

green_magic.data.dataset.TabularData.nb_columns()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
import os
2
import attr
3
from green_magic.utils import Observer, Subject
4
5
6
@attr.s(str=True, repr=True)
7
class Dataset:
8
    datapoints = attr.ib(init=True)
9
    name = attr.ib(init=True, default=None)
10
11
    _features = attr.ib(init=True, default=[])
12
    handler = attr.ib(init=True, default=None)
13
    size = attr.ib(init=False, default=attr.Factory(lambda self: len(self.datapoints) if self.datapoints else 0, takes_self=True))
14
15
    @property
16
    def features(self):
17
        return self._features
18
19
    @features.setter
20
    def features(self, features):
21
        self._features = features
22
23
    # @classmethod
24
    # def from_file(cls, file_path, name):
25
    #     return Dataset(Datapoints.from_file(file_path), name)
26
27
from abc import ABC, abstractmethod
28
29
class DatapointsInterface(ABC):
30
    """The Datapoints interface gives access to the 'observations' property."""
31
    @property
32
    @abstractmethod
33
    def observations(self):
34
        raise NotImplementedError
35
36
class StructuredDataInterface(ABC):
37
    @property
38
    @abstractmethod
39
    def attributes(self):
40
        raise NotImplementedError
41
42
43
class DatapointsFactory:
44
    constructors = {}
45
46
    @classmethod
47
    def register_constructor(cls, name):
48
        def wrapper(subclass):
49
            cls.constructors[name] = subclass
50
            return subclass
51
        return wrapper
52
53
    @classmethod
54
    def create(cls, name, *args, **kwargs) -> DatapointsInterface:
55
        if name not in cls.constructors:
56
            raise ValueError(
57
                f"Request Engine of type '{name}'; supported are [{', '.join(sorted(cls.constructors.keys()))}]")
58
        return cls.constructors[name](*args, **kwargs)
59
60
61
class BroadcastingDatapointsFactory(DatapointsFactory):
62
    subject = Subject()
63
64
    @classmethod
65
    def create(cls, name, *args, **kwargs) -> DatapointsInterface:
66
        cls.subject.state = super().create(name, *args, **kwargs)
67
        cls.subject.name = kwargs.get('id', kwargs.get('name', ''))
68
        if args and not hasattr(cls, '.name'):
69
            cls.name = getattr(args[0], 'name', '')
70
        cls.subject.notify()
71
        return cls.subject.state
72
73
74
@attr.s
75
@DatapointsFactory.register_constructor('structured-data')
76
class StructuredData(DatapointsInterface, StructuredDataInterface):
77
    """Structured data. There are specific attributes/variables per observation.
78
79
    Args:
80
        observations (object): a reference to an object that encapsulates structured data
81
    """
82
    _observations = attr.ib(init=True)
83
    _attributes = attr.ib(init=True, converter=lambda input_value: [x for x in input_value])
84
85
    @property
86
    def attributes(self):
87
        return self._attributes
88
89
    @property
90
    def observations(self):
91
        return self._observations
92
93
@attr.s
94
@DatapointsFactory.register_constructor('tabular-data')
95
class TabularData(StructuredData):
96
    """Table-like datapoints that are loaded in memory"""
97
    retriever = attr.ib(init=True)
98
    iterator = attr.ib(init=True)
99
100
    def column(self, identifier):
101
        return self.retriever.column(identifier, self)
102
103
    def row(self, identifier):
104
        return self.retriever.row(identifier, self)
105
106
    @property
107
    def nb_columns(self):
108
        return self.retriever.nb_columns(self)
109
110
    @property
111
    def nb_rows(self):
112
        return self.retriever.nb_rows(self)
113
114
    def __len__(self):
115
        return self.retriever.nb_rows(self)
116
117
    def __iter__(self):
118
        return self.iterator.iterrows(self)
119
120
    def iterrows(self):
121
        return self.iterator.iterrows(self)
122
123
    def itercolumns(self):
124
        return self.iterator.itercolumns(self)
125
126
127
@attr.s
128
class DatapointsManager(Observer):
129
    datapoints_objects = attr.ib(init=True, default={})
130
    _last_key = attr.ib(init=False, default='')
131
132
    def update(self, subject: Subject):
133
        datapoints_object = subject.state
134
        key = getattr(subject, 'name', '')
135
        print(type(datapoints_object))
136
        print(dir(subject))
137
        print(dir(subject.state))
138
        if key in self.datapoints_objects:
139
            raise RuntimeError(f"Attempted to register a new Datapoints object at the existing key '{key}'.")
140
        self.datapoints_objects[key] = datapoints_object
141
        self._last_key = key
142
143
    @property
144
    def state(self):
145
        return self._last_key
146
147
    @property
148
    def datapoints(self):
149
        try:
150
            return self.datapoints_objects[self._last_key]
151
        except KeyError as e:
152
            print(f"{e}. Requested datapoints with id '{self._last_key}', but was not found in registered [{', '.join(_ for _ in self.datapoints_objects.keys())}]")
153