Source code for time_split.settings

"""Global settings for the splitting logic."""

import typing as _t

import pandas as _pd

from . import types as _tst


[docs] class auto_expand_limits: # noqa: N801 """Configuration for the `'auto'` :attr:`~time_split.types.ExpandLimits` logic. This class determines how ``(min, max)``-tuples are expanded when expanded limits are enabled. """ SANITY_CHECK: bool = True """If ``True``, use original limits if expanded limits do not pass sanity checks."""
[docs] @classmethod def set_level( cls, level: _t.Literal["hour", "day"], *, start_at: _tst.TimedeltaTypes, round_to: _tst.TimedeltaTypes, tolerance: _tst.TimedeltaTypes, ) -> None: """Set a :class:`Level` used by the auto-expand_limits logic. Inputs are not verified until an actual split is made. Args: level: The level to set; `'hour'` or `'day'`. start_at: Span size at which this level starts. round_to: Frequency to round the range limits to. tolerance: Maximum amount by which to alter limits. Raises: AttributeError: For unknown `level` names. """ if level not in {"hour", "day"}: raise AttributeError(f"Bad {level=}: Expected one of ('hour', 'day').") level_tuple = (start_at, round_to, tolerance) setattr(cls, level, level_tuple)
[docs] class Level(_t.NamedTuple): """Level type used by :attr:`auto_expand_limits`.""" start_at: _tst.TimedeltaTypes """Span size at which this level starts.""" round_to: _tst.TimedeltaTypes """Frequency to round the range limits to.""" tolerance: _tst.TimedeltaTypes """Maximum amount by which to alter limits."""
hour: Level = Level("6 hours", "hour", "15 min") """Conditions under which bounds are rounded to the nearest hour. Default setting: Round to hour if the total range is at least 6 hours, but do not move the bounds more than 15 minutes. """ day: Level = Level("2 days", "day", "3 hours") """Conditions under which bounds are rounded to the nearest day. Default setting: Round to day if the total range is at least 2 days, but do not move the bounds more than 3 hours. """
[docs] class plot: # noqa: N801 """Global settings for the :func:`.time_split.plot`-function.""" THOUSANDS_SEPARATOR: str = "'" """Separator to use when printing `bar_labels`.""" THOUSANDS_SEPARATOR_CUTOFF: int = 10_000 """Minimum value before `bar_labels` include a :attr:`THOUSANDS_SEPARATOR`.""" ROW_UNIT: str = "rows" """Unit to append to the count when displaying number of rows on the bars.""" DATA_LABEL: str = "Data" """Label of the blue bar; data in the the [:attr:`~.DatetimeSplitBounds.start`, :attr:`~.types.DatetimeSplitBounds.mid`)-range.""" FUTURE_DATA_LABEL: str = "Future data" """Label of the red bar; data in the the [:attr:`~.DatetimeSplitBounds.mid`, :attr:`~.types.DatetimeSplitBounds.end`)-range.""" DEFAULT_TIME_UNIT: str = "hours" """Time unit to use by default when ``bar_labels=True`` and ``available=None`` or a limits tuple.""" REMOVED_FOLD_STYLE: _t.ClassVar[dict[str, _t.Any]] = { "alpha": 0.35, "height": 0.6, } """Keyword arguments used to distinguish filtered folds when plotting with ``show_removed=True``. See :func:`matplotlib.pyplot.bar` for details. """
[docs] class log_split_progress: # noqa: N801 """Global settings for the :func:`.log_split_progress`-function.""" FOLD_FORMAT: str = "'{start.auto}' <= [schedule: '{mid.auto}' ({mid:%A})] < '{end.auto}'" """Pretty-printed `fold`-key for other messages. * Only the ``start``, ``mid``, and ``end`` keys are available (see :attr:`~time_split.types.DatetimeSplitBounds`). You may use ``<key>.auto`` to format as a date when time is zero (this is the default). .. code-block:: python :caption: Sample output. '2021-12-30' <= [schedule: '2022-01-04' (Tuesday)] < '2022-01-04 18:00:00' """ SECONDS_FORMATTER: _t.Callable[[float], str] | None = None """A callable ``(seconds) -> formatted_seconds``. Use :func:`rics.strings.format_seconds` if ``None``. Both ``seconds`` and ``formatted_seconds`` will be available to the :attr:`END_MESSAGE` message. """ START_MESSAGE: str = "Begin fold {n}/{n_splits}: {fold}." """Message indicating that the current fold has been yielded to the user. Has access to all keys from the previous section, as well as: * The ``fold`` key (see :attr:`FOLD_FORMAT`), and * The ``n`` key, which is the 1-based position of the fold in `splits`, and * The ``n_folds`` key, which is just ``len(splits)``. .. code-block:: python :caption: Sample output. Begin fold 5/7: '2021-12-30' <= [schedule: '2022-01-04' (Tuesday)] < '2022-01-04 18:00:00'. """ END_MESSAGE: str = "Finished fold {n}/{n_splits}: [schedule: '{mid.auto}' ({mid:%A})] after {formatted_seconds}." """Message indicating that the user is done with the current fold. Has access to all keys from the previous sections, as well as: * The ``seconds`` key, which is the (fractional) time the user spent in the fold, and * The ``formatted_seconds`` key, obtained using the :attr:`SECONDS_FORMATTER`. The value of ``seconds`` is obtained using :py:func:`time.perf_counter`. .. code-block:: python :caption: Sample output. Finished fold 5/7: [schedule: '2022-01-04' (Tuesday)] after 5m 21s. """ AUTO_DATE_FORMAT = "%Y-%m-%d" """Short-form timestamp format_spec used by ``<key>.auto``.""" AUTO_DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S" """Long-form timestamp format_spec used by ``<key>.auto``.""" FORMAT_METRICS: _tst.FormatMetrics[_t.Any] | None = None """A callable ``(end_message, metrics) -> str``. Use the :func:`default formatter <.support.default_metrics_formatter>` if ``None``."""
[docs] class misc: # noqa: N801 """Miscellaneous settings that don't fit in any other namespace.""" snap_to_end: bool = True """Controls alignment of timedelta-based splits. .. note:: Active only when both `schedule` and `after` are :attr:`~time_split.types.TimedeltaTypes`. If ``True``, ensure that the `Future data` of the final fold ends at the rightmost edge of the available data range. Otherwise, alignment is determined by :func:`pandas.date_range`. """ filter: _t.Callable[[_pd.Timestamp, _pd.Timestamp, _pd.Timestamp], bool] | None = None """A callable ``(start, mid, end) -> bool`` applied to all generated folds."""