series type is now user defined

This commit is contained in:
Gourav Kumar 2022-02-21 22:27:26 +05:30
parent 59c9c658ca
commit e22f6acc87

View File

@ -2,7 +2,7 @@ import datetime
from collections import UserDict, UserList from collections import UserDict, UserList
from dataclasses import dataclass from dataclasses import dataclass
from numbers import Number from numbers import Number
from typing import Iterable, List, Literal, Mapping, Sequence, Tuple, Union from typing import Iterable, List, Literal, Mapping, Sequence, Tuple, Type, Union
@dataclass @dataclass
@ -132,30 +132,26 @@ class _IndexSlicer:
class Series(UserList): class Series(UserList):
def __init__(self, data): """Container for a series of objects, all objects must be of the same type"""
if not isinstance(data, Sequence):
raise TypeError("Series only supports creation using Sequence types")
if isinstance(data[0], bool): def __init__(
self.data = data self,
self.dtype = bool data,
elif isinstance(data[0], Number): data_type: Union[Type[bool], Type[float], Type[str], Type[datetime.datetime]],
self.dtype = float date_format: str = None,
self.data = [float(i) for i in data] ):
elif isinstance(data[0], str): self.dtype = data_type
try: if not isinstance(data, Sequence):
data = [datetime.datetime.strptime(i, FincalOptions.date_format) for i in data] raise TypeError("Series object can only be created using Sequence types")
self.dtype = datetime.datetime
except ValueError: for i in data:
raise TypeError( if not isinstance(i, data_type):
"Series does not support string data type except dates.\n" raise Exception("All arguments must be of the same type")
"Hint: Try setting the date format using FincalOptions.date_format"
) if data_type == str:
elif isinstance(data[0], (datetime.datetime, datetime.date)): data = [_parse_date(i, date_format) for i in data]
self.dtype = datetime.datetime
self.data = [_parse_date(i) for i in data] self.data = data
else:
raise TypeError(f"Cannot create series object from {type(data).__name__} of {type(data[0]).__name__}")
def __repr__(self): def __repr__(self):
return f"{self.__class__.__name__}({self.data})" return f"{self.__class__.__name__}({self.data})"
@ -168,7 +164,7 @@ class Series(UserList):
other = _parse_date(other) other = _parse_date(other)
if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype): if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype):
gt = Series([i > other for i in self.data]) gt = Series([i > other for i in self.data], bool)
else: else:
raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}") raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}")
@ -179,14 +175,14 @@ class Series(UserList):
raise TypeError("< not supported for boolean series") raise TypeError("< not supported for boolean series")
if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype): if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype):
lt = Series([i < other for i in self.data]) lt = Series([i < other for i in self.data], bool)
else: else:
raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}") raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}")
return lt return lt
def __eq__(self, other): def __eq__(self, other):
if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype): if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype):
eq = Series([i == other for i in self.data]) eq = Series([i == other for i in self.data], bool)
else: else:
raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}") raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}")
return eq return eq
@ -234,14 +230,14 @@ class TimeSeriesCore(UserDict):
if self._dates is None or len(self._dates) != len(self.data): if self._dates is None or len(self._dates) != len(self.data):
self._dates = list(self.data.keys()) self._dates = list(self.data.keys())
return Series(self._dates) return Series(self._dates, datetime.datetime)
@property @property
def values(self): def values(self):
if self._values is None or len(self._values) != len(self.data): if self._values is None or len(self._values) != len(self.data):
self._values = list(self.data.values()) self._values = list(self.data.values())
return Series(self._values) return Series(self._values, float)
@property @property
def start_date(self): def start_date(self):
@ -326,9 +322,6 @@ class TimeSeriesCore(UserDict):
raise TypeError(f"Invalid type {repr(type(key).__name__)} for slicing.") raise TypeError(f"Invalid type {repr(type(key).__name__)} for slicing.")
return item return item
def __len__(self):
return len(self.data)
def __iter__(self): def __iter__(self):
self.n = 0 self.n = 0
return self return self