Source code for iode.time.period

import sys
import warnings
from typing import Union, Tuple, List, Any
if sys.version_info.minor >= 11:
    from typing import Self
else:
    Self = Any

from iode.common import PeriodICITY_LIST
from iode.iode_cython import Period as CythonPeriod


[docs] class Period:
[docs] def __init__(self, period_or_year: Union[str, int, Self], periodicity: str='Y', step: int=1) -> Self: r""" An IODE period is defined by a year, a periodicity and by a position in the year. Possible values for the periodicity are: - Y: yearly - S: semestrial - Q: quarterly - M: monthly - W: weekly - D: daily Parameters ---------- period_or_year: str or int If str, it is consided as a string representing the year, the periodicity and the position of the period in the year (step). If int, it is considered as the year of the period. periodicity: str, optional Periodicity of the period. Possible values are 'Y', 'S', 'Q', 'M', 'W' and 'D'. Default to 'Y' (yearly). step: int, optional Position of the period in the year. Default to 1. Attributes ---------- year: int periodicity: str step: int position in the year Examples -------- >>> from iode import Period >>> # passing a string >>> period = Period("2000Y1") >>> period Period("2000Y1") >>> # passing year, periodicity and step >>> period = Period(2010, 'Q', 1) >>> period Period("2010Q1") >>> # passing only year >>> period = Period(2010) >>> period Period("2010Y1") >>> # passing year and periodicity >>> period = Period(2010, 'Q') >>> period Period("2010Q1") >>> # copy a period >>> period_2 = Period(period) >>> period_2 Period("2010Q1") """ if isinstance(period_or_year, Period): period = period_or_year self._cy_period = CythonPeriod(period.year, period.periodicity, period.step) elif isinstance(period_or_year, str): period = period_or_year self._cy_period = CythonPeriod(period) elif isinstance(period_or_year, int): year = period_or_year if len(periodicity) != 1: raise ValueError("'periodicity': Expected string of length 1") if periodicity not in PeriodICITY_LIST: raise ValueError(f"Wrong periodicity. Valid values for the periodicity are: {', '.join(PeriodICITY_LIST)}") self._cy_period = CythonPeriod(year, periodicity, step)
@classmethod def from_cython_obj(cls, obj: CythonPeriod) -> Self: instance = cls.__new__(cls) instance._cy_period = obj return instance @property def nb_periods_per_year(self) -> int: r""" Number of periods in a year according to the periodicity. Examples -------- >>> from iode import Period >>> period = Period(2010, 'Q', 1) >>> period.nb_periods_per_year 4 """ return self._cy_period.get_nb_periods_per_year()
[docs] def difference(self, other: Self) -> int: r""" Number of sub periods between two periods. The two periods must have the same periodicity. Parameters ---------- other: Period Returns ------- int Examples -------- >>> from iode import Period >>> period = Period(2000, 'Q', 1) >>> period_2 = Period(2001, 'Q', 3) >>> period.difference(period_2) -6 >>> period_2.difference(period) 6 """ return self._cy_period.difference(other._cy_period)
[docs] def shift(self, nb_periods: int) -> Self: r""" Shift the current period by a number of sub periods. If the number of sub periods is positive, the shift is time forward. Conversely, if the number of sub periods is negative, the shift is time backward. Parameters ---------- nb_periods: int Number of sub periods. The shift is time forward if positive and time backward if negative. Returns ------- shifted_period: Period Examples -------- >>> from iode import Period >>> period = Period(2000, 'Q', 1) >>> period Period("2000Q1") >>> # shift forward >>> shifted_period = period.shift(7) >>> shifted_period Period("2001Q4") >>> # shift backward >>> shifted_period = period.shift(-7) >>> shifted_period Period("1998Q2") """ cy_period: CythonPeriod = self._cy_period.shift(nb_periods) shifted_per = Period.from_cython_obj(cy_period) return shifted_per
@property def year(self) -> int: r""" Corresponding year of the period Examples -------- >>> from iode import Period >>> period = Period(2000, 'Q', 3) >>> period.year 2000 """ return self._cy_period.get_year() @property def periodicity(self) -> str: r""" Possible values are: - Y: yearly - S: semestrial - Q: quarterly - M: monthly - W: weekly - D: daily Examples -------- >>> from iode import Period >>> period = Period(2000, 'Q', 3) >>> period.periodicity 'Q' """ return self._cy_period.get_periodicity() @property def step(self) -> int: r""" Position of the period in the year Examples -------- >>> from iode import Period >>> period = Period(2000, 'Q', 3) >>> period.step 3 """ return self._cy_period.get_step() def __eq__(self, other: Self) -> bool: if not isinstance(other, Period): warnings.warn(f"Comparing '{self}' with '{other}' is not supported", UserWarning) return False return self._cy_period.__eq__(other._cy_period)
[docs] def __float__(self) -> float: r""" Returns a float representation of the period. Returns ------- float Examples -------- >>> from iode import Period >>> period = Period(2000, 'Q', 1) >>> float(period) 2000.0 >>> period = Period(2000, 'Q', 3) >>> float(period) 2000.5 """ return float(self._cy_period)
def __lt__(self, other: Self) -> bool: if not isinstance(other, Period): warnings.warn(f"Comparing '{self}' with '{other}' is not supported", UserWarning) return False return float(self) < float(other) def __gt__(self, other: Self) -> bool: if not isinstance(other, Period): warnings.warn(f"Comparing '{self}' with '{other}' is not supported", UserWarning) return False return float(self) > float(other) def __le__(self, other: Self) -> bool: if not isinstance(other, Period): warnings.warn(f"Comparing '{self}' with '{other}' is not supported", UserWarning) return False if self == other: return True else: return self < other def __ge__(self, other: Self) -> bool: if not isinstance(other, Period): warnings.warn(f"Comparing '{self}' with '{other}' is not supported", UserWarning) return False if self == other: return True else: return self > other def __str__(self) -> str: if self.year == 0: return "" else: return f"{self.year}{self.periodicity}{self.step}" def __repr__(self) -> str: if self.year == 0: return "" else: return f'Period("{self.year}{self.periodicity}{self.step}")'