From 655a618b98454664b7f4404d11d192895cbe1375 Mon Sep 17 00:00:00 2001 From: Jannes Date: Mon, 9 Dec 2024 18:28:57 +0100 Subject: [PATCH 1/6] add exception for invalid or `ags` --- src/climatevision/generator/makeentries.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/climatevision/generator/makeentries.py b/src/climatevision/generator/makeentries.py index f55b4771..49aa92fe 100644 --- a/src/climatevision/generator/makeentries.py +++ b/src/climatevision/generator/makeentries.py @@ -2,7 +2,7 @@ from .entries import Entries from .utils import div -from .refdata import RefData, Row +from .refdata import RefData, Row, RowNotFound from .years import YEAR_BASELINE_CHOICES, YEAR_TARGET_CHOICES @@ -42,7 +42,12 @@ def make_entries( m_population_sta = data.population(ags_sta_padded).int("total") m_population_nat = data.population(ags_germany).int("total") - data_area_com = data.area(ags) + try: + data_area_com = data.area(ags) + except RowNotFound: + raise ValueError( + f"ags '{ags}' was not found in the data, please check your entry." + ) data_area_dis = data.area(ags_dis_padded) data_area_sta = data.area(ags_sta_padded) data_area_nat = data.area(ags_germany) From d95aea8b87d21bac2a4627d6a43980b366e0fef1 Mon Sep 17 00:00:00 2001 From: Jannes Date: Mon, 9 Dec 2024 18:35:05 +0100 Subject: [PATCH 2/6] refactor: change position of exception --- src/climatevision/generator/makeentries.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/climatevision/generator/makeentries.py b/src/climatevision/generator/makeentries.py index 49aa92fe..81b6d232 100644 --- a/src/climatevision/generator/makeentries.py +++ b/src/climatevision/generator/makeentries.py @@ -12,6 +12,13 @@ def make_entries( assert year_baseline in YEAR_BASELINE_CHOICES assert year_target in YEAR_TARGET_CHOICES + try: + data_area_com = data.area(ags) + except RowNotFound: + raise ValueError( + f"ags '{ags}' was not found in the data, please check your entry." + ) + # ags identifies the community (Kommune) ags_dis = ags[:5] # This identifies the administrative district (Landkreis) ags_sta = ags[:2] # This identifies the federal state (Bundesland) @@ -42,12 +49,6 @@ def make_entries( m_population_sta = data.population(ags_sta_padded).int("total") m_population_nat = data.population(ags_germany).int("total") - try: - data_area_com = data.area(ags) - except RowNotFound: - raise ValueError( - f"ags '{ags}' was not found in the data, please check your entry." - ) data_area_dis = data.area(ags_dis_padded) data_area_sta = data.area(ags_sta_padded) data_area_nat = data.area(ags_germany) From 8b67b7ce10163be9bc482636324ec7c245f6bcc3 Mon Sep 17 00:00:00 2001 From: Jannes Date: Wed, 11 Dec 2024 19:18:46 +0100 Subject: [PATCH 3/6] add error without stacktrace if ags not exist --- src/climatevision/generator/makeentries.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/climatevision/generator/makeentries.py b/src/climatevision/generator/makeentries.py index 81b6d232..b9f8ff56 100644 --- a/src/climatevision/generator/makeentries.py +++ b/src/climatevision/generator/makeentries.py @@ -12,12 +12,9 @@ def make_entries( assert year_baseline in YEAR_BASELINE_CHOICES assert year_target in YEAR_TARGET_CHOICES - try: - data_area_com = data.area(ags) - except RowNotFound: - raise ValueError( - f"ags '{ags}' was not found in the data, please check your entry." - ) + if ags not in list(data.ags_master().keys()): + print(f"ags '{ags}' was not found in the master CSV, please check your entry.") + exit(1) # Exit gracefully with a non-zero status code # ags identifies the community (Kommune) ags_dis = ags[:5] # This identifies the administrative district (Landkreis) @@ -49,6 +46,7 @@ def make_entries( m_population_sta = data.population(ags_sta_padded).int("total") m_population_nat = data.population(ags_germany).int("total") + data_area_com = data.area(ags) data_area_dis = data.area(ags_dis_padded) data_area_sta = data.area(ags_sta_padded) data_area_nat = data.area(ags_germany) @@ -771,3 +769,8 @@ def compute_efactor_from_n2o( ags=ags, w_elec_fec=w_elec_fec, ) + + +if __name__ == "__main__": + rd = RefData.load(year_ref=2035) + entries = make_entries(data=rd, ags=12345678, year_baseline=2018, year_target=2035) From 27d4ad75e163162b1c9e6a87068f9fcccd0198c3 Mon Sep 17 00:00:00 2001 From: Jannes Date: Mon, 16 Dec 2024 17:55:33 +0100 Subject: [PATCH 4/6] add assertion like error to make_entries --- src/climatevision/generator/makeentries.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/climatevision/generator/makeentries.py b/src/climatevision/generator/makeentries.py index b9f8ff56..7e28b9ae 100644 --- a/src/climatevision/generator/makeentries.py +++ b/src/climatevision/generator/makeentries.py @@ -2,7 +2,7 @@ from .entries import Entries from .utils import div -from .refdata import RefData, Row, RowNotFound +from .refdata import RefData, Row from .years import YEAR_BASELINE_CHOICES, YEAR_TARGET_CHOICES @@ -12,9 +12,9 @@ def make_entries( assert year_baseline in YEAR_BASELINE_CHOICES assert year_target in YEAR_TARGET_CHOICES - if ags not in list(data.ags_master().keys()): + if ags not in data.ags_master(): print(f"ags '{ags}' was not found in the master CSV, please check your entry.") - exit(1) # Exit gracefully with a non-zero status code + exit(1) # ags identifies the community (Kommune) ags_dis = ags[:5] # This identifies the administrative district (Landkreis) @@ -769,8 +769,3 @@ def compute_efactor_from_n2o( ags=ags, w_elec_fec=w_elec_fec, ) - - -if __name__ == "__main__": - rd = RefData.load(year_ref=2035) - entries = make_entries(data=rd, ags=12345678, year_baseline=2018, year_target=2035) From 519ea59f6ea842a7de085b7cace1dd24e0203183 Mon Sep 17 00:00:00 2001 From: Jannes Date: Mon, 16 Dec 2024 18:24:50 +0100 Subject: [PATCH 5/6] add tests for target and ref year --- tests/test_devtool_commands.py | 46 +++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/tests/test_devtool_commands.py b/tests/test_devtool_commands.py index fa91b815..2ff043ec 100644 --- a/tests/test_devtool_commands.py +++ b/tests/test_devtool_commands.py @@ -2,6 +2,8 @@ import os +import pytest + from devtool import Devtool filePath = "test.txt" @@ -64,6 +66,48 @@ def test_cmd_make_entries_with_parameters(): assert False, "file " + filePath + " was not created" +def test_cmd_make_entries_with_invalid_target_year(): + with pytest.raises(SystemExit) as excinfo: + check_cmd( + [ + "make", + "-ags", + "100000000", + "-year_target", + "2100", # Invalid target year + "-year_ref", + "2018", + "-o", + filePath, + ], + "make", + False, + ) + + assert excinfo.value.code == 2 + + +def test_cmd_make_entries_with_invalid_ref_year(): + with pytest.raises(SystemExit) as excinfo: + check_cmd( + [ + "make", + "-ags", + "100000000", + "-year_target", + "2040", + "-year_ref", + "1999", # Invalid ref year + "-o", + filePath, + ], + "make", + False, + ) + + assert excinfo.value.code == 2 + + def test_cmd_explorer(): check_cmd( ["explorer"], @@ -124,7 +168,7 @@ def test_cmd_test_end_to_end_update_expectations(): check_cmd( ["test_end_to_end", "update_expectations"], "update_expectations", - False # You shouldn't run this as it will update expectations. + False, # You shouldn't run this as it will update expectations. # We only want people to do so when they have thought about it first. ) From c771899c07ed32edb86717ed9bb76b4aed76f3f1 Mon Sep 17 00:00:00 2001 From: Jannes Date: Wed, 18 Dec 2024 10:55:48 +0100 Subject: [PATCH 6/6] add checks for ags in rguments.py; add new test --- commands/arguments.py | 27 +++++++-- src/climatevision/generator/makeentries.py | 7 +-- tests/test_devtool_commands.py | 64 +++++++++++++++++++++- 3 files changed, 84 insertions(+), 14 deletions(-) diff --git a/commands/arguments.py b/commands/arguments.py index 0eb47cd5..3d74b69d 100644 --- a/commands/arguments.py +++ b/commands/arguments.py @@ -1,20 +1,35 @@ +import argparse from typing import Any +from climatevision.generator import RefData from climatevision.generator.years import ( - YEAR_REF_DEFAULT, - YEAR_REF_CHOICES, - YEAR_REF_HELP, - YEAR_BASELINE_DEFAULT, YEAR_BASELINE_CHOICES, + YEAR_BASELINE_DEFAULT, YEAR_BASELINE_HELP, - YEAR_TARGET_DEFAULT, + YEAR_REF_CHOICES, + YEAR_REF_DEFAULT, + YEAR_REF_HELP, YEAR_TARGET_CHOICES, + YEAR_TARGET_DEFAULT, YEAR_TARGET_HELP, ) +class DynamicChoicesAction(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): + year_ref = getattr(namespace, "year_ref", 2018) # Default to 2018 if not set + ags_master = RefData.load(int(year_ref)).ags_master() + if values not in ags_master: + raise argparse.ArgumentError( + self, + f"Invalid choice: {values!r}. Valid choices include: {', '.join(list(ags_master)[:10])}, ...", + ) + + setattr(namespace, self.dest, values) + + def add_ags_argument(parser: Any): - parser.add_argument("-ags", default="03159016") + parser.add_argument("-ags", default="03159016", action=DynamicChoicesAction) def add_year_ref_argument(parser: Any): diff --git a/src/climatevision/generator/makeentries.py b/src/climatevision/generator/makeentries.py index 7e28b9ae..65e02aaf 100644 --- a/src/climatevision/generator/makeentries.py +++ b/src/climatevision/generator/makeentries.py @@ -1,8 +1,8 @@ # pyright: strict from .entries import Entries -from .utils import div from .refdata import RefData, Row +from .utils import div from .years import YEAR_BASELINE_CHOICES, YEAR_TARGET_CHOICES @@ -11,10 +11,7 @@ def make_entries( ) -> Entries: assert year_baseline in YEAR_BASELINE_CHOICES assert year_target in YEAR_TARGET_CHOICES - - if ags not in data.ags_master(): - print(f"ags '{ags}' was not found in the master CSV, please check your entry.") - exit(1) + assert ags in data.ags_master() # ags identifies the community (Kommune) ags_dis = ags[:5] # This identifies the administrative district (Landkreis) diff --git a/tests/test_devtool_commands.py b/tests/test_devtool_commands.py index 2ff043ec..24a29070 100644 --- a/tests/test_devtool_commands.py +++ b/tests/test_devtool_commands.py @@ -25,7 +25,19 @@ def test_cmd_run_with_parameters(): assert False, "file " + filePath + " already exists" check_cmd( - ["run", "-ags", "10000000", "-year_target", "2040", "-o", filePath], + [ + "run", + "-ags", + "10000000", + "-year_target", + "2040", + "-year_ref", + "2021", + "-year_baseline", + "2022", + "-o", + filePath, + ], "run", True, ) @@ -53,6 +65,8 @@ def test_cmd_make_entries_with_parameters(): "2040", "-year_ref", "2021", + "-year_baseline", + "2022", "-o", filePath, ], @@ -66,13 +80,34 @@ def test_cmd_make_entries_with_parameters(): assert False, "file " + filePath + " was not created" +def test_cmd_make_entries_with_invalid_ags(): + with pytest.raises(SystemExit) as excinfo: + check_cmd( + [ + "make", + "-ags", + "12345678", # Invalid AGS value + "-year_target", + "2040", + "-year_ref", + "2018", + "-o", + "dummy_output_path", + ], + "make", + False, + ) + + assert excinfo.value.code == 2 + + def test_cmd_make_entries_with_invalid_target_year(): with pytest.raises(SystemExit) as excinfo: check_cmd( [ "make", "-ags", - "100000000", + "10000000", "-year_target", "2100", # Invalid target year "-year_ref", @@ -93,7 +128,7 @@ def test_cmd_make_entries_with_invalid_ref_year(): [ "make", "-ags", - "100000000", + "10000000", "-year_target", "2040", "-year_ref", @@ -108,6 +143,29 @@ def test_cmd_make_entries_with_invalid_ref_year(): assert excinfo.value.code == 2 +def test_cmd_make_entries_with_invalid_baseline_year(): + with pytest.raises(SystemExit) as excinfo: + check_cmd( + [ + "make", + "-ags", + "10000000", + "-year_target", + "2040", + "-year_ref", + "2018", + "-year_baseline", + "1999", # Invalid baseline year + "-o", + filePath, + ], + "make", + False, + ) + + assert excinfo.value.code == 2 + + def test_cmd_explorer(): check_cmd( ["explorer"],