ripple-down-rules 0.5.59__py3-none-any.whl → 0.5.61__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/__init__.py +1 -1
- ripple_down_rules/datastructures/callable_expression.py +2 -1
- ripple_down_rules/experts.py +8 -1
- ripple_down_rules/rdr.py +11 -5
- ripple_down_rules/rdr_decorators.py +6 -8
- {ripple_down_rules-0.5.59.dist-info → ripple_down_rules-0.5.61.dist-info}/METADATA +1 -1
- {ripple_down_rules-0.5.59.dist-info → ripple_down_rules-0.5.61.dist-info}/RECORD +10 -10
- {ripple_down_rules-0.5.59.dist-info → ripple_down_rules-0.5.61.dist-info}/WHEEL +0 -0
- {ripple_down_rules-0.5.59.dist-info → ripple_down_rules-0.5.61.dist-info}/licenses/LICENSE +0 -0
- {ripple_down_rules-0.5.59.dist-info → ripple_down_rules-0.5.61.dist-info}/top_level.txt +0 -0
ripple_down_rules/__init__.py
CHANGED
@@ -259,7 +259,8 @@ class CallableExpression(SubclassJSONSerializer):
|
|
259
259
|
"conclusion_type": [get_full_class_name(t) for t in self.conclusion_type]
|
260
260
|
if self.conclusion_type is not None else None,
|
261
261
|
"scope": {k: get_full_class_name(v) for k, v in self.scope.items()
|
262
|
-
if hasattr(v, '__module__') and hasattr(v, '__name__')
|
262
|
+
if hasattr(v, '__module__') and hasattr(v, '__name__')
|
263
|
+
and v.__module__ is not None and v.__name__ is not None},
|
263
264
|
"conclusion": conclusion_to_json(self.conclusion),
|
264
265
|
"mutually_exclusive": self.mutually_exclusive,
|
265
266
|
}
|
ripple_down_rules/experts.py
CHANGED
@@ -138,7 +138,12 @@ class Expert(ABC):
|
|
138
138
|
os.makedirs(dir_name, exist_ok=True)
|
139
139
|
with open(dir_name + '/__init__.py', 'w') as f:
|
140
140
|
f.write('# This is an empty init file to make the directory a package.\n')
|
141
|
-
|
141
|
+
# Current file data
|
142
|
+
current_file_data = None
|
143
|
+
if os.path.exists(path + '.py'):
|
144
|
+
with open(path + '.py', 'r') as f:
|
145
|
+
current_file_data = f.read()
|
146
|
+
action = 'a' if self.append and current_file_data is not None else 'w'
|
142
147
|
with open(path + '.py', action) as f:
|
143
148
|
for scope, func_source in self.all_expert_answers:
|
144
149
|
if len(scope) > 0:
|
@@ -150,6 +155,8 @@ class Expert(ABC):
|
|
150
155
|
func_source = encapsulate_user_input(func_source, CallableExpression.get_encapsulating_function(f'_{uid}'))
|
151
156
|
else:
|
152
157
|
func_source = 'pass # No user input provided for this case.\n'
|
158
|
+
if func_source[1:] in current_file_data:
|
159
|
+
continue
|
153
160
|
f.write(imports + func_source + '\n' + '\n\n\n\'===New Answer===\'\n\n\n')
|
154
161
|
|
155
162
|
def load_answers(self, path: Optional[str] = None):
|
ripple_down_rules/rdr.py
CHANGED
@@ -78,7 +78,7 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
|
|
78
78
|
"""
|
79
79
|
|
80
80
|
def __init__(self, start_rule: Optional[Rule] = None, viewer: Optional[RDRCaseViewer] = None,
|
81
|
-
save_dir: Optional[str] = None, ask_always: bool =
|
81
|
+
save_dir: Optional[str] = None, ask_always: bool = False, model_name: Optional[str] = None):
|
82
82
|
"""
|
83
83
|
:param start_rule: The starting rule for the classifier.
|
84
84
|
:param viewer: The viewer gui to use for the classifier. If None, no viewer is used.
|
@@ -241,12 +241,18 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
|
|
241
241
|
self.case_type = case_query.case_type if self.case_type is None else self.case_type
|
242
242
|
self.case_name = case_query.case_name if self.case_name is None else self.case_name
|
243
243
|
|
244
|
-
expert = expert or Human(
|
244
|
+
expert = expert or Human(viewer=self.viewer,
|
245
|
+
answers_save_path=self.save_dir + '/expert_answers'
|
246
|
+
if self.save_dir else None)
|
245
247
|
|
246
248
|
if case_query.target is None:
|
247
249
|
case_query_cp = copy(case_query)
|
248
250
|
conclusions = self.classify(case_query_cp.case, modify_case=True)
|
249
|
-
if self.ask_always or conclusions is None
|
251
|
+
if (self.ask_always or conclusions is None
|
252
|
+
or is_iterable(conclusions) and len(conclusions) == 0
|
253
|
+
or (isinstance(conclusions, dict) and (case_query_cp.attribute_name not in conclusions
|
254
|
+
or not any(type(c) in case_query_cp.core_attribute_type
|
255
|
+
for c in make_list(conclusions[case_query_cp.attribute_name]))))):
|
250
256
|
expert.ask_for_conclusion(case_query_cp)
|
251
257
|
case_query.target = case_query_cp.target
|
252
258
|
if case_query.target is None:
|
@@ -646,12 +652,12 @@ class MultiClassRDR(RDRWithCodeWriter):
|
|
646
652
|
"""
|
647
653
|
|
648
654
|
def __init__(self, start_rule: Optional[MultiClassTopRule] = None,
|
649
|
-
mode: MCRDRMode = MCRDRMode.StopOnly):
|
655
|
+
mode: MCRDRMode = MCRDRMode.StopOnly, **kwargs):
|
650
656
|
"""
|
651
657
|
:param start_rule: The starting rules for the classifier.
|
652
658
|
:param mode: The mode of the classifier, either StopOnly or StopPlusRule, or StopPlusRuleCombined.
|
653
659
|
"""
|
654
|
-
super(MultiClassRDR, self).__init__(start_rule)
|
660
|
+
super(MultiClassRDR, self).__init__(start_rule, **kwargs)
|
655
661
|
self.mode: MCRDRMode = mode
|
656
662
|
|
657
663
|
def classify(self, case: Union[Case, SQLTable], modify_case: bool = False) -> Set[Any]:
|
@@ -24,7 +24,6 @@ class RDRDecorator:
|
|
24
24
|
def __init__(self, models_dir: str,
|
25
25
|
output_type: Tuple[Type],
|
26
26
|
mutual_exclusive: bool,
|
27
|
-
python_dir: Optional[str] = None,
|
28
27
|
output_name: str = "output_",
|
29
28
|
fit: bool = True,
|
30
29
|
expert: Optional[Expert] = None):
|
@@ -32,7 +31,6 @@ class RDRDecorator:
|
|
32
31
|
:param models_dir: The directory to save/load the RDR models.
|
33
32
|
:param output_type: The type of the output. This is used to create the RDR model.
|
34
33
|
:param mutual_exclusive: If True, the output types are mutually exclusive.
|
35
|
-
:param python_dir: The directory to save the RDR model as a python file.
|
36
34
|
If None, the RDR model will not be saved as a python file.
|
37
35
|
:param output_name: The name of the output. This is used to create the RDR model.
|
38
36
|
:param fit: If True, the function will be in fit mode. This means that the RDR will prompt the user for the
|
@@ -47,7 +45,6 @@ class RDRDecorator:
|
|
47
45
|
self.output_type = output_type
|
48
46
|
self.parsed_output_type: List[Type] = []
|
49
47
|
self.mutual_exclusive = mutual_exclusive
|
50
|
-
self.rdr_python_path: Optional[str] = python_dir
|
51
48
|
self.output_name = output_name
|
52
49
|
self.fit: bool = fit
|
53
50
|
self.expert: Optional[Expert] = expert
|
@@ -64,8 +61,6 @@ class RDRDecorator:
|
|
64
61
|
self.initialize_rdr_model_name_and_load(func)
|
65
62
|
|
66
63
|
if self.fit:
|
67
|
-
expert_answers_path = os.path.join(self.rdr_models_dir, self.model_name, "expert_answers")
|
68
|
-
self.expert = self.expert or Human(answers_save_path=expert_answers_path)
|
69
64
|
case_query = self.create_case_query_from_method(func, self.parsed_output_type,
|
70
65
|
self.mutual_exclusive, self.output_name,
|
71
66
|
*args, **kwargs)
|
@@ -148,9 +143,12 @@ class RDRDecorator:
|
|
148
143
|
"""
|
149
144
|
Load the RDR model from the specified directory.
|
150
145
|
"""
|
151
|
-
|
152
|
-
|
153
|
-
|
146
|
+
self.rdr = None
|
147
|
+
if self.model_name is not None:
|
148
|
+
model_path = os.path.join(self.rdr_models_dir, self.model_name + f"/rdr_metadata/{self.model_name}.json")
|
149
|
+
if os.path.exists(os.path.join(self.rdr_models_dir, model_path)):
|
150
|
+
self.rdr = GeneralRDR.load(self.rdr_models_dir, self.model_name)
|
151
|
+
if self.rdr is None:
|
154
152
|
self.rdr = GeneralRDR(save_dir=self.rdr_models_dir, model_name=self.model_name)
|
155
153
|
|
156
154
|
def update_from_python(self):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.61
|
4
4
|
Summary: Implements the various versions of Ripple Down Rules (RDR) for knowledge representation and reasoning.
|
5
5
|
Author-email: Abdelrhman Bassiouny <abassiou@uni-bremen.de>
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
@@ -1,13 +1,13 @@
|
|
1
|
-
ripple_down_rules/__init__.py,sha256=
|
2
|
-
ripple_down_rules/experts.py,sha256=
|
1
|
+
ripple_down_rules/__init__.py,sha256=HTMMmCE5AYEKizCjLFu9IPmEvRHJS3yrXE380eC2jus,100
|
2
|
+
ripple_down_rules/experts.py,sha256=9SDkyJGtmx-YaSCqWw727do09DwrRIbLrkheP625aXE,12576
|
3
3
|
ripple_down_rules/helpers.py,sha256=TvTJU0BA3dPcAyzvZFvAu7jZqsp8Lu0HAAwvuizlGjg,2018
|
4
|
-
ripple_down_rules/rdr.py,sha256=
|
5
|
-
ripple_down_rules/rdr_decorators.py,sha256=
|
4
|
+
ripple_down_rules/rdr.py,sha256=4iobla4XmMwAOQsn_JZaZe2tWU0aMMvqgzP5WavIagI,49280
|
5
|
+
ripple_down_rules/rdr_decorators.py,sha256=bmn4h4a7xujTVxu-ofECe71cM_6iiqZhLVFosEItid4,7602
|
6
6
|
ripple_down_rules/rules.py,sha256=TPNVMqW9T-_46BS4WemrspLg5uG8kP6tsPvWWBAzJxg,17515
|
7
7
|
ripple_down_rules/start-code-server.sh,sha256=otClk7VmDgBOX2TS_cjws6K0UwvgAUJhoA0ugkPCLqQ,949
|
8
8
|
ripple_down_rules/utils.py,sha256=N5Rgz7wb9oKrVLZiJG2P-irnsjhy7VR3Vqyggf4Mq7I,51564
|
9
9
|
ripple_down_rules/datastructures/__init__.py,sha256=V2aNgf5C96Y5-IGghra3n9uiefpoIm_QdT7cc_C8cxQ,111
|
10
|
-
ripple_down_rules/datastructures/callable_expression.py,sha256=
|
10
|
+
ripple_down_rules/datastructures/callable_expression.py,sha256=f3wUPTrLa1INO-1qfgVz87ryrCABronfyq0_JKWoZCs,12800
|
11
11
|
ripple_down_rules/datastructures/case.py,sha256=r8kjL9xP_wk84ThXusspgPMrAoed2bGQmKi54fzhmH8,15258
|
12
12
|
ripple_down_rules/datastructures/dataclasses.py,sha256=PuD-7zWqWT2p4FnGvnihHvZlZKg9A1ctnFgVYf2cs-8,8554
|
13
13
|
ripple_down_rules/datastructures/enums.py,sha256=ce7tqS0otfSTNAOwsnXlhsvIn4iW_Y_N3TNebF3YoZs,5700
|
@@ -17,8 +17,8 @@ ripple_down_rules/user_interface/ipython_custom_shell.py,sha256=24MIFwqnAhC6ofOb
|
|
17
17
|
ripple_down_rules/user_interface/object_diagram.py,sha256=tsB6iuLNEbHxp5lR2WjyejjWbnAX_nHF9xS8jNPOQVk,4548
|
18
18
|
ripple_down_rules/user_interface/prompt.py,sha256=AkkltdDIaioN43lkRKDPKSjJcmdSSGZDMYz7AL7X9lE,8082
|
19
19
|
ripple_down_rules/user_interface/template_file_creator.py,sha256=FGtLfYBfr4310c7Dfa9b2qiOWLNzHk1q3kdhD70Ilg4,13804
|
20
|
-
ripple_down_rules-0.5.
|
21
|
-
ripple_down_rules-0.5.
|
22
|
-
ripple_down_rules-0.5.
|
23
|
-
ripple_down_rules-0.5.
|
24
|
-
ripple_down_rules-0.5.
|
20
|
+
ripple_down_rules-0.5.61.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
21
|
+
ripple_down_rules-0.5.61.dist-info/METADATA,sha256=2RMPipq0IAqfsMJdijKW-JSYCKpLtmYSnXf6_BTC3BQ,48189
|
22
|
+
ripple_down_rules-0.5.61.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
23
|
+
ripple_down_rules-0.5.61.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
|
24
|
+
ripple_down_rules-0.5.61.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|