ripple-down-rules 0.4.7__py3-none-any.whl → 0.4.9__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 +5 -0
- ripple_down_rules/datastructures/callable_expression.py +20 -1
- ripple_down_rules/datastructures/case.py +8 -6
- ripple_down_rules/datastructures/dataclasses.py +9 -1
- ripple_down_rules/experts.py +194 -33
- ripple_down_rules/rdr.py +196 -114
- ripple_down_rules/rdr_decorators.py +73 -52
- ripple_down_rules/rules.py +7 -6
- ripple_down_rules/start-code-server.sh +27 -0
- ripple_down_rules/user_interface/gui.py +21 -35
- ripple_down_rules/user_interface/ipython_custom_shell.py +6 -4
- ripple_down_rules/user_interface/object_diagram.py +7 -1
- ripple_down_rules/user_interface/prompt.py +9 -4
- ripple_down_rules/user_interface/template_file_creator.py +55 -32
- ripple_down_rules/utils.py +66 -26
- {ripple_down_rules-0.4.7.dist-info → ripple_down_rules-0.4.9.dist-info}/METADATA +10 -8
- ripple_down_rules-0.4.9.dist-info/RECORD +26 -0
- ripple_down_rules-0.4.7.dist-info/RECORD +0 -25
- {ripple_down_rules-0.4.7.dist-info → ripple_down_rules-0.4.9.dist-info}/WHEEL +0 -0
- {ripple_down_rules-0.4.7.dist-info → ripple_down_rules-0.4.9.dist-info}/licenses/LICENSE +0 -0
- {ripple_down_rules-0.4.7.dist-info → ripple_down_rules-0.4.9.dist-info}/top_level.txt +0 -0
ripple_down_rules/utils.py
CHANGED
@@ -16,14 +16,27 @@ from dataclasses import is_dataclass, fields
|
|
16
16
|
from enum import Enum
|
17
17
|
from textwrap import dedent
|
18
18
|
from types import NoneType
|
19
|
+
from typing import List
|
20
|
+
|
21
|
+
try:
|
22
|
+
import matplotlib
|
23
|
+
from matplotlib import pyplot as plt
|
24
|
+
Figure = plt.Figure
|
25
|
+
except ImportError as e:
|
26
|
+
matplotlib = None
|
27
|
+
plt = None
|
28
|
+
Figure = None
|
29
|
+
logging.debug(f"{e}: matplotlib is not installed")
|
30
|
+
|
31
|
+
try:
|
32
|
+
import networkx as nx
|
33
|
+
except ImportError as e:
|
34
|
+
nx = None
|
35
|
+
logging.debug(f"{e}: networkx is not installed")
|
19
36
|
|
20
|
-
import matplotlib
|
21
|
-
import networkx as nx
|
22
37
|
import requests
|
23
38
|
from anytree import Node, RenderTree
|
24
39
|
from anytree.exporter import DotExporter
|
25
|
-
from matplotlib import pyplot as plt
|
26
|
-
from rospy import logwarn
|
27
40
|
from sqlalchemy import MetaData, inspect
|
28
41
|
from sqlalchemy.orm import Mapped, registry, class_mapper, DeclarativeBase as SQLTable, Session
|
29
42
|
from tabulate import tabulate
|
@@ -107,9 +120,12 @@ def get_imports_from_scope(scope: Dict[str, Any]) -> List[str]:
|
|
107
120
|
return imports
|
108
121
|
|
109
122
|
|
110
|
-
def extract_imports(file_path):
|
111
|
-
|
112
|
-
|
123
|
+
def extract_imports(file_path: Optional[str] = None, tree: Optional[ast.AST] = None) -> Dict[str, Any]:
|
124
|
+
if tree is None:
|
125
|
+
if file_path is None:
|
126
|
+
raise ValueError("Either file_path or tree must be provided")
|
127
|
+
with open(file_path, "r") as f:
|
128
|
+
tree = ast.parse(f.read(), filename=file_path)
|
113
129
|
|
114
130
|
scope = {}
|
115
131
|
|
@@ -131,7 +147,7 @@ def extract_imports(file_path):
|
|
131
147
|
module = importlib.import_module(module_name)
|
132
148
|
scope[asname] = getattr(module, name)
|
133
149
|
except (ImportError, AttributeError) as e:
|
134
|
-
|
150
|
+
logging.warning(f"Could not import {module_name}: {e} while extracting imports from {file_path}")
|
135
151
|
|
136
152
|
return scope
|
137
153
|
|
@@ -162,7 +178,7 @@ def extract_function_source(file_path: str,
|
|
162
178
|
functions_source: Dict[str, Union[str, List[str]]] = {}
|
163
179
|
line_numbers = []
|
164
180
|
for node in tree.body:
|
165
|
-
if isinstance(node, ast.FunctionDef) and node.name in function_names:
|
181
|
+
if isinstance(node, ast.FunctionDef) and (node.name in function_names or len(function_names) == 0):
|
166
182
|
# Get the line numbers of the function
|
167
183
|
lines = source.splitlines()
|
168
184
|
func_lines = lines[node.lineno - 1:node.end_lineno]
|
@@ -170,9 +186,9 @@ def extract_function_source(file_path: str,
|
|
170
186
|
func_lines = func_lines[1:]
|
171
187
|
line_numbers.append((node.lineno, node.end_lineno))
|
172
188
|
functions_source[node.name] = dedent("\n".join(func_lines)) if join_lines else func_lines
|
173
|
-
if len(functions_source)
|
189
|
+
if len(functions_source) >= len(function_names):
|
174
190
|
break
|
175
|
-
if len(functions_source)
|
191
|
+
if len(functions_source) < len(function_names):
|
176
192
|
raise ValueError(f"Could not find all functions in {file_path}: {function_names} not found,"
|
177
193
|
f"functions not found: {set(function_names) - set(functions_source.keys())}")
|
178
194
|
if return_line_numbers:
|
@@ -889,8 +905,8 @@ class SubclassJSONSerializer:
|
|
889
905
|
if not filename.endswith(".json"):
|
890
906
|
filename += ".json"
|
891
907
|
with open(filename, "r") as f:
|
892
|
-
|
893
|
-
deserialized_obj = cls.from_json(
|
908
|
+
rdr_json = json.load(f)
|
909
|
+
deserialized_obj = cls.from_json(rdr_json)
|
894
910
|
cls.data_class_refs.clear()
|
895
911
|
return deserialized_obj
|
896
912
|
|
@@ -937,9 +953,6 @@ class SubclassJSONSerializer:
|
|
937
953
|
|
938
954
|
raise ValueError("Unknown type {}".format(data["_type"]))
|
939
955
|
|
940
|
-
save = to_json_file
|
941
|
-
load = from_json_file
|
942
|
-
|
943
956
|
|
944
957
|
def _pickle_thread(thread_obj) -> Any:
|
945
958
|
"""Return a plain object with user-defined attributes but no thread behavior."""
|
@@ -1082,24 +1095,29 @@ def get_origin_and_args_from_type_hint(type_hint: Type) -> Tuple[Optional[Type],
|
|
1082
1095
|
return origin, args
|
1083
1096
|
|
1084
1097
|
|
1085
|
-
def table_rows_as_str(
|
1098
|
+
def table_rows_as_str(row_dicts: List[Dict[str, Any]], columns_per_row: int = 20):
|
1086
1099
|
"""
|
1087
1100
|
Print a table row.
|
1088
1101
|
|
1089
|
-
:param
|
1102
|
+
:param row_dicts: The rows to print.
|
1090
1103
|
:param columns_per_row: The maximum number of columns per row.
|
1091
1104
|
"""
|
1092
|
-
|
1105
|
+
all_row_dicts_items = [list(row_dict.items()) for row_dict in row_dicts]
|
1093
1106
|
# make items a list of n rows such that each row has a max size of 4
|
1094
|
-
all_items = [all_items[i:i + columns_per_row] for
|
1107
|
+
all_items = [all_items[i:i + columns_per_row] for all_items in all_row_dicts_items
|
1108
|
+
for i in range(0, len(all_items), columns_per_row)]
|
1095
1109
|
keys = [list(map(lambda i: i[0], row)) for row in all_items]
|
1096
1110
|
values = [list(map(lambda i: i[1], row)) for row in all_items]
|
1111
|
+
zipped_keys = list(zip(*keys))
|
1112
|
+
zipped_values = list(zip(*values))
|
1113
|
+
keys_values = [list(zip(zipped_keys[i], zipped_values[i])) for i in range(len(zipped_keys))]
|
1114
|
+
keys_values = [list(r[0]) + list(r[1]) if len(r) > 1 else r[0] for r in keys_values]
|
1097
1115
|
all_table_rows = []
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1116
|
+
row_values = [list(map(lambda v: str(v) if v is not None else "", row)) for row in keys_values]
|
1117
|
+
row_values = [list(map(lambda v: v[:150] + '...' if len(v) > 150 else v, row)) for row in row_values]
|
1118
|
+
row_values = [list(map(lambda v: v.lower() if v in ["True", "False"] else v, row)) for row in row_values]
|
1119
|
+
table = tabulate(row_values, tablefmt='simple_grid', maxcolwidths=[150] * 2)
|
1120
|
+
all_table_rows.append(table)
|
1103
1121
|
return "\n".join(all_table_rows)
|
1104
1122
|
|
1105
1123
|
|
@@ -1348,7 +1366,7 @@ def render_tree(root: Node, use_dot_exporter: bool = False,
|
|
1348
1366
|
de.to_picture(f"{filename}{'.png'}")
|
1349
1367
|
|
1350
1368
|
|
1351
|
-
def draw_tree(root: Node, fig:
|
1369
|
+
def draw_tree(root: Node, fig: Figure):
|
1352
1370
|
"""
|
1353
1371
|
Draw the tree using matplotlib and networkx.
|
1354
1372
|
"""
|
@@ -1372,3 +1390,25 @@ def draw_tree(root: Node, fig: plt.Figure):
|
|
1372
1390
|
nx.draw_networkx_edge_labels(graph, pos, edge_labels=nx.get_edge_attributes(graph, 'weight'),
|
1373
1391
|
ax=fig.gca(), rotate=False, clip_on=False)
|
1374
1392
|
plt.pause(0.1)
|
1393
|
+
|
1394
|
+
|
1395
|
+
def encapsulate_code_lines_into_a_function(code_lines: List[str], function_name: str, function_signature: str,
|
1396
|
+
func_doc: str, case_query: CaseQuery) -> str:
|
1397
|
+
"""
|
1398
|
+
Encapsulate the given code lines into a function with the specified name, signature, and docstring.
|
1399
|
+
|
1400
|
+
:param code_lines: The lines of code to include in the user input.
|
1401
|
+
:param function_name: The name of the function to include in the user input.
|
1402
|
+
:param function_signature: The function signature to include in the user input.
|
1403
|
+
:param func_doc: The function docstring to include in the user input.
|
1404
|
+
:param case_query: The case query object.
|
1405
|
+
"""
|
1406
|
+
code = '\n'.join(code_lines)
|
1407
|
+
code = encapsulate_user_input(code, function_signature, func_doc)
|
1408
|
+
if case_query.is_function:
|
1409
|
+
args = "**case"
|
1410
|
+
else:
|
1411
|
+
args = "case"
|
1412
|
+
if f"return {function_name}({args})" not in code:
|
1413
|
+
code = code.strip() + f"\nreturn {function_name}({args})"
|
1414
|
+
return code
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.9
|
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
|
@@ -682,21 +682,23 @@ Classifier: Programming Language :: Python :: 3
|
|
682
682
|
Description-Content-Type: text/markdown
|
683
683
|
License-File: LICENSE
|
684
684
|
Requires-Dist: anytree>=2.8.0
|
685
|
-
Requires-Dist: pandas>=2.0.3
|
686
|
-
Requires-Dist: networkx>=3.1
|
687
685
|
Requires-Dist: ordered_set>=4
|
688
686
|
Requires-Dist: pygraphviz>=1.7
|
689
|
-
Requires-Dist: ucimlrepo>=0.0.7
|
690
687
|
Requires-Dist: typing-extensions>=4.12.2
|
691
|
-
Requires-Dist: matplotlib>=3.7.5
|
692
|
-
Requires-Dist: sqlalchemy
|
693
|
-
Requires-Dist: pyqt6
|
694
|
-
Requires-Dist: qtconsole
|
695
688
|
Requires-Dist: graphviz
|
696
689
|
Requires-Dist: tabulate
|
697
690
|
Requires-Dist: ipython
|
698
691
|
Requires-Dist: requests
|
699
692
|
Requires-Dist: colorama
|
693
|
+
Requires-Dist: pygments
|
694
|
+
Requires-Dist: sqlalchemy
|
695
|
+
Requires-Dist: pandas
|
696
|
+
Provides-Extra: viz
|
697
|
+
Requires-Dist: networkx>=3.1; extra == "viz"
|
698
|
+
Requires-Dist: matplotlib>=3.7.5; extra == "viz"
|
699
|
+
Provides-Extra: gui
|
700
|
+
Requires-Dist: pyqt6; extra == "gui"
|
701
|
+
Requires-Dist: qtconsole; extra == "gui"
|
700
702
|
Dynamic: license-file
|
701
703
|
|
702
704
|
# Ripple Down Rules (RDR)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
ripple_down_rules/__init__.py,sha256=PUnq-y-UONNX6u9U669iIwMK6S5qMXYECFClTLPBrbI,99
|
2
|
+
ripple_down_rules/datasets.py,sha256=fJbZ7V-UUYTu5XVVpFinTbuzN3YePCnUB01L3AyZVM8,6837
|
3
|
+
ripple_down_rules/experts.py,sha256=9Vc3vx0uhDPy3YlNjwKuWJLl_A-kubRPUU6bMvQhaAg,13237
|
4
|
+
ripple_down_rules/failures.py,sha256=E6ajDUsw3Blom8eVLbA7d_Qnov2conhtZ0UmpQ9ZtSE,302
|
5
|
+
ripple_down_rules/helpers.py,sha256=TvTJU0BA3dPcAyzvZFvAu7jZqsp8Lu0HAAwvuizlGjg,2018
|
6
|
+
ripple_down_rules/rdr.py,sha256=E1OiiZClQyAfGjL64ID-MWYFO4-h8iUAX-Vm9qrOoeQ,48727
|
7
|
+
ripple_down_rules/rdr_decorators.py,sha256=pYCKLgMKgQ6x_252WQtF2t4ZNjWPBxnaWtJ6TpGdcc0,7820
|
8
|
+
ripple_down_rules/rules.py,sha256=TPNVMqW9T-_46BS4WemrspLg5uG8kP6tsPvWWBAzJxg,17515
|
9
|
+
ripple_down_rules/start-code-server.sh,sha256=otClk7VmDgBOX2TS_cjws6K0UwvgAUJhoA0ugkPCLqQ,949
|
10
|
+
ripple_down_rules/utils.py,sha256=uS38KcFceRMzT_470DCL1M0LzETdP5RLwE7cCmfo7eI,51086
|
11
|
+
ripple_down_rules/datastructures/__init__.py,sha256=V2aNgf5C96Y5-IGghra3n9uiefpoIm_QdT7cc_C8cxQ,111
|
12
|
+
ripple_down_rules/datastructures/callable_expression.py,sha256=3EucsD3jWzekhjyzL2y0dyUsucd-aqC9glmgPL0Ubb4,12425
|
13
|
+
ripple_down_rules/datastructures/case.py,sha256=r8kjL9xP_wk84ThXusspgPMrAoed2bGQmKi54fzhmH8,15258
|
14
|
+
ripple_down_rules/datastructures/dataclasses.py,sha256=PuD-7zWqWT2p4FnGvnihHvZlZKg9A1ctnFgVYf2cs-8,8554
|
15
|
+
ripple_down_rules/datastructures/enums.py,sha256=ce7tqS0otfSTNAOwsnXlhsvIn4iW_Y_N3TNebF3YoZs,5700
|
16
|
+
ripple_down_rules/user_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
+
ripple_down_rules/user_interface/gui.py,sha256=SB0gUhgReJ3yx-NEHRPMGVuNRLPRUwW8-qup-Kd4Cfo,27182
|
18
|
+
ripple_down_rules/user_interface/ipython_custom_shell.py,sha256=24MIFwqnAhC6ofObEO6x5xRWRnyQmPpPmTvxbCKBrzM,6514
|
19
|
+
ripple_down_rules/user_interface/object_diagram.py,sha256=tsB6iuLNEbHxp5lR2WjyejjWbnAX_nHF9xS8jNPOQVk,4548
|
20
|
+
ripple_down_rules/user_interface/prompt.py,sha256=AkkltdDIaioN43lkRKDPKSjJcmdSSGZDMYz7AL7X9lE,8082
|
21
|
+
ripple_down_rules/user_interface/template_file_creator.py,sha256=ycCbddy_BJP8d0Q2Sj21UzamhGtqGZuK_e73VTJqznY,13766
|
22
|
+
ripple_down_rules-0.4.9.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
23
|
+
ripple_down_rules-0.4.9.dist-info/METADATA,sha256=T-Q5WS_rd2wJsVcip0d6-so4qlvygGnUdsYBWLVBKEE,43306
|
24
|
+
ripple_down_rules-0.4.9.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
25
|
+
ripple_down_rules-0.4.9.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
|
26
|
+
ripple_down_rules-0.4.9.dist-info/RECORD,,
|
@@ -1,25 +0,0 @@
|
|
1
|
-
ripple_down_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
ripple_down_rules/datasets.py,sha256=fJbZ7V-UUYTu5XVVpFinTbuzN3YePCnUB01L3AyZVM8,6837
|
3
|
-
ripple_down_rules/experts.py,sha256=dEZKv58sdicDByj0T0bu0q6coIBMce6o4t9gJICQy1k,6556
|
4
|
-
ripple_down_rules/failures.py,sha256=E6ajDUsw3Blom8eVLbA7d_Qnov2conhtZ0UmpQ9ZtSE,302
|
5
|
-
ripple_down_rules/helpers.py,sha256=TvTJU0BA3dPcAyzvZFvAu7jZqsp8Lu0HAAwvuizlGjg,2018
|
6
|
-
ripple_down_rules/rdr.py,sha256=jxMvkyQ_2jdyxa5aKmvGRHvD-IJBKjsyOpxvvJbFLPE,45518
|
7
|
-
ripple_down_rules/rdr_decorators.py,sha256=VdmE0JrE8j89b6Af1R1tLZiKfy3h1VCvhAUefN_FLLQ,6753
|
8
|
-
ripple_down_rules/rules.py,sha256=PLNaRLn5tQbq7gNsAe-n9hTjKC80p_7MbfkZWgDxLBg,17474
|
9
|
-
ripple_down_rules/utils.py,sha256=3x6BHCoqEewn40lDtUIWOMQLZ_IA0j7WnY9_YDHvs-o,49192
|
10
|
-
ripple_down_rules/datastructures/__init__.py,sha256=V2aNgf5C96Y5-IGghra3n9uiefpoIm_QdT7cc_C8cxQ,111
|
11
|
-
ripple_down_rules/datastructures/callable_expression.py,sha256=jA7424_mWPbOoPICW3eLMX0-ypxnsW6gOqxrJ7JpDbE,11610
|
12
|
-
ripple_down_rules/datastructures/case.py,sha256=oC8OSdhXvHE-Zx1IIQlad-fsKzQQqr6MZBW24c-dbeU,15191
|
13
|
-
ripple_down_rules/datastructures/dataclasses.py,sha256=GWnUF4h4zfNHSsyBIz3L9y8sLkrXRv0FK_OxzzLc8L8,8183
|
14
|
-
ripple_down_rules/datastructures/enums.py,sha256=ce7tqS0otfSTNAOwsnXlhsvIn4iW_Y_N3TNebF3YoZs,5700
|
15
|
-
ripple_down_rules/user_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
-
ripple_down_rules/user_interface/gui.py,sha256=GlVUYGpMRikrd-FjYCAamdKFAuTAeiq21ZzQvjVKJ4g,27588
|
17
|
-
ripple_down_rules/user_interface/ipython_custom_shell.py,sha256=tc7ms80iPNElm9AYC6i1FlfMKkqHLT8wmOEXg_k9yAU,6275
|
18
|
-
ripple_down_rules/user_interface/object_diagram.py,sha256=84JlEH0nQmtGmP8Su5iRX3ZfqByYHbVwd0BQYYPuckY,4436
|
19
|
-
ripple_down_rules/user_interface/prompt.py,sha256=97s5mhmsqrFTQkfmHssYFko0SPLBDxesHoLumqZO0FA,8028
|
20
|
-
ripple_down_rules/user_interface/template_file_creator.py,sha256=_CEe8H07q62YpImy1p72vXcPHkJ2_Q0n6t56K6g2gPE,12930
|
21
|
-
ripple_down_rules-0.4.7.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
22
|
-
ripple_down_rules-0.4.7.dist-info/METADATA,sha256=NOxEaLxlUHlfwCGv9lgu_083JZl3ls6fcknejdagcm0,43217
|
23
|
-
ripple_down_rules-0.4.7.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
24
|
-
ripple_down_rules-0.4.7.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
|
25
|
-
ripple_down_rules-0.4.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|