Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename feature node to configuration node #75

Merged
merged 1 commit into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cfmtoolbox/__init__.py
Original file line number Diff line number Diff line change
@@ -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()
Expand All @@ -10,5 +10,5 @@
"Cardinality",
"Feature",
"Constraint",
"FeatureNode",
"ConfigurationNode",
]
8 changes: 4 additions & 4 deletions cfmtoolbox/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
6 changes: 3 additions & 3 deletions cfmtoolbox/plugins/one_wise_sampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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 = []
Expand Down Expand Up @@ -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=[],
)
Expand Down
6 changes: 3 additions & 3 deletions cfmtoolbox/plugins/random_sampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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)
Expand Down Expand Up @@ -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=[],
)
Expand Down
2 changes: 1 addition & 1 deletion docs/framework/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@

## ::: cfmtoolbox.models.Interval

## ::: cfmtoolbox.models.FeatureNode
## ::: cfmtoolbox.models.ConfigurationNode
135 changes: 70 additions & 65 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from cfmtoolbox.models import (
CFM,
Cardinality,
ConfigurationNode,
Constraint,
Feature,
FeatureNode,
Interval,
)

Expand Down Expand Up @@ -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", []),
],
]

Expand All @@ -256,7 +256,7 @@ def test_partition_children():
None,
[],
),
FeatureNode("Sandwich#0", []),
ConfigurationNode("Sandwich#0", []),
True,
),
(
Expand All @@ -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

Expand All @@ -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)]),
Expand Down Expand Up @@ -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)]),
Expand Down Expand Up @@ -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", []),
],
),
],
Expand All @@ -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)
Expand Down Expand Up @@ -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", []),
],
),
],
Expand Down
Loading