From 74f931237cfc3c36daac03f1fc61519d32794355 Mon Sep 17 00:00:00 2001 From: Stefano Borini <sborini@enthought.com> Date: Tue, 1 Aug 2017 15:42:15 +0100 Subject: [PATCH] Introduced slots --- force_bdss/core/slot.py | 11 +++++++ force_bdss/core/tests/test_slot.py | 10 +++++++ .../csv_extractor_data_source.py | 9 ++++++ .../dummy_data_source/dummy_data_source.py | 3 ++ .../dummy_kpi_calculator.py | 3 ++ .../dummy/kpi_adder/kpi_adder_calculator.py | 11 +++++++ force_bdss/data_sources/base_data_source.py | 14 ++++++--- .../tests/test_base_data_source.py | 3 ++ force_bdss/kpi/base_kpi_calculator.py | 29 +++++++++++++++++++ .../kpi/tests/test_base_kpi_calculator.py | 3 ++ .../tests/test_core_evaluation_driver.py | 6 ++++ 11 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 force_bdss/core/slot.py create mode 100644 force_bdss/core/tests/test_slot.py diff --git a/force_bdss/core/slot.py b/force_bdss/core/slot.py new file mode 100644 index 0000000..2218275 --- /dev/null +++ b/force_bdss/core/slot.py @@ -0,0 +1,11 @@ +from traits.api import HasStrictTraits, String + + +class Slot(HasStrictTraits): + """Describes an input or output slot in the DataSource or + KPICalculator""" + #: A textual description of the slot + description = String("No description") + + #: The CUBA key of the slot + type = String() diff --git a/force_bdss/core/tests/test_slot.py b/force_bdss/core/tests/test_slot.py new file mode 100644 index 0000000..b6c687e --- /dev/null +++ b/force_bdss/core/tests/test_slot.py @@ -0,0 +1,10 @@ +import unittest + +from force_bdss.core.slot import Slot + + +class TestSlot(unittest.TestCase): + def test_initialization(self): + slot = Slot() + self.assertEqual(slot.type, "") + self.assertEqual(slot.description, "No description") diff --git a/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py b/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py index 471f3ac..36f7297 100644 --- a/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py +++ b/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py @@ -1,5 +1,6 @@ import csv from force_bdss.api import BaseDataSource, DataValue +from force_bdss.core.slot import Slot class CSVExtractorDataSource(BaseDataSource): @@ -20,3 +21,11 @@ class CSVExtractorDataSource(BaseDataSource): break raise IndexError("Could not find specified data.") + + def slots(self, model): + return ( + (), + ( + Slot(type=model.cuba_type), + ) + ) diff --git a/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py b/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py index 03c36de..ac4dc61 100644 --- a/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py +++ b/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py @@ -4,3 +4,6 @@ from force_bdss.api import BaseDataSource class DummyDataSource(BaseDataSource): def run(self, model, parameters): return parameters + + def slots(self, model): + return (), () diff --git a/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py b/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py index bd10473..3e035cb 100644 --- a/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py +++ b/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py @@ -4,3 +4,6 @@ from force_bdss.api import BaseKPICalculator class DummyKPICalculator(BaseKPICalculator): def run(self, model, data_source_results): return data_source_results + + def slots(self, model): + return (), () diff --git a/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py b/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py index 94128b3..ff4b7ce 100644 --- a/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py +++ b/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py @@ -1,4 +1,5 @@ from force_bdss.api import BaseKPICalculator, DataValue +from force_bdss.core.slot import Slot class KPIAdderCalculator(BaseKPICalculator): @@ -16,3 +17,13 @@ class KPIAdderCalculator(BaseKPICalculator): type=model.cuba_type_out, value=sum )] + + def slots(self, model): + return ( + ( + Slot(type=model.cuba_type_in), + ), + ( + Slot(type=model.cuba_type_out), + ) + ) diff --git a/force_bdss/data_sources/base_data_source.py b/force_bdss/data_sources/base_data_source.py index e0283b5..be9fb39 100644 --- a/force_bdss/data_sources/base_data_source.py +++ b/force_bdss/data_sources/base_data_source.py @@ -55,8 +55,14 @@ class BaseDataSource(ABCHasStrictTraits): Returns ------- - list[tuple, tuple] - A list containing two tuples, the first element is the input slots, - the second element is the output slots. Each slot must be an - instance of the Slot class. + (input_slots, output_slots): tuple[tuple, tuple] + A tuple containing two tuples. + The first element is the input slots, the second element is + the output slots. Each slot must be an instance of the Slot class. + It is possible for each of the two inside tuples to be empty. + The case of an empty input slot is common: the DataSource does + not need any information from the MCO to operate. + The case of an empty output slot is uncommon, but supported: + the DataSource does not produce any output and is therefore + useless. """ diff --git a/force_bdss/data_sources/tests/test_base_data_source.py b/force_bdss/data_sources/tests/test_base_data_source.py index 810b5f6..a4de041 100644 --- a/force_bdss/data_sources/tests/test_base_data_source.py +++ b/force_bdss/data_sources/tests/test_base_data_source.py @@ -13,6 +13,9 @@ class DummyDataSource(BaseDataSource): def run(self, *args, **kwargs): pass + def slots(self, model): + return (), () + class TestBaseDataSource(unittest.TestCase): def test_initialization(self): diff --git a/force_bdss/kpi/base_kpi_calculator.py b/force_bdss/kpi/base_kpi_calculator.py index 1bb1bf4..b757dd4 100644 --- a/force_bdss/kpi/base_kpi_calculator.py +++ b/force_bdss/kpi/base_kpi_calculator.py @@ -38,3 +38,32 @@ class BaseKPICalculator(ABCHasStrictTraits): List[DataValue]: The result of this KPI evaluation, as a list of DataValues. """ + + @abc.abstractmethod + def slots(self, model): + """Returns the input (and output) slots of the KPI Calculator. + Slots are the entities that are needed (and produced) by this + KPI Calculator. + + The slots may depend on the configuration options, and thus the model. + This allows, for example, to change the slots depending if an option + is enabled or not. + + Parameters + ---------- + model: BaseKPICalculatorModel + The model of the KPICalculator, instantiated through create_model() + + Returns + ------- + (input_slots, output_slots): tuple[tuple, tuple] + A tuple containing two tuples. + The first element is the input slots, the second element is + the output slots. Each slot must be an instance of the Slot class. + It is possible for each of the two inside tuples to be empty. + The case of an empty input slot is common: the KPICalculator does + not need any information from the MCO to operate. + The case of an empty output slot is uncommon, but supported: + the KPICalculator does not produce any output and is therefore + useless. + """ diff --git a/force_bdss/kpi/tests/test_base_kpi_calculator.py b/force_bdss/kpi/tests/test_base_kpi_calculator.py index 5483835..334c191 100644 --- a/force_bdss/kpi/tests/test_base_kpi_calculator.py +++ b/force_bdss/kpi/tests/test_base_kpi_calculator.py @@ -12,6 +12,9 @@ class DummyKPICalculator(BaseKPICalculator): def run(self, *args, **kwargs): pass + def slots(self, model): + return (), () + class TestBaseKPICalculator(unittest.TestCase): def test_initialization(self): diff --git a/force_bdss/tests/test_core_evaluation_driver.py b/force_bdss/tests/test_core_evaluation_driver.py index 3ce8480..fc79b48 100644 --- a/force_bdss/tests/test_core_evaluation_driver.py +++ b/force_bdss/tests/test_core_evaluation_driver.py @@ -80,6 +80,9 @@ class NullKPICalculator(BaseKPICalculator): def run(self, model, data_source_results): return [] + def slots(self, model): + return (), () + class NullKPICalculatorBundle(BaseKPICalculatorBundle): def create_model(self, model_data=None): @@ -97,6 +100,9 @@ class NullDataSource(BaseDataSource): def run(self, model, parameters): return [] + def slots(self, model): + return (), () + class NullDataSourceBundle(BaseDataSourceBundle): def create_model(self, model_data=None): -- GitLab