Skip to content

quast_decisiontree.problems.input_parser

quast_decisiontree.problems.input_parser

logger module-attribute

logger = logging.getLogger('dt_logger')

discover_types

discover_types(refresh=False)

discovers all available problem types - subclasses of OptimizationProblem

The result is cached after the first call. Pass refresh=True to force a rescan, e.g. when problem classes are registered after the initial import.

Returns a list of classes implementing specific optimization problem types.

Source code in src/quast_decisiontree/problems/input_parser.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
def discover_types(refresh: bool = False) -> list:
    """discovers all available problem types - subclasses of OptimizationProblem

    The result is cached after the first call. Pass refresh=True to force a rescan,
    e.g. when problem classes are registered after the initial import.

    Returns a list of classes implementing specific optimization problem types.
    """
    global _problem_types
    if _problem_types is not None and not refresh:
        return _problem_types

    import_problem_classes()
    _problem_types = OptimizationProblem.__subclasses__()
    if not _problem_types:
        logger.warning(
            "Couldn't discover any concrete optimization problem types. Catch this error if this"
            " is intended."
        )
    return _problem_types

import_problem_classes

import_problem_classes()

Import all concrete problem modules so their classes register as OptimizationProblem subclasses.

Lazy-loaded packages do not execute their submodules on package import, so each submodule must be imported explicitly.

Source code in src/quast_decisiontree/problems/input_parser.py
48
49
50
51
52
53
54
55
56
def import_problem_classes() -> None:
    """Import all concrete problem modules so their classes register as
    OptimizationProblem subclasses.

    Lazy-loaded packages do not execute their submodules on package import,
    so each submodule must be imported explicitly.
    """
    for module_name in _class_submodules:
        importlib.import_module("." + module_name, package="quast_decisiontree.problems.classes")

from_json

from_json(file)

attempts to create an optimization problem instance with the data specified in the given json

file: Any specification compatible with the json.loads() method (str, bytes or bytearray containing a JSON file)

Returns: OptimizationProblem: An instance of the appropriate OptimizationProblem class.

Source code in src/quast_decisiontree/problems/input_parser.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def from_json(file: Any) -> OptimizationProblem:
    """attempts to create an optimization problem instance with the data specified
    in the given json

    Args:
    file: Any specification compatible with the json.loads() method (str, bytes or bytearray
        containing a JSON file)

    Returns:
    OptimizationProblem: An instance of the appropriate OptimizationProblem class.
    """
    with open(file) as f:
        data = json.load(f)
    return from_dict(data)

from_dict

from_dict(problem_dict)

attempts to create an optimization problem instance with the data specified in the given dict

InvalidProblemDictError: If problem_class is missing, not a string, or cannot be matched with an existing OptimizationProblem child class.

Returns: OptimizationProblem: A problem instance of the appropriate OptimizationProblem class

Source code in src/quast_decisiontree/problems/input_parser.py
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def from_dict(problem_dict: Mapping) -> OptimizationProblem:
    """attempts to create an optimization problem instance with the data specified in the
    given dict

    Raises:
    InvalidProblemDictError: If problem_class is missing, not a string, or cannot be matched
        with an existing OptimizationProblem child class.

    Returns:
    OptimizationProblem: A problem instance of the appropriate OptimizationProblem class
    """
    problem_class = problem_dict.get("problem_class")
    if problem_class is None:
        raise InvalidProblemDictError("Problem dict is missing required key 'problem_class'.")
    if not isinstance(problem_class, str):
        raise InvalidProblemDictError(
            f"'problem_class' must be a string, got {type(problem_class).__name__!r}."
        )

    target = problem_class.lower()
    class_obj = None
    for pc in discover_types():
        names = [pc.__name__]
        aliases = getattr(pc, "alias", [])
        if isinstance(aliases, str):
            logger.warning(
                "Problem class %r declares its alias as a bare string %r; expected an iterable "
                "of strings. Treating it as a single alias.",
                pc.__name__,
                aliases,
            )
            aliases = [aliases]
        names.extend(aliases)
        if any(target == name.lower() for name in names):
            class_obj = pc
            break

    if class_obj is None:
        raise InvalidProblemDictError(
            f"Couldn't find a matching problem class for specification {problem_class!r}."
        )

    return class_obj.from_dict(problem_dict)

save_problem_instance

save_problem_instance(
    instance, folder, filename="problem_instance.json"
)
Source code in src/quast_decisiontree/problems/input_parser.py
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
def save_problem_instance(
    instance: OptimizationProblem, folder: str, filename="problem_instance.json"
) -> str | None:
    try:
        save_dict = instance.to_dict()
    except NotImplementedError:
        logger.warning(
            "Cannot save problem instance of type %r: to_dict is not implemented.",
            type(instance).__name__,
        )
        return None

    save_dict = deep_convert(save_dict)
    instance_file = os.path.join(folder, filename)
    with open(instance_file, "w", encoding="utf8") as file:
        json.dump(save_dict, file, indent=4)

    return instance_file