ripple-down-rules 0.5.53__py3-none-any.whl → 0.5.55__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,4 +1,4 @@
1
- __version__ = "0.5.53"
1
+ __version__ = "0.5.55"
2
2
 
3
3
  import logging
4
4
  logger = logging.Logger("rdr")
@@ -93,7 +93,6 @@ class CallableExpression(SubclassJSONSerializer):
93
93
  A callable that is constructed from a string statement written by an expert.
94
94
  """
95
95
  encapsulating_function_name: str = "_get_value"
96
- encapsulating_function: str = f"def {encapsulating_function_name}(case):"
97
96
 
98
97
  def __init__(self, user_input: Optional[str] = None,
99
98
  conclusion_type: Optional[Tuple[Type]] = None,
@@ -117,7 +116,7 @@ class CallableExpression(SubclassJSONSerializer):
117
116
  if user_input is None:
118
117
  user_input = build_user_input_from_conclusion(conclusion)
119
118
  self.conclusion: Optional[Any] = conclusion
120
- self._user_input: str = encapsulate_user_input(user_input, self.encapsulating_function)
119
+ self._user_input: str = encapsulate_user_input(user_input, self.get_encapsulating_function())
121
120
  if conclusion_type is not None:
122
121
  if is_iterable(conclusion_type):
123
122
  conclusion_type = tuple(conclusion_type)
@@ -132,6 +131,13 @@ class CallableExpression(SubclassJSONSerializer):
132
131
  self.visitor.visit(self.expression_tree)
133
132
  self.mutually_exclusive: bool = mutually_exclusive
134
133
 
134
+ @classmethod
135
+ def get_encapsulating_function(cls, postfix: str = '') -> str:
136
+ """
137
+ Get the encapsulating function that is used to wrap the user input.
138
+ """
139
+ return f"def {cls.encapsulating_function_name}{postfix}(case):"
140
+
135
141
  def __call__(self, case: Any, **kwargs) -> Any:
136
142
  try:
137
143
  if self.user_input is not None:
@@ -161,8 +167,8 @@ class CallableExpression(SubclassJSONSerializer):
161
167
  """
162
168
  Combine this callable expression with another callable expression using the 'and' operator.
163
169
  """
164
- cond1_user_input = self.user_input.replace(self.encapsulating_function, "def _cond1(case):")
165
- cond2_user_input = other.user_input.replace(self.encapsulating_function, "def _cond2(case):")
170
+ cond1_user_input = self.user_input.replace(self.get_encapsulating_function(), "def _cond1(case):")
171
+ cond2_user_input = other.user_input.replace(self.get_encapsulating_function(), "def _cond2(case):")
166
172
  new_user_input = (f"{cond1_user_input}\n"
167
173
  f"{cond2_user_input}\n"
168
174
  f"return _cond1(case) and _cond2(case)")
@@ -175,7 +181,7 @@ class CallableExpression(SubclassJSONSerializer):
175
181
  new_function_body = extract_function_source(file_path, [function_name])[function_name]
176
182
  if new_function_body is None:
177
183
  return
178
- self.user_input = self.encapsulating_function + '\n' + new_function_body
184
+ self.user_input = self.get_encapsulating_function() + '\n' + new_function_body
179
185
 
180
186
  def write_to_python_file(self, file_path: str, append: bool = False):
181
187
  """
@@ -208,7 +214,7 @@ class CallableExpression(SubclassJSONSerializer):
208
214
  Set the user input.
209
215
  """
210
216
  if value is not None:
211
- self._user_input = encapsulate_user_input(value, self.encapsulating_function)
217
+ self._user_input = encapsulate_user_input(value, self.get_encapsulating_function())
212
218
  self.scope = get_used_scope(self.user_input, self.scope)
213
219
  self.expression_tree = parse_string_to_expression(self.user_input)
214
220
  self.code = compile_expression_to_code(self.expression_tree)
@@ -286,8 +292,8 @@ def parse_string_to_expression(expression_str: str) -> AST:
286
292
  :param expression_str: The string which will be parsed.
287
293
  :return: The parsed expression.
288
294
  """
289
- if not expression_str.startswith(CallableExpression.encapsulating_function):
290
- expression_str = encapsulate_user_input(expression_str, CallableExpression.encapsulating_function)
295
+ if not expression_str.startswith(CallableExpression.get_encapsulating_function()):
296
+ expression_str = encapsulate_user_input(expression_str, CallableExpression.get_encapsulating_function())
291
297
  mode = 'exec' if expression_str.startswith('def') else 'eval'
292
298
  tree = ast.parse(expression_str, mode=mode)
293
299
  logging.debug(f"AST parsed successfully: {ast.dump(tree)}")
@@ -147,7 +147,7 @@ class Expert(ABC):
147
147
  imports = ''
148
148
  if func_source is not None:
149
149
  uid = uuid.uuid4().hex
150
- func_source = encapsulate_user_input(func_source, CallableExpression.encapsulating_function + f'_{uid}')
150
+ func_source = encapsulate_user_input(func_source, CallableExpression.get_encapsulating_function(f'_{uid}'))
151
151
  else:
