smok-serwis/firanka

View on GitHub
firanka/series/bundle.py

Summary

Maintainability
A
45 mins
Test Coverage
import functools
import logging

from sortedcontainers import SortedSet, SortedList

logger = logging.getLogger(__name__)

from .base import Series, DiscreteSeries
from ..intervals import REAL_SET


class SeriesBundle(Series):
    """
    Bundles a bunch of series together, returning a list from their outputs
    """

    def __init__(self, *series):
        domain = functools.reduce(lambda x, y: x.intersection(y),
                                  (p.domain for p in series),
                                  REAL_SET)

        super().__init__(domain)

        self.series = series

    def _get_for(self, item):
        return [s._get_for(item) for s in self.series]


class DiscreteSeriesBundle(SeriesBundle):
    def __init__(self, *series):
        """
        :raise TypeError: if not all series are discrete
        """
        super().__init__(*series)

        if any((not isinstance(s, DiscreteSeries)) for s in series):
            raise TypeError('All series must be discrete')

    def compose(self):
        """
        Return a DiscreteSet from multiple bunded series.
        This does not lose accuracy.

        If you use any fancy classes based from DiscreteSeries,
        their functionality WILL BE LOST.
        """
        keys = SortedSet()

        for s in self.series:
            for k, v in s.data:
                keys.add(k)

        data = SortedList()
        for k in keys:
            v = self._get_for(k)
            if len(data) > 0 and data[-1][1] == v:
                continue
            else:
                data.add((k, v))

        return DiscreteSeries([(k, self._get_for(k)) for k in keys], self.domain)