Goal:
ExperimentConfig Base class that defines the abstract methods and attributes that should be inherited by any subclass. I would like to standardize the features of the ExperimentConfig; parameters load from a JSON, however, they are only useful if I create a @property function for them. I would like any ExperimentConfig to gracefully load all JSON parameters in such a way that they can be called and used across a GUI software, even edited, while still retaining some form of immutability
import os
import json
import pandas as pd
from abc import ABC, abstractmethod
class ExperimentConfigBase(ABC):
"""
A base class for ExperimentConfig implementations.
Features:
- Gracefully loads parameters from a JSON file.
- Provides read-only access to parameters outside the class.
- Defines abstract methods for saving configuration, which must be implemented by subclasses.
- Facilitates GUI usage by offering methods to convert parameters to a DataFrame.
Note:
While parameters can be updated via update_parameter, the parameters property returns a copy to
help preserve immutability outside the class.
"""
def __init__(self, path: str):
self._parameters: dict = {}
self._json_file_path: str = ""
self._save_dir: str = os.path.abspath(path)
self.notes: list[str] = []
def load_parameters(self, json_file_path: str) -> None:
"""
Loads parameters from a JSON file.
The loaded parameters are stored in a private dictionary.
"""
try:
with open(json_file_path, 'r') as f:
self._parameters = json.load(f)
self._json_file_path = json_file_path
except FileNotFoundError:
print(f"File not found: {json_file_path}")
except json.JSONDecodeError as e:
print(f"Error decoding JSON: {e}")
def update_parameter(self, key, value) -> None:
"""
Updates a configuration parameter.
Override this method in subclasses if you want to enforce stricter immutability.
"""
self._parameters[key] = value
@property
def parameters(self) -> dict:
"""
Returns an immutable copy of the parameters.
This prevents external code from directly modifying the configuration.
"""
return self._parameters.copy()
def to_dataframe(self) -> pd.DataFrame:
"""
Converts the configuration parameters to a pandas DataFrame,
useful for displaying in GUI tables or exporting.
"""
data = {
'Parameter': list(self._parameters.keys()),
'Value': list(self._parameters.values())
}
return pd.DataFrame(data)
@abstractmethod
def save_configuration(self) -> None:
"""
Save the configuration parameters and any associated notes/data.
Subclasses must implement the file saving routines.
"""
pass