def test_hit_cooler_stops_and_waits_shorter(): b = BeeClust(numpy.array([[0], [3], [7]]), p_wall=1, p_changedir=0) assert b.tick() == 0 assert b.map[0, 0] == 0 assert b.map[2, 0] == 7 assert b.map[1, 0] <= -2 assert b.map[1, 0] == -2 # cold, bad, waits shorter
def test_hit_wall_stops_and_waits(): b = BeeClust(numpy.array([[5, 4, 0]]), p_wall=1, p_changedir=0) assert b.tick() == 0 assert b.map[0, 0] == 5 assert b.map[0, 2] == 0 assert b.map[0, 1] <= -2 # waits at least min_wait assert b.map[0, 1] == -3 # actually waits based on temp
def test_hit_heater_stops_and_waits_longer(): b = BeeClust(numpy.array([[6], [1], [0]]), p_wall=1, p_changedir=0) assert b.tick() == 0 assert b.map[0, 0] == 6 assert b.map[2, 0] == 0 assert b.map[1, 0] <= -2 assert b.map[1, 0] == -11 # warm, good, waits longer
def test_bee_is_moving_more_or_less_random(): # WARNING: This test is not deterministic, if it fails, run it again. # For a couple of p_changedir probabilities, it ticks ~thousands times, # it counts how many times the bee actually changes the direction. # The numbers should be more or less reflect the p_changedir value. # Remaining directions should be selected by a fair chance. # After some experimenting, we've set tolerance to be 30 %, # that should be enough to beat the odds. But well, it's random. total = 1024 for p_changedir in .2, .4, .5, .9: ups = downs = lefts = rights = 0 for _ in range(total): b = BeeClust(loner(1), p_changedir=p_changedir) assert b.tick() == 1 assert numpy.count_nonzero(b.map) == 1 if b.map[0, 1]: ups += 1 elif b.map[2, 1]: downs += 1 elif b.map[1, 0]: lefts += 1 else: assert b.map[1, 2] rights += 1 tolreance = .3 changedir = p_changedir * total goes = total - changedir assert math.isclose(ups, goes, rel_tol=tolreance) assert math.isclose(downs, changedir / 3, rel_tol=tolreance) assert math.isclose(lefts, changedir / 3, rel_tol=tolreance) assert math.isclose(rights, changedir / 3, rel_tol=tolreance)
def test_hit_cooler_stops_and_waits_at_least_min(): b = BeeClust(numpy.array([[0], [3], [7]]), p_wall=1, p_changedir=0, min_wait=20) assert b.tick() == 0 assert b.map[1, 0] == -20
def test_score_changes(): simple_map = zeros8((3, 1)) simple_map[1, 0] = 1 simple_map[2, 0] = HEATER b = BeeClust(simple_map, p_changedir=0) score = b.score b.tick() assert b.score < score
def test_bee_keeps_going_right_until_it_hits_end(): b = BeeClust(numpy.array([[2, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), p_changedir=0) for j in range(1, 10): assert b.tick() == 1 assert numpy.count_nonzero(b.map) == 1 assert b.map[0, j] == 2 assert b.tick() == 0 assert b.map[0, -1] != 0
def test_forget_direction_waiting(): for value in 1, 2, 3, 4, -2, -12, -3: b = BeeClust(loner(value), p_changedir=0) lo = loner(-1) b.map[0, 0] = lo[0, 0] = 5 b.map[-1, -1] = lo[-1, -1] = 6 b.map[0, -1] = lo[0, -1] = 7 b.forget() assert (b.map == lo).all()
def test_bees_change_after_tick(): simple_map = zeros8((2, 2)) simple_map[1, 0] = 1 b = BeeClust(simple_map, p_changedir=0) assert len(b.bees) == 1 assert sbt(b.bees)[0] == (1, 0) b.tick() assert len(b.bees) == 1 assert sbt(b.bees)[0] != (1, 0)
def test_swarms_change_after_tick(): simple_map = zeros8((2, 2)) simple_map[1, 0] = 1 b = BeeClust(simple_map, p_changedir=0) assert swt(b.swarms) == [[(1, 0)]] b.tick() assert len(b.swarms) == 1 assert len(swt(b.swarms)[0]) == 1 assert swt(b.swarms)[0][0] != (1, 0)
def test_bee_keeps_going_left_until_it_hits_end(): b = BeeClust(numpy.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 4]]), p_changedir=0) for j in range(2, 11): print(j) assert b.tick() == 1 assert numpy.count_nonzero(b.map) == 1 assert b.map[0, -j] == 4 assert b.tick() == 0 assert b.map[0, 0] != 0
def test_bee_keeps_going_down_until_it_hits_a_barrier(): for wall in 5, 6, 7: b = BeeClust(numpy.array([[3], [0], [0], [0], [0], [wall], [0], [0]]), p_changedir=0) for j in range(1, 5): assert b.tick() == 1 assert numpy.count_nonzero(b.map) == 2 assert b.map[j, 0] == 3 assert b.tick() == 0 assert b.map[4, 0] != 0
def test_hit_cooler_stops_and_waits_longer(): b = BeeClust(numpy.array([[0], [3], [7]]), p_wall=1, p_changedir=0, T_cooler=-100, T_ideal=-90) assert b.tick() == 0 assert b.map[0, 0] == 0 assert b.map[2, 0] == 7 assert b.map[1, 0] <= -2 assert b.map[1, 0] == -15 # this kind of bee likes cold environment
def test_hit_strong_heater_stops_and_waits_very_long(): b = BeeClust(numpy.array([[6], [1], [0]]), p_wall=1, p_changedir=0, T_heater=100, T_ideal=90) assert b.tick() == 0 assert b.map[0, 0] == 6 assert b.map[2, 0] == 0 assert b.map[1, 0] <= -2 assert b.map[1, 0] == -15 # hot, very good, waits very long
def test_tick_empty(): original = zeros8((3, 4)) original[1, 2] = 5 # wall original[1, 3] = 6 # heater b = BeeClust(original.copy()) assert b.map is not original # this could go to infinity, but 42 would do # no monkey business at 43, please for _ in range(42): assert b.tick() == 0 assert (b.map == original).all()
def test_score_one_bee_heater(): simple_map = zeros8((3, 4)) simple_map[1, 1] = -2 simple_map[1, 2] = HEATER b = BeeClust(simple_map) assert T_HEATER > b.score > T_ENV assert math.isclose(b.score, 38.2)
def test_two_bordering_bees_in_swarms(): simple_map = zeros8((2, 2)) simple_map[1, 0] = -5 simple_map[1, 1] = 4 b = BeeClust(simple_map) assert len(b.swarms) == 1 assert swt(b.swarms) == [[(1, 0), (1, 1)]]
def test_pseoudorandom_heat(): simple_map = numpy.array([ [HEATER, WALL, COOLER], [-1, 0, 4], [HEATER, COOLER, 0], [0, 3, 0], ]) b = BeeClust(simple_map) WARM = 22.9 COLD = 14.8 assert math.isclose(b.heatmap[0, 0], T_HEATER) assert math.isclose(b.heatmap[0, 2], T_COOLER) assert math.isclose(b.heatmap[1, 0], WARM) assert math.isclose(b.heatmap[1, 1], WARM) assert math.isclose(b.heatmap[1, 2], COLD) assert math.isclose(b.heatmap[2, 0], T_HEATER) assert math.isclose(b.heatmap[2, 1], T_COOLER) assert math.isclose(b.heatmap[2, 2], COLD) assert math.isclose(b.heatmap[3, 0], WARM) assert math.isclose(b.heatmap[3, 1], WARM) assert math.isclose(b.heatmap[3, 2], COLD)
def test_heat_distribution_along_diagonal(): simple_map = zeros8((8, 8)) simple_map[0, 0] = HEATER b = BeeClust(simple_map) TEMPS = [40, 38.2, 30.1, 27.4, 26.05, 25.24, 24.7, 24.31428571] for i in range(-8, 8): assert numpy.isclose(b.heatmap.diagonal(i), TEMPS[abs(i):]).all()
def test_two_bees_in_swarms_corner(): simple_map = zeros8((3, 3)) simple_map[1, 0] = -5 simple_map[0, 1] = 4 b = BeeClust(simple_map) assert len(b.swarms) == 2 assert swt(b.swarms) == [[(0, 1)], [(1, 0)]]
def test_str_kwargs_raise_TypeError(): for key in KWARGS.keys(): kwargs = OrderedDict(**KWARGS) kwargs[key] = 'impossibru' with pytest.raises(TypeError) as excinfo: BeeClust(**kwargs) assert key in str(excinfo.value)
def test_weird_map_shape_raises_ValueError(): for shape in (8, ), (2, 2, 2): kwargs = OrderedDict(**KWARGS) kwargs['map'] = zeros8(shape) with pytest.raises(ValueError) as excinfo: BeeClust(**kwargs) assert ('shape' in str(excinfo.value) or 'dim' in str(excinfo.value))
def test_negative_temps(): BeeClust( MAP, T_cooler=-10, T_env=1, T_heater=5, )
def test_optional_kwargs(): for key in KWARGS.keys(): if key == 'map': continue kwargs = OrderedDict(**KWARGS) del kwargs[key] BeeClust(**kwargs)
def test_wall_may_stop_or_turn(): # WARNING: This test is not deterministic, if it fails, run it again. # Let's not run another statistics and just check it works at least once. waited = False turned = False tries = 0 while not turned and waited: tries += 1 b = BeeClust(numpy.array([[0, 2, 5]]), p_wall=.5, p_changedir=0) assert b.tick() == 0 if b.map[0, 1] == 4: turned = True else: assert b.map[0, 1] <= -2 waited = True assert tries < 20
def test_invalid_probability_values_raise_ValueError(): for key in 'p_changedir', 'p_wall', 'p_meet': kwargs = OrderedDict(**KWARGS) kwargs[key] = 2 with pytest.raises(ValueError) as excinfo: BeeClust(**kwargs) assert ('probability' in str(excinfo.value) and '1' in str(excinfo.value))
def test_inert_temps(): # shouldn't rise BeeClust( MAP, T_cooler=10, T_env=10, T_heater=10, )
def test_score_two_bees_heater_cooler(): simple_map = zeros8((3, 4)) simple_map[0, 0] = COOLER simple_map[2, 3] = HEATER simple_map[0, 1] = 2 simple_map[2, 2] = 3 b = BeeClust(simple_map) assert math.isclose(b.score, 22.675)
def test_wall_stops_cool(): simple_map = zeros8((3, 3)) simple_map[:, 1] = WALL simple_map[:, 2] = COOLER b = BeeClust(simple_map) assert math.isclose(b.heatmap[0, 0], T_ENV) assert math.isclose(b.heatmap[1, 0], T_ENV) assert math.isclose(b.heatmap[2, 0], T_ENV)
def test_two_bees_in_bees(): simple_map = zeros8((2, 2)) simple_map[1, 0] = -5 simple_map[1, 1] = 4 b = BeeClust(simple_map) assert len(b.bees) == 2 assert (1, 0) in sbt(b.bees) assert (1, 1) in sbt(b.bees)