ripple-down-rules 0.0.13__py3-none-any.whl → 0.0.14__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.
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from collections import UserDict
4
+ from copy import copy, deepcopy
4
5
  from dataclasses import dataclass
5
6
  from enum import Enum
6
7
 
@@ -9,7 +10,8 @@ from sqlalchemy import MetaData
9
10
  from sqlalchemy.orm import DeclarativeBase as SQLTable, MappedColumn as SQLColumn, registry
10
11
  from typing_extensions import Any, Optional, Dict, Type, Set, Hashable, Union, List, TYPE_CHECKING
11
12
 
12
- from ..utils import make_set, row_to_dict, table_rows_as_str, get_value_type_from_type_hint, SubclassJSONSerializer
13
+ from ..utils import make_set, row_to_dict, table_rows_as_str, get_value_type_from_type_hint, SubclassJSONSerializer, \
14
+ get_full_class_name, get_type_from_string
13
15
 
14
16
  if TYPE_CHECKING:
15
17
  from ripple_down_rules.rules import Rule
@@ -76,11 +78,17 @@ class Case(UserDict, SubclassJSONSerializer):
76
78
  def _to_json(self) -> Dict[str, Any]:
77
79
  serializable = {k: v for k, v in self.items() if not k.startswith("_")}
78
80
  serializable["_id"] = self._id
81
+ for k, v in serializable.items():
82
+ if isinstance(v, set):
83
+ serializable[k] = {'_type': get_full_class_name(set), 'value': list(v)}
79
84
  return {k: v.to_json() if isinstance(v, SubclassJSONSerializer) else v for k, v in serializable.items()}
80
85
 
81
86
  @classmethod
82
87
  def _from_json(cls, data: Dict[str, Any]) -> Case:
83
88
  id_ = data.pop("_id")
89
+ for k, v in data.items():
90
+ if isinstance(v, dict) and "_type" in v:
91
+ data[k] = SubclassJSONSerializer.from_json(v)
84
92
  return cls(_id=id_, **data)
85
93
 
86
94
 
ripple_down_rules/rdr.py CHANGED
@@ -14,7 +14,7 @@ from .datastructures import Case, MCRDRMode, CallableExpression, CaseAttribute,
14
14
  from .experts import Expert, Human
15
15
  from .rules import Rule, SingleClassRule, MultiClassTopRule, MultiClassStopRule
16
16
  from .utils import draw_tree, make_set, get_attribute_by_type, copy_case, \
17
- get_hint_for_attribute, SubclassJSONSerializer, is_iterable, make_list
17
+ get_hint_for_attribute, SubclassJSONSerializer, is_iterable, make_list, get_full_class_name, get_type_from_string
18
18
 
19
19
 
20
20
  class RippleDownRules(SubclassJSONSerializer, ABC):
@@ -801,3 +801,17 @@ class GeneralRDR(RippleDownRules):
801
801
  Get all the types of categories that the GRDR can classify.
802
802
  """
803
803
  return list(self.start_rules_dict.keys())
804
+
805
+ def _to_json(self) -> Dict[str, Any]:
806
+ return {"start_rules": {get_full_class_name(t): rdr.to_json() for t, rdr in self.start_rules_dict.items()}}
807
+
808
+ @classmethod
809
+ def _from_json(cls, data: Dict[str, Any]) -> GeneralRDR:
810
+ """
811
+ Create an instance of the class from a json
812
+ """
813
+ start_rules_dict = {}
814
+ for k, v in data["start_rules"].items():
815
+ k = get_type_from_string(k)
816
+ start_rules_dict[k] = get_type_from_string(v['_type']).from_json(v)
817
+ return cls(start_rules_dict)
@@ -8,7 +8,7 @@ from typing_extensions import List, Optional, Self, Union, Dict, Any
8
8
 
9
9
  from .datastructures import CallableExpression, Case, SQLTable
10
10
  from .datastructures.enums import RDREdge, Stop
11
- from .utils import SubclassJSONSerializer
11
+ from .utils import SubclassJSONSerializer, is_iterable, get_full_class_name
12
12
 
13
13
 
14
14
  class Rule(NodeMixin, SubclassJSONSerializer, ABC):
@@ -102,8 +102,17 @@ class Rule(NodeMixin, SubclassJSONSerializer, ABC):
102
102
  pass
103
103
 
104
104
  def _to_json(self) -> Dict[str, Any]:
105
+ def conclusion_to_json(conclusion):
106
+ if is_iterable(conclusion):
107
+ conclusions = {'_type': get_full_class_name(type(conclusion)), 'value': []}
108
+ for c in conclusion:
109
+ conclusions['value'].append(conclusion_to_json(c))
110
+ else:
111
+ conclusions = conclusion.to_json()
112
+ return conclusions
113
+
105
114
  json_serialization = {"conditions": self.conditions.to_json(),
106
- "conclusion": self.conclusion.to_json(),
115
+ "conclusion": conclusion_to_json(self.conclusion),
107
116
  "parent": self.parent.json_serialization if self.parent else None,
108
117
  "corner_case": self.corner_case.to_json() if self.corner_case else None,
109
118
  "weight": self.weight}
@@ -25,6 +25,16 @@ if TYPE_CHECKING:
25
25
  matplotlib.use("Qt5Agg") # or "Qt5Agg", depending on availability
26
26
 
27
27
 
28
+ def flatten_list(a: List):
29
+ a_flattened = []
30
+ for c in a:
31
+ if is_iterable(c):
32
+ a_flattened.extend(list(c))
33
+ else:
34
+ a_flattened.append(c)
35
+ return a_flattened
36
+
37
+
28
38
  def make_list(value: Any) -> List:
29
39
  """
