Exemple #1
0
class PrintingNode(BaseNode['PrintingNode', Printing]):
    _children: FrozenMultiset[PrintingNodeChild]
    _CARDBOARD_EQUIVALENT = CardboardNode

    flattened: t.Iterator[t.Union[Printing, AnyNode]]
    flattened_options: t.Iterator[FrozenMultiset[Printing]]

    def __init__(
        self,
        children: t.Union[
            t.Iterable[PrintingNodeChild],
            t.Mapping[PrintingNodeChild, int]
        ],
    ):
        self._children = FrozenMultiset(children)

    @property
    def children(self) -> FrozenMultiset[PrintingNodeChild]:
        return self._children

    def _calc_persistent_hash(self) -> t.Iterable[t.ByteString]:
        yield self.__class__.__name__.encode('UTF-8')
        for s in sorted(
            child.persistent_hash()
            if isinstance(child, BaseNode) else
            str(child.id)
            for child in
            self._children
        ):
            yield s.encode('ASCII')

    @property
    def as_cardboards(self) -> CardboardNode:
        return self._CARDBOARD_EQUIVALENT(
            child.cardboard
            if isinstance(child, Printing) else
            child.as_cardboards
            for child in
            self._children
        )

    def get_minimal_string(self, identified_by_id: bool = True) -> str:
        return self._MINIMAL_STRING_CONNECTOR.join(
            (
                '({})'.format(
                    (f'{multiplicity}# ' if multiplicity > 1 else '')
                    + f'{child.cardboard.name}|{child.id if identified_by_id else child.expansion.code}'
                    if isinstance(child, Printing) else
                    f'{child.get_minimal_string(identified_by_id)}'
                )
                for child, multiplicity in
                self.sorted_items
            )
        )

    @LazyProperty
    def name(self):
        return ''.join(
            (
                str(multiplicity) + 'x'
                if multiplicity > 1 else
                ''
            )
            + (
                option.cardboard.name
                if isinstance(option, Printing) else
                '{} {}'.format(
                    option.name,
                    option.__class__.__name__,
                )
            )
            for option, multiplicity in
            self.sorted_items
        )

    @LazyProperty
    def sorted_items(self) -> t.List[t.Tuple[PrintingNodeChild, int]]:
        return sorted(
            self._children.items(),
            key = lambda p:
            p[0].cardboard.name
            if isinstance(p[0], Printing) else
            p[0].name
        )

    @property
    def imageds(self) -> t.Iterator[t.Union[Printing, PrintingNode]]:
        return itertools.chain(
            *(
                itertools.repeat(item, 1 if isinstance(item, Printing) else multiplicity)
                for item, multiplicity in
                self._children.items()
            )
        )

    @LazyProperty
    def sorted_imageds(self) -> t.List[PrintingNodeChild]:
        return sorted(
            list(self.imageds),
            key = lambda p:
            p.cardboard.name
            if isinstance(p, Printing) else
            p.name
        )

    @LazyProperty
    def sorted_uniques(self) -> t.List[PrintingNodeChild]:
        return sorted(
            self._children.distinct_elements(),
            key = lambda p:
            p.cardboard.name
            if isinstance(p, Printing) else
            p.name
        )

    @abstractmethod
    def get_image(self, loader: ImageLoader, width: int, height: int, **kwargs) -> Image.Image:
        pass

    @classmethod
    def deserialize(cls, value: serialization_model, inflator: Inflator) -> PrintingNode:
        return (
            AnyNode
            if value['type'] == AnyNode.__name__ else
            AllNode
        )(

            {
                (
                    inflator.inflate(Printing, child)
                    if isinstance(child, int) else
                    cls.deserialize(child, inflator)
                ):
                    multiplicity
                for child, multiplicity
                in value['options']
            }
        )

    @property
    def image_amount(self) -> int:
        return sum(
            1 if isinstance(child, Printing) else multiplicity * child.image_amount
            for child, multiplicity in
            self._children.items()
        )
Exemple #2
0
class CardboardNode(BaseNode['CardboardNode', Cardboard]):
    flattened: t.Iterator[t.Union[Cardboard, CardboardAnyNode]]
    flattened_options: t.Iterator[FrozenMultiset[Cardboard]]

    def __init__(
        self,
        children: t.Union[
            t.Iterable[CardboardNodeChild],
            t.Mapping[CardboardNodeChild, int]
        ],
    ):
        self._children = FrozenMultiset(children)

    @property
    def sorted_items(self) -> t.List[t.Tuple[CardboardNodeChild, int]]:
        return sorted(
            self._children.items(),
            key = lambda p: p[0].name,
        )

    def get_minimal_string(self, **kwargs) -> str:
        return self._MINIMAL_STRING_CONNECTOR.join(
            (
                '({})'.format(
                    (f'{multiplicity}# ' if multiplicity > 1 else '')
                    + child.name
                    if isinstance(child, Cardboard) else
                    f'{child.get_minimal_string()}'
                )
                for child, multiplicity in
                self.sorted_items
            )
        )

    @property
    def children(self) -> FrozenMultiset[CardboardNodeChild]:
        return self._children

    @property
    def name(self) -> str:
        return ''.join(
            (
                str(multiplicity) + 'x'
                if multiplicity > 1 else
                ''
            )
            + (
                option.name
                if isinstance(option, Cardboard) else
                '{} {}'.format(
                    option.name,
                    option.__class__.__name__,
                )
            )
            for option, multiplicity in
            self.sorted_items
        )

    def _calc_persistent_hash(self) -> t.Iterable[t.ByteString]:
        yield self.__class__.__name__.encode('UTF-8')
        for s in sorted(
            child.persistent_hash()
            if isinstance(child, BaseNode) else
            str(child.id)
            for child in
            self._children
        ):
            yield s.encode('UTF-8')

    @classmethod
    def deserialize(cls, value: serialization_model, inflator: Inflator) -> CardboardNode:
        return (
            CardboardAnyNode
            if value['type'] == CardboardAnyNode.__name__ else
            CardboardAllNode
        )(

            {
                (
                    inflator.inflate(Cardboard, child)
                    if isinstance(child, str) else
                    cls.deserialize(child, inflator)
                ):
                    multiplicity
                for child, multiplicity
                in value['options']
            }
        )