152
152
  func_source = 'pass # No user input provided for this case.\n'
153
153
  f.write(imports + func_source + '\n' + '\n\n\n\'===New Answer===\'\n\n\n')
@@ -241,6 +241,7 @@ class Human(Expert):
241
241
  except IndexError:
242
242
  self.use_loaded_answers = False
243
243
  if user_input is not None:
244
+ case_query.scope.update(loaded_scope)
244
245
  condition = CallableExpression(user_input, bool, scope=case_query.scope)
245
246
  else:
246
247
  user_input, condition = self.user_prompt.prompt_user_for_expression(case_query, PromptFor.Conditions)
@@ -266,6 +267,7 @@ class Human(Expert):
266
267
  try:
267
268
  loaded_scope, expert_input = self.all_expert_answers.pop(0)
268
269
  if expert_input is not None:
270
+ case_query.scope.update(loaded_scope)
269
271
  expression = CallableExpression(expert_input, case_query.attribute_type,
270
272
  scope=case_query.scope,
271
273
  mutually_exclusive=case_query.mutually_exclusive)
@@ -18,6 +18,8 @@ from textwrap import dedent
18
18
  from types import NoneType
19
19
  from typing import List
20
20
 
21
+ from casadi import conic_n_out
22
+
21
23
  try:
22
24
  import matplotlib
23
25
  from matplotlib import pyplot as plt
@@ -499,7 +501,12 @@ def serialize_dataclass(obj: Any, seen=None) -> Any:
499
501
  elif isinstance(obj, list):
500
502
  return [serialize_dataclass(v, seen) for v in obj]
501
503
  elif isinstance(obj, dict):
502
- return {k: serialize_dataclass(v, seen) for k, v in obj.items()}
504
+ serialized_dict = {}
505
+ for k, v in obj.items():
506
+ if not isinstance(k, (str, int, bool, float, None)):
507
+ continue
508
+ serialized_dict[k] = serialize_dataclass(v, seen)
509
+ return serialized_dict
503
510
  else:
504
511
  try:
505
512
  json.dumps(obj) # Check if the object is JSON serializable
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripple_down_rules
3
- Version: 0.5.53
3
+ Version: 0.5.55
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=LKt5C0kg1CabiBILMQzPoFf80F4xL9CU80b3t9CQZSY,100
2
- ripple_down_rules/experts.py,sha256=MjYaQLWGl5I8_VG_Iy5KXRGGvy8UduG2jFDhseNNYq8,12155
1
+ ripple_down_rules/__init__.py,sha256=GkbqAXIdwBcSMmD6Mp-8-dQ7eM_-v0SsaPm_pKzuwDs,100
2
+ ripple_down_rules/experts.py,sha256=8p5tFOWuQWgp9gt-6Yr6MFFphOTmpI9IJ3iepUyy3FY,12266
3
3
  ripple_down_rules/helpers.py,sha256=TvTJU0BA3dPcAyzvZFvAu7jZqsp8Lu0HAAwvuizlGjg,2018
4
4
  ripple_down_rules/rdr.py,sha256=FJYuRXgpUYSSK1pYrp2yeXb_ZZ2xjPED31tzxofokL4,48865
5
5
  ripple_down_rules/rdr_decorators.py,sha256=pYCKLgMKgQ6x_252WQtF2t4ZNjWPBxnaWtJ6TpGdcc0,7820
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=4xQ5gmIeMsY-mA9g-4cedKt2WJq4oZAMs5XEKeplWPM,51127
8
+ ripple_down_rules/utils.py,sha256=PMC0f1CNNINjZYXqzDuv3C1_nS3oTxj4zO8hhGpypJQ,51331
9
9
  ripple_down_rules/datastructures/__init__.py,sha256=V2aNgf5C96Y5-IGghra3n9uiefpoIm_QdT7cc_C8cxQ,111
10
- ripple_down_rules/datastructures/callable_expression.py,sha256=D2KD1RdShzxYZPAERgywZ5ZPE4ar8WmMtXINqvYo_Tc,12497
10
+ ripple_down_rules/datastructures/callable_expression.py,sha256=w6Gpo1o-xnFvTaPrzJ2w7VgCjSr1xqp8LQG0jAl-mfc,12718
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.53.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
21
- ripple_down_rules-0.5.53.dist-info/METADATA,sha256=L6wXpYzu-UYGXpBhXuocC319zeWGpfGrhQQHILhTr7M,48189
22
- ripple_down_rules-0.5.53.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- ripple_down_rules-0.5.53.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
24
- ripple_down_rules-0.5.53.dist-info/RECORD,,
20
+ ripple_down_rules-0.5.55.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
21
+ ripple_down_rules-0.5.55.dist-info/METADATA,sha256=u3aR9vbi2_vnOUtcWnze18LhPouXxwUm_criDCAswOM,48189
22
+ ripple_down_rules-0.5.55.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
+ ripple_down_rules-0.5.55.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
24
+ ripple_down_rules-0.5.55.dist-info/RECORD,,