ripple-down-rules 0.2.0__py3-none-any.whl → 0.2.2__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.
@@ -9,7 +9,8 @@ from typing_extensions import Type, Optional, Any, List, Union, Tuple, Dict, Set
9
9
 
10
10
  from .case import create_case, Case
11
11
  from ..utils import SubclassJSONSerializer, get_full_class_name, get_type_from_string, conclusion_to_json, is_iterable, \
12
- build_user_input_from_conclusion, encapsulate_user_input, extract_function_source
12
+ build_user_input_from_conclusion, encapsulate_user_input, extract_function_source, are_results_subclass_of_types, \
13
+ make_list
13
14
 
14
15
 
15
16
  class VariableVisitor(ast.NodeVisitor):
@@ -133,15 +134,16 @@ class CallableExpression(SubclassJSONSerializer):
133
134
  if output is None:
134
135
  output = scope['_get_value'](case)
135
136
  if self.conclusion_type is not None:
136
- if is_iterable(output) and not isinstance(output, self.conclusion_type):
137
- assert isinstance(list(output)[0], self.conclusion_type), (f"Expected output type {self.conclusion_type},"
138
- f" got {type(output)}")
139
- else:
140
- assert isinstance(output, self.conclusion_type), (f"Expected output type {self.conclusion_type},"
141
- f" got {type(output)}")
137
+ output_types = {type(o) for o in make_list(output)}
138
+ output_types.add(type(output))
139
+ if not are_results_subclass_of_types(output_types, self.conclusion_type):
140
+ raise ValueError(f"Not all result types {output_types} are subclasses of expected types"
141
+ f" {self.conclusion_type}")
142
142
  return output
143
- else:
143
+ elif self.conclusion is not None:
144
144
  return self.conclusion
145
+ else:
146
+ raise ValueError("Either user_input or conclusion must be provided.")
145
147
  except Exception as e:
146
148
  raise ValueError(f"Error during evaluation: {e}")
147
149
 
@@ -83,6 +83,13 @@ class CaseQuery:
83
83
  raise ValueError("The case must be a Case or SQLTable object.")
84
84
  self._case = value
85
85
 
86
+ @property
87
+ def core_attribute_type(self) -> Tuple[Type]:
88
+ """
89
+ :return: The core type of the attribute.
90
+ """
91
+ return (t for t in self.attribute_type if t not in (set, list))
92
+
86
93
  @property
87
94
  def attribute_type(self) -> Tuple[Type]:
88
95
  """
@@ -10,14 +10,15 @@ from textwrap import indent, dedent
10
10
  from IPython.core.magic import register_line_magic, line_magic, Magics, magics_class
11
11
  from IPython.terminal.embed import InteractiveShellEmbed
12
12
  from traitlets.config import Config
13
- from typing_extensions import List, Optional, Tuple, Dict, Type, Union
13
+ from typing_extensions import List, Optional, Tuple, Dict, Type, Union, Any
14
14
 
15
15
  from .datastructures.enums import PromptFor
16
16
  from .datastructures.case import Case
17
17
  from .datastructures.callable_expression import CallableExpression, parse_string_to_expression
18
18
  from .datastructures.dataclasses import CaseQuery
19
19
  from .utils import extract_dependencies, contains_return_statement, make_set, get_imports_from_scope, make_list, \
20
- get_import_from_type, get_imports_from_types, is_iterable, extract_function_source, encapsulate_user_input
20
+ get_import_from_type, get_imports_from_types, is_iterable, extract_function_source, encapsulate_user_input, \
21
+ are_results_subclass_of_types
21
22
 
22
23
 
23
24
  @magics_class
@@ -259,7 +260,6 @@ class IPythonShell:
259
260
  if len(self.all_code_lines) == 1 and self.all_code_lines[0].strip() == '':
260
261
  self.user_input = None
261
262
  else:
262
- import pdb; pdb.set_trace()
263
263
  self.user_input = '\n'.join(self.all_code_lines)
264
264
  self.user_input = encapsulate_user_input(self.user_input, self.shell.my_magics.function_signature,
265
265
  self.func_doc)
@@ -278,6 +278,7 @@ def prompt_user_for_expression(case_query: CaseQuery, prompt_for: PromptFor, pro
278
278
  :return: A callable expression that takes a case and executes user expression on it.
279
279
  """
280
280
  prev_user_input: Optional[str] = None
281
+ callable_expression: Optional[CallableExpression] = None
281
282
  while True:
282
283
  user_input, expression_tree = prompt_user_about_case(case_query, prompt_for, prompt_str,
283
284
  code_to_modify=prev_user_input)
@@ -294,9 +295,8 @@ def prompt_user_for_expression(case_query: CaseQuery, prompt_for: PromptFor, pro
294
295
  scope=case_query.scope)
295
296
  try:
296
297
  result = callable_expression(case_query.case)
297
- result = make_list(result)
298
- if len(result) == 0:
299
- print(f"The given expression gave an empty result for case {case_query.name}, please modify")
298
+ if len(make_list(result)) == 0:
299
+ print(f"The given expression gave an empty result for case {case_query.name}. Please modify!")
300
300
  continue
