Browse Source

series type is now user defined

UserDict-trial
Gourav Kumar 2 years ago
parent
commit
e22f6acc87
  1. 57
      fincal/core.py

57
fincal/core.py

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

Loading…
Cancel
Save