Skip to content

Commit

Permalink
fix: pass prospector and fix sampling and product interfaces (#119)
Browse files Browse the repository at this point in the history
* Fix some prospector and hint typing

* Fix sampling and product interface
  • Loading branch information
jmhorcas authored May 10, 2024
1 parent 4ee9ae3 commit 87c2ac7
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 65 deletions.
5 changes: 2 additions & 3 deletions flamapy/core/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ def use_operation(self, src: VariabilityModel, operation_name: str) -> Operation
operation = plugin.get_operation(operation_name)
return plugin.use_operation(operation, src)


def use_operation_from_vm(
self,
operation_name: str,
Expand Down Expand Up @@ -218,15 +217,15 @@ def use_operation_from_vm(
operation = plugin.use_operation(operation, vm_temp)

return operation.get_result()

def use_operation_from_file(
self,
operation_name: str,
file: str,
plugin_name: Optional[str] = None,
configuration_file: Optional[str] = None
) -> Any:

if operation_name not in self.get_name_operations():
raise OperationNotFound()

Expand Down
4 changes: 3 additions & 1 deletion flamapy/core/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
class FlamaException(Exception):
pass


class ParsingException(Exception):
pass


class PluginNotFound(FlamaException):
pass

Expand All @@ -25,4 +27,4 @@ class DuplicatedFeature(FlamaException):


class ConfigurationNotFound(FlamaException):
pass
pass
4 changes: 2 additions & 2 deletions flamapy/core/models/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ASTOperation(Enum):
EQUALS = 'EQUALS'
LOWER = 'LOWER'
GREATER = 'GREATER'
LOWER_EQUALS = 'LOWER_EQUALS'
LOWER_EQUALS = 'LOWER_EQUALS'
GREATER_EQUALS = 'GREATER_EQUALS'
NOT_EQUALS = 'NOT_EQUALS'
# Arithmetic operators
Expand All @@ -24,7 +24,7 @@ class ASTOperation(Enum):
MUL = 'MUL'
DIV = 'DIV'
# Aggregation operators
SUM ='SUM'
SUM = 'SUM'
AVG = 'AVG'
# Set operators
LEN = 'LEN'
Expand Down
1 change: 1 addition & 0 deletions flamapy/core/models/variability_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ def get_extension() -> str:


class VariabilityElement():

def __init__(self, name: str) -> None:
self.name = name
94 changes: 47 additions & 47 deletions flamapy/core/operations/metrics_operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
import json

from typing import Any, Callable,List, Tuple, Union, Optional, Collection, Dict
from typing import Any, Optional, Collection

from flamapy.core.exceptions import FlamaException
from flamapy.core.transformations.model_to_model import ModelToModel
Expand All @@ -13,93 +13,93 @@


class Metrics(Operation):
"""This is intended to host a set of metrics calculations for a variability model. This abstract class will recruit all its implementations and agregate the results
"""This is intended to host a set of metrics calculations for a variability model.
This abstract class will recruit all its implementations and agregate the results
"""
filter: Optional[List[str]] = None
result: List[Dict[str, Any]] = []
filter: Optional[list[str]] = None
result: list[dict[str, Any]] = []

def __init__(self) -> None:
self.model: Optional[VariabilityModel] = None

@abstractmethod
def calculate_metamodel_metrics(
self,
model: VariabilityModel,
) -> List[Dict[str, Any]]:
"""Return a list of metrics for each metamodel"""
def calculate_metamodel_metrics(self, model: VariabilityModel) -> list[dict[str, Any]]:
"""Return a list of metrics for each metamodel."""

def only_these_metrics(self, filter: List[str]) -> None:
self.filter = filter
def only_these_metrics(self, filter_metrics: list[str]) -> None:
self.filter = filter_metrics

def execute(self, model: VariabilityModel) -> 'Metrics':
self.model = model
#Identifying all implementations of MetricsOperation
# Identifying all implementations of MetricsOperation

for subclass in Metrics.__subclasses__():
#We first have to identify the metamodels that are being used and transform this model to the correspointing metamodel
metrics_operation=subclass()

# We first have to identify the metamodels that are being used and
# transform this model to the correspointing metamodel
metrics_operation = subclass()

if self.model.__class__.get_extension() == metrics_operation.model_type_extension:
#if its the metamodel that math the model, calculate the metrics
#Then we calculate the metrics for each metamodel
# If its the metamodel that math the model, calculate the metrics
# Then we calculate the metrics for each metamodel
self.result.append(subclass().calculate_metamodel_metrics(model))
else:
#if not, search a transformation, transform and call the calutation
m_to_m=self._search_transformations(self.model.__class__.get_extension(),metrics_operation.model_type_extension)
dest_model=m_to_m(self.model).transform()
# If not, search a transformation, transform and call the calutation
m_to_m = self._search_transformations(self.model.__class__.get_extension(),
metrics_operation.model_type_extension)
dest_model = m_to_m(self.model).transform()
self.result.append(subclass().calculate_metamodel_metrics(dest_model))
return self

def _search_transformations(self,orig:str,dest:str) -> ModelToModel:
result=[]

def _search_transformations(self, orig: str, dest: str) -> ModelToModel:
try:
for m_to_m in ModelToModel.__subclasses__():
_orig = m_to_m.get_source_extension()
_dest = m_to_m.get_destination_extension()
if (_orig==orig and _dest==dest):
if (_orig == orig and _dest == dest):
return m_to_m
except FlamaException("No transformation found that is required in the Metrics operation"):
except FlamaException:
LOGGER.exception("No transformation found that is required in the Metrics operation")
raise FlamaException("No transformation found")

@staticmethod
def get_result(self) -> List[Dict[str, Any]]:
def get_result(self) -> list[dict[str, Any]]:
return self.result
def get_result_json(self):
json_object = json.dumps(self.get_result(), indent = 4)
return json_object

def get_result_json(self) -> str:
return json.dumps(self.get_result(), indent=4)

@staticmethod
def get_ratio(collection1: Collection, collection2: Collection, precision: int = 4) -> float:
def get_ratio(collection1: Collection[Any],
collection2: Collection[Any],
precision: int = 4) -> float:
if not collection1 and not collection2:
# Handle case where both collections are empty
return 0.0
if not collection2:
return 0.0
return float(round(len(collection1) / len(collection2), precision))

@staticmethod
def construct_result(
name: Optional[str] = None,
doc: Optional[str] = None,
result: Optional[Any] = None,
size: Optional[int] = None,
ratio: Optional[float] = None
) -> Dict[str, Any]:
def construct_result(name: Optional[str] = None,
doc: Optional[str] = None,
result: Optional[Any] = None,
size: Optional[int] = None,
ratio: Optional[float] = None
) -> dict[str, Any]:
"""Constructs a dictionary with named keys from the provided list and other arguments.
property name: The property name.
description: The description of the property
value (optional): the list of abstract features.
size (optional): the length of the list.
ratio (optional): the percentage of abstract features with regards the total number of features."""

ratio (optional): the percentage of abstract features with regards the total number
of features.
"""

return {
"name": name or "Default Name", # Using a default value if name is None
"documentation": doc or "Default Documentation",
"result": result or [],
"size": size or 0,
"ratio": ratio or 0.0
}

@staticmethod
def only_these_metrics(self, filter: List[str]) -> None:
self.filter = filter
4 changes: 2 additions & 2 deletions flamapy/core/operations/products.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from abc import abstractmethod
from typing import Any

from flamapy.core.operations import Operation
from flamapy.metamodels.configuration_metamodel.models.configuration import Configuration


class Products(Operation):
Expand All @@ -11,5 +11,5 @@ def __init__(self) -> None:
pass

@abstractmethod
def get_products(self) -> list[Any]:
def get_products(self) -> list[Configuration]:
pass
28 changes: 18 additions & 10 deletions flamapy/core/operations/sampling.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from abc import abstractmethod
from typing import Optional

from flamapy.metamodels.configuration_metamodel.models.configuration import Configuration
from flamapy.core.operations import Operation
Expand All @@ -11,12 +10,21 @@ class Sampling(Operation):
"""

@abstractmethod
def sample(self, size: int, with_replacement: bool = False,
partial_configuration: Optional[Configuration] = None) -> list[Configuration]:
"""Return a sample of configurations.
Keyword arguments:
size -- number of configurations of the sample.
with_replacement -- allow repeated configurations in the sample (default False).
partial_configuration -- from which the sample is built (default empty configuration).
"""
def __init__(self) -> None:
pass

@abstractmethod
def set_sample_size(self, sample_size: int) -> None:
"""Number of configurations of the sample."""

@abstractmethod
def set_with_replacement(self, with_replacement: bool) -> None:
"Allow repeated configurations in the sample (default False)."

@abstractmethod
def set_partial_configuration(self, partial_configuration: Configuration) -> None:
"From which the sample is built (default empty configuration)."

@abstractmethod
def get_sample(self) -> list[Configuration]:
"""Return a sample of configurations."""

0 comments on commit 87c2ac7

Please sign in to comment.