def test_get_best_anticipation(self, _p0, _result): # given p0 = Perception(_p0) effect = Effect(['#', '#', '0', '#', '#', '0', '#', '#']) # when result0 = effect.get_best_anticipation(p0) # then assert result0 == _result
def test_does_match(self, _p0, _p1, _e, _result): # given p0 = Perception(_p0) p1 = Perception(_p1) effect = Effect(_e) # when result = effect.does_match(p0, p1) # then assert result is _result
def test_does_specify_only_changes_backwards(self, _p0, _p1, _e, _result): # given back_ant = Perception(_p0) sit = Perception(_p1) effect = Effect(_e) # when result = effect.does_specify_only_changes_backwards(back_ant, sit) # then assert result is _result
def test_should_check_if_specializable_6(self): # given p0 = Perception(['0', '0', '1', '1', '0', '0', '0', '0']) p1 = Perception(['0', '0', '1', '1', '0', '0', '0', '0']) effect = Effect(['#', '1', '0', '#', '#', '#', '1', '1']) # when res = effect.is_specializable(p0, p1) # then assert res is False
def test_should_specialize(self, _p0, _p1, _init_cond, _init_effect, _res_cond, _res_effect, cfg): # given cls = Classifier(condition=Condition(_init_cond), effect=Effect(_init_effect), cfg=cfg) p0 = Perception(_p0) p1 = Perception(_p1) # when cls.specialize(p0, p1, leave_specialized=False) # then assert cls.condition == Condition(_res_cond) assert cls.effect == Effect(_res_effect)
def test_should_handle_expected_case_3(self, cfg): # given p0 = Perception('00110000') time = 26 cls = Classifier(action=5, quality=0.46, cfg=cfg) cls.mark[0].add('0') cls.mark[1].add('1') cls.mark[2].add('0') cls.mark[3].add('1') cls.mark[4].add('0') cls.mark[5].add('1') cls.mark[6].add('1') cls.mark[7].add('1') # when new_cls = expected_case(cls, p0, time) # then assert new_cls is not None # One `random` attribute gets specified assert 1 == new_cls.condition.specificity assert Effect('########') == new_cls.effect assert 5 == new_cls.action assert new_cls.is_marked() is False assert 0.5 == new_cls.q
def test_should_handle_expected_case_4(self, cfg): # given p0 = Perception('11101101') time = 703 cls = Classifier(condition='1##01#0#', action=7, effect='0##10#1#', quality=0.47, cfg=cfg) cls.mark[1].update(['0', '2']) cls.mark[2].update(['1']) cls.mark[5].update(['0', '1']) cls.mark[7].update(['1']) # when new_cls = expected_case(cls, p0, time) # then assert new_cls is not None # One `random` attribute gets specified assert new_cls.condition.specificity in [4, 5] assert Effect('0##10#1#') == new_cls.effect assert 7 == new_cls.action assert new_cls.is_marked() is False assert 0.5 == new_cls.q
def test_should_handle_unexpected_case_2(self, cfg): # given cls = Classifier(condition='#######0', action=4, quality=0.4, cfg=cfg) cls.mark[0].update([0, 1]) cls.mark[1].update([0, 1]) cls.mark[2].update([0, 1]) cls.mark[3].update([0, 1]) cls.mark[4].update([1]) cls.mark[5].update([0, 1]) cls.mark[6].update([0, 1]) p0 = Perception('11101010') p1 = Perception('10011101') time = 94 # when new_cl = unexpected_case(cls, p0, p1, time) # then assert new_cl.condition == Condition('#110#010') assert new_cl.effect == Effect('#001#101') assert new_cl.is_marked() is False assert time == new_cl.tga assert time == new_cl.talp assert abs(cls.q - 0.38) < 0.01
def test_copy_from_and_change_does_not_influence_another_effect(self, cfg): """ Verify that not just reference to Condition copied (changing which will change the original - definitily not original C++ code did). """ # given operation_time = 123 original_cl = Classifier(effect='10####1#', cfg=cfg) # when copied_cl = Classifier.copy_from(original_cl, operation_time) # when & then copied_cl.effect[2] = '1' assert Effect('101###1#') == copied_cl.effect assert Effect('10####1#') == original_cl.effect # when & then original_cl.effect[3] = '0' assert Effect('101###1#') == copied_cl.effect assert Effect('10#0##1#') == original_cl.effect
def test_should_detect_correct_anticipation_1(self, cfg): # Classifier is not predicting any change, all pass-through effect # should predict correctly # given cls = Classifier(effect=Effect('########'), cfg=cfg) p0 = Perception('00001111') p1 = Perception('00001111') # then assert cls.does_anticipate_correctly(p0, p1) is True
def test_should_detect_correct_anticipation_6(self, cfg): # Case when effect predicts situation incorrectly # given cls = Classifier(effect=Effect( ['#', '#', '1', '#', '0', '#', '0', '#']), cfg=cfg) p0 = Perception(['0', '0', '0', '1', '1', '0', '1', '0']) p1 = Perception(['0', '0', '1', '1', '0', '0', '0', '0']) # then assert cls.does_anticipate_correctly(p0, p1) is True
def test_update_equivalence(self): # given (note that the effects are practically equivalent) perception = Perception("1101") effect_a = Effect( ({"1": 0.6, "0": 0.4}, {"0": 0.8, "1": 0.2}, "1", "1")) effect_b = Effect(({"1": 0.6, "0": 0.4}, {"0": 0.8, "1": 0.2}, {"1": 1.0, "0": 0.0}, {"1": 1.0, "0": 0.0})) # when effect_a.update_enhanced_effect_probs(perception, 0.6) effect_b.update_enhanced_effect_probs(perception, 0.6) # then assert effect_a == effect_b
def test_eq(self): assert Effect('00001111') == Effect('00001111') assert Effect('00001111') != Effect('0000111#') assert Effect(({"1": 0.6, "0": 0.4}, {"0": 0.8, "1": 0.2}, {"1": 1.0, "0": 0.0}, {"1": 1.0, "0": 0.0})) \ == Effect(({"0": 0.4, "1": 0.6}, {"1": 0.2, "0": 0.8}, {"0": 0.0, "1": 1.0}, {"0": 0.0, "1": 1.0})) # Note that for probability-enhanced attributes, they are # considered "equal" when the algorithms are concerned, if # only they have the same symbols, no matter their probabilities assert Effect(({"1": 0.6, "0": 0.4}, {"0": 0.8, "1": 0.2}, {"1": 1.0, "0": 0.0}, {"1": 1.0, "0": 0.0})) \ == Effect(({"0": 0.4, "1": 0.6}, {"1": 0.3, "0": 0.7}, {"0": 0.0, "1": 1.0}, {"0": 0.0, "1": 1.0}))
def test_should_handle_pass_through_symbol(self, cfg): # A case when there was no change in perception but effect has no # pass-through symbol # given cls = Classifier(effect=Effect( ['#', '0', '#', '#', '#', '#', '#', '#']), cfg=cfg) p0 = Perception(['0', '0', '0', '0', '1', '1', '1', '1']) p1 = Perception(['0', '0', '0', '0', '1', '1', '1', '1']) # then assert cls.does_anticipate_correctly(p0, p1) is False
def test_should_detect_correct_anticipation_2(self, cfg): # Introduce two changes into situation and effect (should # also predict correctly) # given cls = Classifier(effect=Effect( ['#', '1', '#', '#', '#', '#', '0', '#']), cfg=cfg) p0 = Perception(['0', '0', '0', '0', '1', '1', '1', '1']) p1 = Perception(['0', '1', '0', '0', '1', '1', '0', '1']) # then assert cls.does_anticipate_correctly(p0, p1) is True
def test_should_handle_unexpected_case_1(self, cfg): # given cls = Classifier(action=2, cfg=cfg) p0 = Perception('01100000') p1 = Perception('10100010') time = 14 new_cls = unexpected_case(cls, p0, p1, time) # Quality should be decreased assert 0.475 == cls.q # Should be marked with previous perception for mark_attrib in cls.mark: assert 1 == len(mark_attrib) assert '0' in cls.mark[0] assert '1' in cls.mark[1] assert '1' in cls.mark[2] assert '0' in cls.mark[3] assert '0' in cls.mark[4] assert '0' in cls.mark[5] assert '0' in cls.mark[6] assert '0' in cls.mark[7] # New classifier should not be the same object assert cls is not new_cls # Check attributes of a new classifier assert Condition('01####0#') == new_cls.condition assert 2 == new_cls.action assert Effect('10####1#') == new_cls.effect # There should be no mark for mark_attrib in new_cls.mark: assert 0 == len(mark_attrib) assert 0.5 == new_cls.q assert cls.r == new_cls.r assert time == new_cls.tga assert time == new_cls.talp
def test_should_create_new_classifier_using_covering(self, cfg): # given action = random.randint(0, cfg.number_of_possible_actions) time = random.randint(0, 1000) p0 = Perception('01001101') p1 = Perception('00011111') # when new_cl = cover(p0, action, p1, time, cfg) # then assert new_cl.condition == Condition('#1#0##0#') assert new_cl.action == action assert new_cl.effect == Effect('#0#1##1#') assert new_cl.q == .5 assert new_cl.r == 0 assert new_cl.ir == 0 assert new_cl.tav == 0 assert new_cl.tga == time assert new_cl.talp == time assert new_cl.num == 1 assert new_cl.exp == 0
def test_should_handle_unexpected_case_5(self, cfg): # given cls = Classifier(condition='00####1#', action=2, effect='########', quality=0.129, reward=341.967, immediate_reward=130.369, experience=201, tga=129, talp=9628, tav=25.08, cfg=cfg) cls.mark[2].add('2') cls.mark[3].add('1') cls.mark[4].add('1') cls.mark[5].add('0') cls.mark[7].add('0') p0 = Perception('00211010') p1 = Perception('00001110') time = 9628 # when new_cls = unexpected_case(cls, p0, p1, time) # then assert new_cls is not None assert Condition('0021#01#') == new_cls.condition assert Effect('##00#1##') == new_cls.effect assert abs(0.5 - new_cls.q) < 0.1 assert abs(341.967 - new_cls.r) < 0.1 assert abs(130.369 - new_cls.ir) < 0.1 assert abs(25.08 - new_cls.tav) < 0.1 assert 1 == new_cls.exp assert 1 == new_cls.num assert time == new_cls.tga assert time == new_cls.talp
def test_should_handle_unexpected_case_6(self, cfg): # given cls = Classifier(condition='0#1####1', action=2, effect='1#0####0', quality=0.38505, reward=1.20898, immediate_reward=0, experience=11, tga=95, talp=873, tav=71.3967, cfg=cfg) cls.mark[1].update(['1']) cls.mark[3].update(['1']) cls.mark[4].update(['0', '1']) cls.mark[5].update(['1']) cls.mark[6].update(['0', '1']) p0 = Perception('01111101') p1 = Perception('11011110') time = 873 # when new_cls = unexpected_case(cls, p0, p1, time) # then assert new_cls is not None assert Condition('0#1###01') == new_cls.condition assert Effect('1#0###10') == new_cls.effect assert abs(0.5 - new_cls.q) < 0.1 assert abs(1.20898 - new_cls.r) < 0.1 assert abs(0 - new_cls.ir) < 0.1 assert abs(71.3967 - new_cls.tav) < 0.1 assert 1 == new_cls.exp assert 1 == new_cls.num assert time == new_cls.tga assert time == new_cls.talp
def test_enhanced(self): # given effect = Effect(({"1": 0.6, "0": 0.4}, {"0": 0.8, "1": 0.2}, "1", "1")) # then assert effect.is_enhanced()
def test_should_initialize_correctly(self): effect = Effect.empty(8) assert 8 == len(effect)
def test_should_detect_change(self, _e, _result): assert Effect(_e).specify_change == _result
def test_should_set_effect_with_non_string_char(self): effect = Effect.empty(8) with pytest.raises(TypeError): effect[0] = 1
def test_eq(self): assert Effect('00001111') == Effect('00001111') assert Effect('00001111') != Effect('0000111#')
def test_should_get_initialized_with_string(self): effect = Effect("#1O##O##") assert 8 == len(effect)
def test_reduced_to_non_enhanced(self): # given effect = Effect(({"1": 0.6, "0": 0.4}, {"0": 0.8, "1": 0.2}, "1", "1")) # then assert effect.reduced_to_non_enhanced() == Effect("1011")
def test_not_enhanced(self): # given effect = Effect(("1", "0", "1", "1")) # then assert not effect.is_enhanced()
def test_should_return_number_of_specific_components_2(self): effect = Effect.empty(8) effect[1] = '1' assert 1 == effect.number_of_specified_elements
def test_should_return_number_of_specific_components_1(self): effect = Effect.empty(8) assert 0 == effect.number_of_specified_elements
def test_str(self): # given effect = Effect(({"1": 0.6, "0": 0.4}, {"0": 0.8, "1": 0.2}, "1", "1")) # then assert str(effect) == "{10}{01}11"