ripple-down-rules 0.5.58__py3-none-any.whl → 0.5.60__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/rdr.py +13 -6
- ripple_down_rules/rdr_decorators.py +6 -8
- ripple_down_rules/utils.py +21 -18
- {ripple_down_rules-0.5.58.dist-info → ripple_down_rules-0.5.60.dist-info}/METADATA +1 -1
- {ripple_down_rules-0.5.58.dist-info → ripple_down_rules-0.5.60.dist-info}/RECORD +10 -10
- {ripple_down_rules-0.5.58.dist-info → ripple_down_rules-0.5.60.dist-info}/WHEEL +0 -0
- {ripple_down_rules-0.5.58.dist-info → ripple_down_rules-0.5.60.dist-info}/licenses/LICENSE +0 -0
- {ripple_down_rules-0.5.58.dist-info → ripple_down_rules-0.5.60.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/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:
|
@@ -493,7 +499,8 @@ class RDRWithCodeWriter(RippleDownRules, ABC):
|
|
493
499
|
return self.start_rule.conclusion_name
|
494
500
|
|
495
501
|
def _to_json(self) -> Dict[str, Any]:
|
496
|
-
return {"start_rule": self.start_rule.to_json(),
|
502
|
+
return {"start_rule": self.start_rule.to_json(),
|
503
|
+
"generated_python_file_name": self.generated_python_file_name,
|
497
504
|
"name": self.name,
|
498
505
|
"case_type": get_full_class_name(self.case_type) if self.case_type is not None else None,
|
499
506
|
"case_name": self.case_name}
|
@@ -645,12 +652,12 @@ class MultiClassRDR(RDRWithCodeWriter):
|
|
645
652
|
"""
|
646
653
|
|
647
654
|
def __init__(self, start_rule: Optional[MultiClassTopRule] = None,
|
648
|
-
mode: MCRDRMode = MCRDRMode.StopOnly):
|
655
|
+
mode: MCRDRMode = MCRDRMode.StopOnly, **kwargs):
|
649
656
|
"""
|
650
657
|
:param start_rule: The starting rules for the classifier.
|
651
658
|
:param mode: The mode of the classifier, either StopOnly or StopPlusRule, or StopPlusRuleCombined.
|
652
659
|
"""
|
653
|
-
super(MultiClassRDR, self).__init__(start_rule)
|
660
|
+
super(MultiClassRDR, self).__init__(start_rule, **kwargs)
|
654
661
|
self.mode: MCRDRMode = mode
|
655
662
|
|
656
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):
|
ripple_down_rules/utils.py
CHANGED
@@ -497,21 +497,8 @@ def serialize_dataclass(obj: Any, seen=None) -> Any:
|
|
497
497
|
value = getattr(obj, f.name)
|
498
498
|
result['fields'][f.name] = serialize_dataclass(value, seen)
|
499
499
|
return result
|
500
|
-
elif isinstance(obj, list):
|
501
|
-
return [serialize_dataclass(v, seen) for v in obj]
|
502
|
-
elif isinstance(obj, dict):
|
503
|
-
serialized_dict = {}
|
504
|
-
for k, v in obj.items():
|
505
|
-
if not isinstance(k, (str, int, bool, float, type(None))):
|
506
|
-
continue
|
507
|
-
serialized_dict[k] = serialize_dataclass(v, seen)
|
508
|
-
return serialized_dict
|
509
500
|
else:
|
510
|
-
|
511
|
-
json.dumps(obj) # Check if the object is JSON serializable
|
512
|
-
return obj
|
513
|
-
except TypeError:
|
514
|
-
return None
|
501
|
+
return SubclassJSONSerializer.to_json_static(obj, seen)
|
515
502
|
|
516
503
|
|
517
504
|
def deserialize_dataclass(data: Any, refs: Optional[Dict[str, Any]] = None) -> Any:
|
@@ -875,10 +862,26 @@ class SubclassJSONSerializer:
|
|
875
862
|
return data
|
876
863
|
|
877
864
|
@staticmethod
|
878
|
-
def to_json_static(obj) ->
|
879
|
-
if
|
880
|
-
return
|
881
|
-
|
865
|
+
def to_json_static(obj, seen=None) -> Any:
|
866
|
+
if isinstance(obj, SubclassJSONSerializer):
|
867
|
+
return {"_type": get_full_class_name(obj.__class__), **obj._to_json()}
|
868
|
+
elif is_dataclass(obj):
|
869
|
+
return serialize_dataclass(obj, seen)
|
870
|
+
elif isinstance(obj, list):
|
871
|
+
return [SubclassJSONSerializer.to_json_static(v, seen) for v in obj]
|
872
|
+
elif isinstance(obj, dict):
|
873
|
+
serialized_dict = {}
|
874
|
+
for k, v in obj.items():
|
875
|
+
if not isinstance(k, (str, int, bool, float, type(None))):
|
876
|
+
continue
|
877
|
+
serialized_dict[k] = SubclassJSONSerializer.to_json_static(v, seen)
|
878
|
+
return serialized_dict
|
879
|
+
else:
|
880
|
+
try:
|
881
|
+
json.dumps(obj) # Check if the object is JSON serializable
|
882
|
+
return obj
|
883
|
+
except TypeError:
|
884
|
+
return None
|
882
885
|
|
883
886
|
def to_json(self) -> Dict[str, Any]:
|
884
887
|
return self.to_json_static(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.60
|
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=
|
1
|
+
ripple_down_rules/__init__.py,sha256=YMDb4SUKV8_gECB2R7_aVOk5ycxEUZZOLksjGvCzCgU,100
|
2
2
|
ripple_down_rules/experts.py,sha256=8p5tFOWuQWgp9gt-6Yr6MFFphOTmpI9IJ3iepUyy3FY,12266
|
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
|
-
ripple_down_rules/utils.py,sha256=
|
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.60.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
21
|
+
ripple_down_rules-0.5.60.dist-info/METADATA,sha256=bS8oBSP7DZJP-wgtpRQWPDRQJ_0bf8nlFZkA_LpbBRE,48189
|
22
|
+
ripple_down_rules-0.5.60.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
23
|
+
ripple_down_rules-0.5.60.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
|
24
|
+
ripple_down_rules-0.5.60.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|