30
40
  Make a list from a value.
@@ -97,15 +107,13 @@ class SubclassJSONSerializer:
97
107
  def to_json(self) -> Dict[str, Any]:
98
108
  return {"_type": get_full_class_name(self.__class__), **self._to_json()}
99
109
 
100
- @abstractmethod
101
110
  def _to_json(self) -> Dict[str, Any]:
102
111
  """
103
112
  Create a json dict from the object.
104
113
  """
105
- pass
114
+ raise NotImplementedError()
106
115
 
107
116
  @classmethod
108
- @abstractmethod
109
117
  def _from_json(cls, data: Dict[str, Any]) -> Self:
110
118
  """
111
119
  Create a variable from a json dict.
@@ -140,7 +148,16 @@ class SubclassJSONSerializer:
140
148
  """
141
149
  if data is None:
142
150
  return None
151
+ if not isinstance(data, dict) or ('_type' not in data):
152
+ return data
153
+ # check if type module is builtins
154
+ data_type = get_type_from_string(data["_type"])
155
+ if data_type.__module__ == 'builtins':
156
+ if is_iterable(data['value']) and not isinstance(data['value'], dict):
157
+ return data_type([cls.from_json(d) for d in data['value']])
158
+ return data_type(data["value"])
143
159
  if get_full_class_name(cls) == data["_type"]:
160
+ data.pop("_type")
144
161
  return cls._from_json(data)
145
162
  for subclass in recursive_subclasses(SubclassJSONSerializer):
146
163
  if get_full_class_name(subclass) == data["_type"]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripple_down_rules
3
- Version: 0.0.13
3
+ Version: 0.0.14
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
@@ -3,16 +3,16 @@ ripple_down_rules/datasets.py,sha256=qYX7IF7ACm0VRbaKfEgQ32j0YbUUyt2GfGU5Lo42CqI
3
3
  ripple_down_rules/experts.py,sha256=wg1uY0ox9dUMR4s1RdGjzpX1_WUqnCa060r1U9lrKYI,11214
4
4
  ripple_down_rules/failures.py,sha256=E6ajDUsw3Blom8eVLbA7d_Qnov2conhtZ0UmpQ9ZtSE,302
5
5
  ripple_down_rules/prompt.py,sha256=QAmxg4ssrGUAlK7lbyKw2nuRczTZColpjc9uMC1ts3I,4210
6
- ripple_down_rules/rdr.py,sha256=4HB_H8PNh8pqucmX9JAOeOql7EF5ajYSYUzZ08HG4Z4,37549
7
- ripple_down_rules/rules.py,sha256=SWqnmP9BN2JlKPOWXviEvVjcP0A4b44Sxhv3y7He-YY,13615
8
- ripple_down_rules/utils.py,sha256=pmjIPjF9wq6dmCHCoUKFRsJmSaI0b-hRLn375WHgWgQ,18010
6
+ ripple_down_rules/rdr.py,sha256=Z-Zu8dH1kdlwOzTVT3DrDdqkMXk6xFQze-Mtz1YZ320,38142
7
+ ripple_down_rules/rules.py,sha256=Gi_GRYDvnwxPIHEh_aP1NmN9cL2pHZbwbaiO6M7YdU0,14044
8
+ ripple_down_rules/utils.py,sha256=32gU9NHIcxQpfS4zPSAtn63np5SdVvS9VuyoYiyKZbc,18664
9
9
  ripple_down_rules/datastructures/__init__.py,sha256=zpmiYm4WkwNHaGdTIfacS7llN5d2xyU6U-saH_TpydI,103
10
10
  ripple_down_rules/datastructures/callable_expression.py,sha256=TN6bi4VYjyLlSLTEA3dRo5ENfEdQYc8Fjj5nbnsz-C0,9058
11
- ripple_down_rules/datastructures/case.py,sha256=UYHz-Ag7TjwP9MRQuUTVH0nmph6ddutTSZMEXGFkxf4,13676
11
+ ripple_down_rules/datastructures/case.py,sha256=0EV69VBzsBTHQ3Ots7fkP09g1tyJ20xW9kSm0nZGy40,14071
12
12
  ripple_down_rules/datastructures/dataclasses.py,sha256=EVQ1jBKW7K7q7_JNgikHX9fm3EmQQKA74sNjEQ4rXn8,2449
13
13
  ripple_down_rules/datastructures/enums.py,sha256=l0Eu-TeJ6qB2XHoJycXmUgLw-3yUebQ8SsEbW8bBZdM,4543
14
- ripple_down_rules-0.0.13.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
15
- ripple_down_rules-0.0.13.dist-info/METADATA,sha256=HplzC77nnv95bL4x1bxRQI2CHzQMyBOFRJNHff2brzs,42519
16
- ripple_down_rules-0.0.13.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
17
- ripple_down_rules-0.0.13.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
18
- ripple_down_rules-0.0.13.dist-info/RECORD,,
14
+ ripple_down_rules-0.0.14.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
15
+ ripple_down_rules-0.0.14.dist-info/METADATA,sha256=VHKBkYFWhQvidy3vV2Td6kyLLjrwkYMv18ROs_dbb2o,42519
16
+ ripple_down_rules-0.0.14.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
17
+ ripple_down_rules-0.0.14.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
18
+ ripple_down_rules-0.0.14.dist-info/RECORD,,