301
301
  break
302
302
  except Exception as e:
@@ -36,6 +36,20 @@ import ast
36
36
  matplotlib.use("Qt5Agg") # or "Qt5Agg", depending on availability
37
37
 
38
38
 
39
+ def are_results_subclass_of_types(result_types: List[Any], types_: List[Type]) -> bool:
40
+ """
41
+ Check if all results are subclasses of the given types.
42
+
43
+ :param result_types: The list of result types to check.
44
+ :param types_: The list of types to check against.
45
+ :return: True if all results are subclasses of the given types, False otherwise.
46
+ """
47
+ for rt in result_types:
48
+ if not any(issubclass(rt, t) for t in types_):
49
+ return False
50
+ return True
51
+
52
+
39
53
  def get_imports_from_types(types: List[Type]) -> List[str]:
40
54
  """
41
55
  Get the import statements for a list of types.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripple_down_rules
3
- Version: 0.2.0
3
+ Version: 0.2.2
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,18 +3,18 @@ ripple_down_rules/datasets.py,sha256=mjJh1GLD_5qMgHaukdDWSGphXS9k_BPEF001ZXPchr8
3
3
  ripple_down_rules/experts.py,sha256=JGVvSNiWhm4FpRpg76f98tl8Ii_C7x_aWD9FxD-JDLQ,6130
4
4
  ripple_down_rules/failures.py,sha256=E6ajDUsw3Blom8eVLbA7d_Qnov2conhtZ0UmpQ9ZtSE,302
5
5
  ripple_down_rules/helpers.py,sha256=TvTJU0BA3dPcAyzvZFvAu7jZqsp8Lu0HAAwvuizlGjg,2018
6
- ripple_down_rules/prompt.py,sha256=sab5yqSJaMGgqfOsXybzZhbKx2vyU0h5dfcSqsQuY7E,16118
6
+ ripple_down_rules/prompt.py,sha256=ReXnZ6OraFPqK5kDfAqH8d4SRPYiQ5d4ESk0js_MM9c,16150
7
7
  ripple_down_rules/rdr.py,sha256=vxNZckp6sLAUD92JQgfCzhBhg9CXfMZ_7W4VgrIUFjU,43366
8
8
  ripple_down_rules/rdr_decorators.py,sha256=8SclpceI3EtrsbuukWJu8HGLh7Q1ZCgYGLX-RPlG-w0,2018
9
9
  ripple_down_rules/rules.py,sha256=QQy7NBG6mKiowxVG_LjQJBxLTDW2hMyx5zAgwUxdCMM,17183
10
- ripple_down_rules/utils.py,sha256=Q5VWgisHCFxEA06Y0ImSfu7cozVJCHTCDYGWbDJNlgA,43516
10
+ ripple_down_rules/utils.py,sha256=EdVdIf93TAqbxRTzbf_1422FjenRSI4MI_Ecp3e10z8,44007
11
11
  ripple_down_rules/datastructures/__init__.py,sha256=V2aNgf5C96Y5-IGghra3n9uiefpoIm_QdT7cc_C8cxQ,111
12
- ripple_down_rules/datastructures/callable_expression.py,sha256=1hwRjS8-csfZ0HSlhLLOBCcvKJ8W3_N1qHayFLNhl3k,10908
12
+ ripple_down_rules/datastructures/callable_expression.py,sha256=qVo8baEI_seeg6V23wmsctYdWj_tJJEOTkHeUc04Wvw,10912
13
13
  ripple_down_rules/datastructures/case.py,sha256=nJDKOjyhGLx4gt0sHxJNxBLdy9X2SLcDn89_SmKzwoc,14035
14
- ripple_down_rules/datastructures/dataclasses.py,sha256=TAOAeEvh0BeTis3rEHu8rpCeqNNhU0vK3to0JaBwTio,5961
14
+ ripple_down_rules/datastructures/dataclasses.py,sha256=BUr0T0CCh98sdsW2CVAXGk2oWqfemM7w1t91QKvg_KU,6171
15
15
  ripple_down_rules/datastructures/enums.py,sha256=hlE6LAa1jUafnG_6UazvaPDfhC1ClI7hKvD89zOyAO8,4661
16
- ripple_down_rules-0.2.0.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
17
- ripple_down_rules-0.2.0.dist-info/METADATA,sha256=FZV_PqD3Yc6Qw1YCPAZowkycnAa6OzdcyMlpT7w8AS4,42575
18
- ripple_down_rules-0.2.0.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
19
- ripple_down_rules-0.2.0.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
20
- ripple_down_rules-0.2.0.dist-info/RECORD,,
16
+ ripple_down_rules-0.2.2.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
17
+ ripple_down_rules-0.2.2.dist-info/METADATA,sha256=cwyxHt0ta-asbPBoOblSxWbw7-ASen5e4ZJ--SAmGM0,42575
18
+ ripple_down_rules-0.2.2.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
19
+ ripple_down_rules-0.2.2.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
20
+ ripple_down_rules-0.2.2.dist-info/RECORD,,