ripple-down-rules 0.3.0__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ripple_down_rules/datasets.py +5 -0
- ripple_down_rules/datastructures/enums.py +14 -0
- ripple_down_rules/experts.py +14 -7
- ripple_down_rules/rdr.py +6 -2
- ripple_down_rules/user_interface/__init__.py +0 -0
- ripple_down_rules/user_interface/gui.py +630 -0
- ripple_down_rules/user_interface/ipython_custom_shell.py +146 -0
- ripple_down_rules/user_interface/object_diagram.py +109 -0
- ripple_down_rules/user_interface/prompt.py +159 -0
- ripple_down_rules/user_interface/template_file_creator.py +293 -0
- ripple_down_rules/utils.py +2 -2
- {ripple_down_rules-0.3.0.dist-info → ripple_down_rules-0.4.0.dist-info}/METADATA +8 -1
- ripple_down_rules-0.4.0.dist-info/RECORD +25 -0
- ripple_down_rules/prompt.py +0 -510
- ripple_down_rules-0.3.0.dist-info/RECORD +0 -20
- {ripple_down_rules-0.3.0.dist-info → ripple_down_rules-0.4.0.dist-info}/WHEEL +0 -0
- {ripple_down_rules-0.3.0.dist-info → ripple_down_rules-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {ripple_down_rules-0.3.0.dist-info → ripple_down_rules-0.4.0.dist-info}/top_level.txt +0 -0
ripple_down_rules/datasets.py
CHANGED
@@ -18,6 +18,8 @@ from .rdr_decorators import RDRDecorator
|
|
18
18
|
def load_cached_dataset(cache_file):
|
19
19
|
"""Loads the dataset from cache if it exists."""
|
20
20
|
dataset = {}
|
21
|
+
if '.pkl' not in cache_file:
|
22
|
+
cache_file += ".pkl"
|
21
23
|
for key in ["features", "targets", "ids"]:
|
22
24
|
part_file = cache_file.replace(".pkl", f"_{key}.pkl")
|
23
25
|
if not os.path.exists(part_file):
|
@@ -43,6 +45,9 @@ def save_dataset_to_cache(dataset, cache_file):
|
|
43
45
|
|
44
46
|
def get_dataset(dataset_id, cache_file: Optional[str] = None):
|
45
47
|
"""Fetches dataset from cache or downloads it if not available."""
|
48
|
+
if cache_file is not None:
|
49
|
+
if not cache_file.endswith(".pkl"):
|
50
|
+
cache_file += ".pkl"
|
46
51
|
dataset = load_cached_dataset(cache_file) if cache_file else None
|
47
52
|
if dataset is None:
|
48
53
|
print("Downloading dataset...")
|
@@ -7,6 +7,20 @@ from typing_extensions import List, Dict, Any, Type
|
|
7
7
|
from ripple_down_rules.utils import SubclassJSONSerializer
|
8
8
|
|
9
9
|
|
10
|
+
class InteractionMode(Enum):
|
11
|
+
"""
|
12
|
+
The interaction mode of the RDR.
|
13
|
+
"""
|
14
|
+
IPythonOnly = auto()
|
15
|
+
"""
|
16
|
+
IPythonOnly mode, the mode where the user uses only an Ipython shell to interact with the RDR.
|
17
|
+
"""
|
18
|
+
GUI = auto()
|
19
|
+
"""
|
20
|
+
GUI mode, the mode where the user uses a GUI to interact with the RDR.
|
21
|
+
"""
|
22
|
+
|
23
|
+
|
10
24
|
class Editor(str, Enum):
|
11
25
|
"""
|
12
26
|
The editor that is used to edit the rules.
|
ripple_down_rules/experts.py
CHANGED
@@ -3,15 +3,14 @@ from __future__ import annotations
|
|
3
3
|
import json
|
4
4
|
from abc import ABC, abstractmethod
|
5
5
|
|
6
|
-
from typing_extensions import Optional,
|
6
|
+
from typing_extensions import Optional, TYPE_CHECKING, List
|
7
7
|
|
8
|
-
from .datastructures.case import Case, CaseAttribute
|
9
8
|
from .datastructures.callable_expression import CallableExpression
|
10
9
|
from .datastructures.enums import PromptFor
|
11
10
|
from .datastructures.dataclasses import CaseQuery
|
12
11
|
from .datastructures.case import show_current_and_corner_cases
|
13
|
-
from .
|
14
|
-
from .
|
12
|
+
from .user_interface.gui import RDRCaseViewer
|
13
|
+
from .user_interface.prompt import UserPrompt
|
15
14
|
|
16
15
|
if TYPE_CHECKING:
|
17
16
|
from .rdr import Rule
|
@@ -66,12 +65,20 @@ class Human(Expert):
|
|
66
65
|
The Human Expert class, an expert that asks the human to provide differentiating features and conclusions.
|
67
66
|
"""
|
68
67
|
|
68
|
+
def __init__(self, use_loaded_answers: bool = False, append: bool = False, viewer: Optional[RDRCaseViewer] = None):
|
69
|
+
"""
|
70
|
+
Initialize the Human expert.
|
71
|
+
|
72
|
+
:param viewer: The RDRCaseViewer instance to use for prompting the user.
|
73
|
+
"""
|
74
|
+
super().__init__(use_loaded_answers=use_loaded_answers, append=append)
|
75
|
+
self.user_prompt = UserPrompt(viewer)
|
76
|
+
|
69
77
|
def save_answers(self, path: str):
|
70
78
|
"""
|
71
79
|
Save the expert answers to a file.
|
72
80
|
|
73
81
|
:param path: The path to save the answers to.
|
74
|
-
:param append: A flag to indicate if the answers should be appended to the file or not.
|
75
82
|
"""
|
76
83
|
if self.append:
|
77
84
|
# read the file and append the new answers
|
@@ -118,7 +125,7 @@ class Human(Expert):
|
|
118
125
|
if user_input:
|
119
126
|
condition = CallableExpression(user_input, bool, scope=case_query.scope)
|
120
127
|
else:
|
121
|
-
user_input, condition = prompt_user_for_expression(case_query, PromptFor.Conditions)
|
128
|
+
user_input, condition = self.user_prompt.prompt_user_for_expression(case_query, PromptFor.Conditions)
|
122
129
|
if not self.use_loaded_answers:
|
123
130
|
self.all_expert_answers.append(user_input)
|
124
131
|
case_query.conditions = condition
|
@@ -142,7 +149,7 @@ class Human(Expert):
|
|
142
149
|
mutually_exclusive=case_query.mutually_exclusive)
|
143
150
|
else:
|
144
151
|
show_current_and_corner_cases(case_query.case)
|
145
|
-
expert_input, expression = prompt_user_for_expression(case_query, PromptFor.Conclusion)
|
152
|
+
expert_input, expression = self.user_prompt.prompt_user_for_expression(case_query, PromptFor.Conclusion)
|
146
153
|
self.all_expert_answers.append(expert_input)
|
147
154
|
case_query.target = expression
|
148
155
|
return expression
|
ripple_down_rules/rdr.py
CHANGED
@@ -883,10 +883,12 @@ class GeneralRDR(RippleDownRules):
|
|
883
883
|
f.write(f"{' ' * 4}return GeneralRDR._classify(classifiers_dict, case)\n")
|
884
884
|
|
885
885
|
@property
|
886
|
-
def case_type(self) -> Type:
|
886
|
+
def case_type(self) -> Optional[Type]:
|
887
887
|
"""
|
888
888
|
:return: The type of the case (input) to the RDR classifier.
|
889
889
|
"""
|
890
|
+
if self.start_rule is None or self.start_rule.corner_case is None:
|
891
|
+
return None
|
890
892
|
if isinstance(self.start_rule.corner_case, Case):
|
891
893
|
return self.start_rule.corner_case._obj_type
|
892
894
|
else:
|
@@ -900,10 +902,12 @@ class GeneralRDR(RippleDownRules):
|
|
900
902
|
return importlib.import_module(f"{file_path.strip('./')}.{self.generated_python_file_name}").classify
|
901
903
|
|
902
904
|
@property
|
903
|
-
def _default_generated_python_file_name(self) -> str:
|
905
|
+
def _default_generated_python_file_name(self) -> Optional[str]:
|
904
906
|
"""
|
905
907
|
:return: The default generated python file name.
|
906
908
|
"""
|
909
|
+
if self.start_rule is None or self.start_rule.corner_case is None:
|
910
|
+
return None
|
907
911
|
if isinstance(self.start_rule.corner_case, Case):
|
908
912
|
name = self.start_rule.corner_case._name
|
909
913
|
else:
|
File without changes
|