# Path: lcs/Perception.py
# class Perception(collections.abc.Sequence):
#     """
#     Represents current state of the environment at given time instance.
#     By default each environment attribute is represented as `str` type.
#     """
# 
#     __slots__ = ['_items', 'oktypes']
# 
#     def __init__(self, observation, oktypes=(str,)):
#         assert all(type(e) in oktypes for e in observation)
#         self._items = tuple(observation)
# 
#     @classmethod
#     def empty(cls):
#         return cls([], oktypes=(None,))
# 
#     def __hash__(self):
#         return hash(self._items)
# 
#     def __getitem__(self, i):
#         return self._items[i]
# 
#     def __len__(self) -> int:
#         return len(self._items)
# 
#     def __repr__(self):
#         return ' '.join(map(str, self))
# 
#     def __eq__(self, other):
#         return all(p0 == p1 for p0, p1 in zip(self, other))
# 
# Path: lcs/agents/yacs/yacs.py
# class Effect(ImmutableSequence):
#     @staticmethod
#     def diff(p0: Optional[Perception], p1: Perception) -> Effect:
#         # Computes the desired effect
#         if p0 is None:
#             return Effect(p1)
# 
#         return Effect(
#             [p1i if p1i != p0i else ImmutableSequence.WILDCARD for p0i, p1i in
#              zip(p0, p1)])
# 
#     def passthrough(self, obs: Perception) -> Perception:
#         # Predicts next state (reverse of diff)
#         return Perception(
#             [ei if ei != ImmutableSequence.WILDCARD else pi for ei, pi in
#              zip(self, obs)])
# 
#     def subsumes(self, other) -> bool:
#         raise NotImplementedError('YACS has no subsume operator')


import pytest
from lcs import Perception
from lcs.agents.yacs.yacs import Effect



class TestEffect:

    def test_should_get_initialized_with_str(self):
        # given
        effect = Effect("#1O##O##")

        # then
        assert len(effect) == 8

    @pytest.mark.parametrize('_p0, _p1, _res', [
        ('1100', '1100', '####'),
        ('1101', '1100', '###0'),
        ('1100', '0011', '0011')
    ])
    def test_should_calculate_desired_effect(self, _p0, _p1, _res):
        assert Effect.diff(Perception(_p0), Perception(_p1)) == Effect(_res)

    def test_should_calculate_desired_effect_with_empty_perception(self):

# Path: lcs/Perception.py
# class Perception(collections.abc.Sequence):
#     """
#     Represents current state of the environment at given time instance.
#     By default each environment attribute is represented as `str` type.
#     """
# 
#     __slots__ = ['_items', 'oktypes']
# 
#     def __init__(self, observation, oktypes=(str,)):
#         assert all(type(e) in oktypes for e in observation)
#         self._items = tuple(observation)
# 
#     @classmethod
#     def empty(cls):
#         return cls([], oktypes=(None,))
# 
#     def __hash__(self):
#         return hash(self._items)
# 
#     def __getitem__(self, i):
#         return self._items[i]
# 
#     def __len__(self) -> int:
#         return len(self._items)
# 
#     def __repr__(self):
#         return ' '.join(map(str, self))
# 
#     def __eq__(self, other):
#         return all(p0 == p1 for p0, p1 in zip(self, other))
# 
# Path: lcs/agents/yacs/yacs.py
# class Effect(ImmutableSequence):
#     @staticmethod
#     def diff(p0: Optional[Perception], p1: Perception) -> Effect:
#         # Computes the desired effect
#         if p0 is None:
#             return Effect(p1)
# 
#         return Effect(
#             [p1i if p1i != p0i else ImmutableSequence.WILDCARD for p0i, p1i in
#              zip(p0, p1)])
# 
#     def passthrough(self, obs: Perception) -> Perception:
#         # Predicts next state (reverse of diff)
#         return Perception(
#             [ei if ei != ImmutableSequence.WILDCARD else pi for ei, pi in
#              zip(self, obs)])
# 
#     def subsumes(self, other) -> bool:
#         raise NotImplementedError('YACS has no subsume operator')


# Path: tests/lcs/agents/yacs/test_Effect.py
import pytest
from lcs import Perception
from lcs.agents.yacs.yacs import Effect




class TestEffect:

    def test_should_get_initialized_with_str(self):
        # given
        effect = Effect("#1O##O##")

        # then
        assert len(effect) == 8

    @pytest.mark.parametrize('_p0, _p1, _res', [
        ('1100', '1100', '####'),
        ('1101', '1100', '###0'),
        ('1100', '0011', '0011')
    ])
    def test_should_calculate_desired_effect(self, _p0, _p1, _res):
        assert Effect.diff(Perception(_p0), Perception(_p1)) == Effect(_res)

    def test_should_calculate_desired_effect_with_empty_perception(self):

        assert Effect.diff(None, Perception('1100')) == Effect('1100')