From 7d133e76aa80e57ce5e9443ab3b0798ed38fa27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carles=20S=2E=20Soriano=20P=C3=A9rez?= Date: Wed, 9 Oct 2024 11:55:37 +0200 Subject: [PATCH] fix: 177 errors when getting total infrastructure per zone (#178) * test: Added failing test for first bug found by PO * fix: Corrected way of taking surrounding matrix points. Now it's only applicable when its value is greater than zero * test: Reenabled all tests for sandbox with obstacles and infrastructures --- .../surroundings/point/point_surroundings.py | 12 ++++---- .../koswat_input_profile_base_cases.py | 19 ++++++++++++ .../koswat_scenario_test_cases.py | 6 ++++ .../test_koswat_surroundings_csv_reader.py | 27 +++++++++++++---- .../point/test_point_surroundings.py | 29 +++++++++++++++++++ 5 files changed, 82 insertions(+), 11 deletions(-) diff --git a/koswat/dike/surroundings/point/point_surroundings.py b/koswat/dike/surroundings/point/point_surroundings.py index 461932ef..da195b39 100644 --- a/koswat/dike/surroundings/point/point_surroundings.py +++ b/koswat/dike/surroundings/point/point_surroundings.py @@ -96,15 +96,15 @@ def matrix_idx_for_limits(limits: tuple[float, float]) -> float: return 0 _total_width = 0 for _matrix_distance, value in _sorted_matrix_array: - if _matrix_distance < _lower_limit and not math.isclose( - _matrix_distance, _lower_limit + if _matrix_distance in _taken_keys or ( + _matrix_distance < _lower_limit + and not math.isclose(_matrix_distance, _lower_limit) ): - return 0 - if _matrix_distance in _taken_keys: continue - # _matrix_distance >= lower_limit + _total_width += value - _taken_keys.append(_matrix_distance) + if value != 0: + _taken_keys.append(_matrix_distance) if _matrix_distance > _upper_limit or math.isclose( _matrix_distance, _upper_limit ): diff --git a/tests/acceptance_scenarios/koswat_input_profile_base_cases.py b/tests/acceptance_scenarios/koswat_input_profile_base_cases.py index 01c81663..3f066068 100644 --- a/tests/acceptance_scenarios/koswat_input_profile_base_cases.py +++ b/tests/acceptance_scenarios/koswat_input_profile_base_cases.py @@ -43,6 +43,25 @@ class InputProfileCases(CasesProtocol): aquifer=-2, ) + infra = KoswatInputProfileBase( + dike_section="test_data", + buiten_maaiveld=0, + buiten_talud=3, + buiten_berm_hoogte=0, + buiten_berm_breedte=0, + kruin_hoogte=6, + kruin_breedte=8, + binnen_talud=3, + binnen_berm_hoogte=0, + binnen_berm_breedte=0, + binnen_maaiveld=0, + grondprijs_bebouwd=150, + grondprijs_onbebouwd=10, + factor_zetting=1.2, + pleistoceen=-5, + aquifer=-2, + ) + cases = [pytest.param(default, id="Default Input Profile")] diff --git a/tests/acceptance_scenarios/koswat_scenario_test_cases.py b/tests/acceptance_scenarios/koswat_scenario_test_cases.py index 04131a6e..f3a7bfe4 100644 --- a/tests/acceptance_scenarios/koswat_scenario_test_cases.py +++ b/tests/acceptance_scenarios/koswat_scenario_test_cases.py @@ -25,6 +25,12 @@ class ScenarioCases(CasesProtocol): kruin_breedte=5, buiten_talud=3, ) + scenario_infra = KoswatScenario( + d_h=0, + d_s=20, + d_p=50, + kruin_breedte=8, + ) cases = [ pytest.param(default, id="Default Scenario"), diff --git a/tests/configuration/io/csv/test_koswat_surroundings_csv_reader.py b/tests/configuration/io/csv/test_koswat_surroundings_csv_reader.py index 35153cb2..bc98a279 100644 --- a/tests/configuration/io/csv/test_koswat_surroundings_csv_reader.py +++ b/tests/configuration/io/csv/test_koswat_surroundings_csv_reader.py @@ -1,3 +1,5 @@ +import pytest + from koswat.configuration.io.csv.koswat_surroundings_csv_fom import ( KoswatSurroundingsCsvFom, ) @@ -30,15 +32,30 @@ def test_read_given_valid_file(self): assert isinstance(_csv_fom, KoswatSurroundingsCsvFom) assert _csv_fom.is_valid() - def test_when_build_point_surroundings_then_reduced_surroundings_matrix(self): + @pytest.mark.parametrize( + "distance_weights, expected_matrix", + [ + pytest.param( + [0, 0, 2, 0, 0, 4, 0], + {10: 0, 15: 2, 25: 0, 30: 4}, + id="More than one weight.", + ), + pytest.param( + [0, 0, 0, 0, 0, 0, 2], {30: 0, 35: 2}, id="Only one weight available." + ), + ], + ) + def test_when_build_point_surroundings_then_reduced_surroundings_matrix( + self, distance_weights: list[float], expected_matrix: dict[int, float] + ): # 1. Define test data. _section = "Dummy" _traject_order = -1 _location_x = 4.2 _location_y = 2.4 _distances_list = [5, 10, 15, 20, 25, 30, 35] - _distance_weights = [0, 0, 2, 0, 0, 4, 0] - _expected_matrix = {10: 0, 15: 2, 25: 0, 30: 4} + assert len(distance_weights) == len(_distances_list) + assert all(_key in _distances_list for _key in expected_matrix.keys()) # 2. Run test. _point_surroundings = KoswatSurroundingsCsvReader()._build_point_surroundings( @@ -47,7 +64,7 @@ def test_when_build_point_surroundings_then_reduced_surroundings_matrix(self): _section, _location_x, _location_y, - *_distance_weights, + *distance_weights, ], distances_list=_distances_list, ) @@ -58,4 +75,4 @@ def test_when_build_point_surroundings_then_reduced_surroundings_matrix(self): assert _point_surroundings.traject_order == _traject_order assert _point_surroundings.location.x == _location_x assert _point_surroundings.location.y == _location_y - assert _point_surroundings.surroundings_matrix == _expected_matrix + assert _point_surroundings.surroundings_matrix == expected_matrix diff --git a/tests/dike/surroundings/point/test_point_surroundings.py b/tests/dike/surroundings/point/test_point_surroundings.py index 8abe8b16..bc44b821 100644 --- a/tests/dike/surroundings/point/test_point_surroundings.py +++ b/tests/dike/surroundings/point/test_point_surroundings.py @@ -43,3 +43,32 @@ def test_get_total_infrastructure_per_zone_with_costs_calculator_case( # 3. Verify expectations. assert _result == _point_surroundings_case.expected_total_widths + + @pytest.mark.parametrize( + "zones, surroundings_matrix, expected_values", + [ + pytest.param( + ([0, 5], [5, 25]), {30: 0, 35: 5}, [0, 0], id="No infra in zone A or B." + ), + pytest.param( + ([0, 8], [8, 76]), + {5.0: 0.0, 10.0: 1.0, 20.0: 0.0, 25.0: 1.0}, + [1, 1], + id="Overlapping distances.", + ), + ], + ) + def test_get_total_infrastructure_per_zone_given_zones_and_surround_matrix( + self, + zones: tuple[list[int], list[int]], + surroundings_matrix: dict[int, int], + expected_values: list[int], + ): + # 1. Define test data. + _ps = PointSurroundings(surroundings_matrix=surroundings_matrix) + + # 2. Run test. + _total_infra = _ps.get_total_infrastructure_per_zone(*zones) + + # 3. Verify expectations. + assert _total_infra == expected_values