From d582cde8155760ee18b7e7f524add292112befe8 Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Sat, 21 Sep 2024 19:56:03 +0200 Subject: [PATCH] Rename feature node to configuration node --- cfmtoolbox/__init__.py | 4 +- cfmtoolbox/models.py | 8 +- cfmtoolbox/plugins/one_wise_sampling.py | 6 +- cfmtoolbox/plugins/random_sampling.py | 6 +- docs/framework/models.md | 2 +- tests/test_models.py | 135 ++++++++++++------------ 6 files changed, 83 insertions(+), 78 deletions(-) diff --git a/cfmtoolbox/__init__.py b/cfmtoolbox/__init__.py index 6fab80e..28ddf6f 100644 --- a/cfmtoolbox/__init__.py +++ b/cfmtoolbox/__init__.py @@ -1,4 +1,4 @@ -from .models import CFM, Cardinality, Constraint, Feature, FeatureNode, Interval +from .models import CFM, Cardinality, ConfigurationNode, Constraint, Feature, Interval from .toolbox import CFMToolbox app = CFMToolbox() @@ -10,5 +10,5 @@ "Cardinality", "Feature", "Constraint", - "FeatureNode", + "ConfigurationNode", ] diff --git a/cfmtoolbox/models.py b/cfmtoolbox/models.py index 683ea09..b189cbe 100644 --- a/cfmtoolbox/models.py +++ b/cfmtoolbox/models.py @@ -131,13 +131,13 @@ def is_unbound(self) -> bool: @dataclass -class FeatureNode: - """Dataclass representing an instantiated feature from a feature model.""" +class ConfigurationNode: + """Dataclass representing configuration of a CFM feature.""" value: str """Value of the feature node.""" - children: list["FeatureNode"] + children: list["ConfigurationNode"] """List of child feature nodes.""" def validate(self, cfm: CFM) -> bool: @@ -216,7 +216,7 @@ def validate_children(self, feature: Feature) -> bool: return True - def partition_children(self, feature: Feature) -> list[list["FeatureNode"]]: + def partition_children(self, feature: Feature) -> list[list["ConfigurationNode"]]: sublists = [] i = 0 for model_child in feature.children: diff --git a/cfmtoolbox/plugins/one_wise_sampling.py b/cfmtoolbox/plugins/one_wise_sampling.py index 294f350..a300fd0 100644 --- a/cfmtoolbox/plugins/one_wise_sampling.py +++ b/cfmtoolbox/plugins/one_wise_sampling.py @@ -7,7 +7,7 @@ import typer from cfmtoolbox import app -from cfmtoolbox.models import CFM, Cardinality, Feature, FeatureNode +from cfmtoolbox.models import CFM, Cardinality, ConfigurationNode, Feature @app.command() @@ -42,7 +42,7 @@ def __init__(self, model: CFM): self.chosen_assignment: tuple[str, int] self.model = model - def one_wise_sampling(self) -> list[FeatureNode]: + def one_wise_sampling(self) -> list[ConfigurationNode]: self.calculate_border_assignments(self.model.root) samples = [] @@ -85,7 +85,7 @@ def generate_random_feature_node_with_assignment( self, feature: Feature, ): - feature_node = FeatureNode( + feature_node = ConfigurationNode( value=f"{feature.name}#{self.global_feature_count[feature.name]}", children=[], ) diff --git a/cfmtoolbox/plugins/random_sampling.py b/cfmtoolbox/plugins/random_sampling.py index e2bdf15..85d8f37 100644 --- a/cfmtoolbox/plugins/random_sampling.py +++ b/cfmtoolbox/plugins/random_sampling.py @@ -7,7 +7,7 @@ import typer from cfmtoolbox import app -from cfmtoolbox.models import CFM, Cardinality, Feature, FeatureNode +from cfmtoolbox.models import CFM, Cardinality, ConfigurationNode, Feature @app.command() @@ -34,7 +34,7 @@ def __init__(self, model: CFM): self.global_feature_count: defaultdict[str, int] = defaultdict(int) self.model = model - def random_sampling(self) -> FeatureNode: + def random_sampling(self) -> ConfigurationNode: while True: self.global_feature_count = defaultdict(int) random_feature_node = self.generate_random_feature_node(self.model.root) @@ -69,7 +69,7 @@ def generate_random_feature_node( self, feature: Feature, ): - feature_node = FeatureNode( + feature_node = ConfigurationNode( value=f"{feature.name}#{self.global_feature_count[feature.name]}", children=[], ) diff --git a/docs/framework/models.md b/docs/framework/models.md index 268167d..df7c4f2 100644 --- a/docs/framework/models.md +++ b/docs/framework/models.md @@ -6,4 +6,4 @@ ## ::: cfmtoolbox.models.Interval -## ::: cfmtoolbox.models.FeatureNode +## ::: cfmtoolbox.models.ConfigurationNode diff --git a/tests/test_models.py b/tests/test_models.py index 0271f8d..e5283ed 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -5,9 +5,9 @@ from cfmtoolbox.models import ( CFM, Cardinality, + ConfigurationNode, Constraint, Feature, - FeatureNode, Interval, ) @@ -224,22 +224,22 @@ def test_partition_children(): ), ], ) - feature_node = FeatureNode( + feature_node = ConfigurationNode( "Sandwich", [ - FeatureNode("Bread#0", []), - FeatureNode("Bread#1", []), - FeatureNode("Meat#0", []), + ConfigurationNode("Bread#0", []), + ConfigurationNode("Bread#1", []), + ConfigurationNode("Meat#0", []), ], ) assert feature_node.partition_children(feature) == [ [ - FeatureNode("Bread#0", []), - FeatureNode("Bread#1", []), + ConfigurationNode("Bread#0", []), + ConfigurationNode("Bread#1", []), ], [], [ - FeatureNode("Meat#0", []), + ConfigurationNode("Meat#0", []), ], ] @@ -256,7 +256,7 @@ def test_partition_children(): None, [], ), - FeatureNode("Sandwich#0", []), + ConfigurationNode("Sandwich#0", []), True, ), ( @@ -268,13 +268,13 @@ def test_partition_children(): None, [], ), - FeatureNode("Sandwich#0", [FeatureNode("Bread#0", [])]), + ConfigurationNode("Sandwich#0", [ConfigurationNode("Bread#0", [])]), False, ), ], ) def test_validate_children_no_children( - feature: Feature, feature_instance: FeatureNode, expectation: bool + feature: Feature, feature_instance: ConfigurationNode, expectation: bool ): assert feature_instance.validate_children(feature) == expectation @@ -283,46 +283,46 @@ def test_validate_children_no_children( ["feature_instance", "expectation"], [ ( - FeatureNode("Sandwich#0", [FeatureNode("Bread#0", [])]), + ConfigurationNode("Sandwich#0", [ConfigurationNode("Bread#0", [])]), False, ), ( - FeatureNode( + ConfigurationNode( "Sandwich#0", [ - FeatureNode("Bread#0", []), - FeatureNode("Bread#1", []), - FeatureNode("Bread#2", []), + ConfigurationNode("Bread#0", []), + ConfigurationNode("Bread#1", []), + ConfigurationNode("Bread#2", []), ], ), False, ), ( - FeatureNode( + ConfigurationNode( "Sandwich#0", [ - FeatureNode("Bread#0", []), - FeatureNode("Bread#1", []), - FeatureNode("Bread#2", []), - FeatureNode("Cheese#0", []), + ConfigurationNode("Bread#0", []), + ConfigurationNode("Bread#1", []), + ConfigurationNode("Bread#2", []), + ConfigurationNode("Cheese#0", []), ], ), False, ), ( - FeatureNode( + ConfigurationNode( "Sandwich#0", [ - FeatureNode("Bread#0", []), - FeatureNode("Bread#1", []), - FeatureNode("Cheese#0", []), + ConfigurationNode("Bread#0", []), + ConfigurationNode("Bread#1", []), + ConfigurationNode("Cheese#0", []), ], ), True, ), ], ) -def test_validate_children(feature_instance: FeatureNode, expectation: bool): +def test_validate_children(feature_instance: ConfigurationNode, expectation: bool): feature = Feature( "Sandwich", Cardinality([Interval(1, 1)]), @@ -363,37 +363,42 @@ def test_validate_children(feature_instance: FeatureNode, expectation: bool): ["feature_instance", "expectation"], [ ( - FeatureNode("Milkshake#0", []), + ConfigurationNode("Milkshake#0", []), False, ), ( - FeatureNode( + ConfigurationNode( "Sandwich#0", [ - FeatureNode( + ConfigurationNode( "Bread#0", - [FeatureNode("Wheat#0", []), FeatureNode("Wheat#0", [])], + [ + ConfigurationNode("Wheat#0", []), + ConfigurationNode("Wheat#0", []), + ], ), - FeatureNode("Bread#1", []), - FeatureNode("Cheese#0", []), + ConfigurationNode("Bread#1", []), + ConfigurationNode("Cheese#0", []), ], ), False, ), ( - FeatureNode( + ConfigurationNode( "Sandwich#0", [ - FeatureNode("Bread#0", [FeatureNode("Wheat#0", [])]), - FeatureNode("Bread#1", [FeatureNode("Wheat#0", [])]), - FeatureNode("Cheese#0", []), + ConfigurationNode("Bread#0", [ConfigurationNode("Wheat#0", [])]), + ConfigurationNode("Bread#1", [ConfigurationNode("Wheat#0", [])]), + ConfigurationNode("Cheese#0", []), ], ), True, ), ], ) -def test_validate_feature_instance(feature_instance: FeatureNode, expectation: bool): +def test_validate_feature_instance( + feature_instance: ConfigurationNode, expectation: bool +): feature = Feature( "Sandwich", Cardinality([Interval(1, 1)]), @@ -452,40 +457,40 @@ def test_validate_feature_instance(feature_instance: FeatureNode, expectation: b ["feature_instance", "expectation"], [ ( - FeatureNode("Milkshake#0", []), + ConfigurationNode("Milkshake#0", []), {"Milkshake": 1}, ), ( - FeatureNode( + ConfigurationNode( "Sandwich#0", [ - FeatureNode("Bread#0", [FeatureNode("Wheat#0", [])]), - FeatureNode("Bread#1", [FeatureNode("Wheat#1", [])]), - FeatureNode("Cheese#0", []), + ConfigurationNode("Bread#0", [ConfigurationNode("Wheat#0", [])]), + ConfigurationNode("Bread#1", [ConfigurationNode("Wheat#1", [])]), + ConfigurationNode("Cheese#0", []), ], ), {"Sandwich": 1, "Bread": 2, "Wheat": 2, "Cheese": 1}, ), ( - FeatureNode( + ConfigurationNode( "Sandwich#0", [ - FeatureNode("Bread#0", [FeatureNode("Wheat#0", [])]), - FeatureNode("Bread#1", [FeatureNode("Wheat#1", [])]), - FeatureNode( + ConfigurationNode("Bread#0", [ConfigurationNode("Wheat#0", [])]), + ConfigurationNode("Bread#1", [ConfigurationNode("Wheat#1", [])]), + ConfigurationNode( "Cheese-mix#0", [ - FeatureNode("Swiss#0", []), - FeatureNode("Gouda#0", []), - FeatureNode("Gouda#1", []), + ConfigurationNode("Swiss#0", []), + ConfigurationNode("Gouda#0", []), + ConfigurationNode("Gouda#1", []), ], ), - FeatureNode( + ConfigurationNode( "Cheese-mix#1", [ - FeatureNode("Swiss#1", []), - FeatureNode("Gouda#2", []), - FeatureNode("Cheddar#0", []), + ConfigurationNode("Swiss#1", []), + ConfigurationNode("Gouda#2", []), + ConfigurationNode("Cheddar#0", []), ], ), ], @@ -503,7 +508,7 @@ def test_validate_feature_instance(feature_instance: FeatureNode, expectation: b ], ) def test_initialize_global_feature_count( - feature_instance: FeatureNode, expectation: defaultdict[str, int] + feature_instance: ConfigurationNode, expectation: defaultdict[str, int] ): global_feature_count: defaultdict[str, int] = defaultdict(int) feature_instance.initialize_global_feature_count(global_feature_count) @@ -700,25 +705,25 @@ def test_validate_constraints( constraints: list[Constraint], expectation: bool, ): - feature_instance = FeatureNode( + feature_instance = ConfigurationNode( "Sandwich#0", [ - FeatureNode("Bread#0", [FeatureNode("Wheat#0", [])]), - FeatureNode("Bread#1", [FeatureNode("Wheat#1", [])]), - FeatureNode( + ConfigurationNode("Bread#0", [ConfigurationNode("Wheat#0", [])]), + ConfigurationNode("Bread#1", [ConfigurationNode("Wheat#1", [])]), + ConfigurationNode( "Cheese-mix#0", [ - FeatureNode("Swiss#0", []), - FeatureNode("Gouda#0", []), - FeatureNode("Gouda#1", []), + ConfigurationNode("Swiss#0", []), + ConfigurationNode("Gouda#0", []), + ConfigurationNode("Gouda#1", []), ], ), - FeatureNode( + ConfigurationNode( "Cheese-mix#1", [ - FeatureNode("Swiss#1", []), - FeatureNode("Gouda#2", []), - FeatureNode("Cheddar#0", []), + ConfigurationNode("Swiss#1", []), + ConfigurationNode("Gouda#2", []), + ConfigurationNode("Cheddar#0", []), ], ), ],