ripple-down-rules 0.4.85__tar.gz → 0.4.88__tar.gz

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.
Files changed (116) hide show
  1. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/PKG-INFO +4 -12
  2. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/pyproject.toml +3 -20
  3. ripple_down_rules-0.4.88/pytest.ini +3 -0
  4. ripple_down_rules-0.4.88/src/ripple_down_rules/__init__.py +5 -0
  5. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/datastructures/case.py +7 -5
  6. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/rdr.py +9 -15
  7. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/utils.py +14 -9
  8. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules.egg-info/PKG-INFO +4 -12
  9. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules.egg-info/SOURCES.txt +1 -0
  10. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules.egg-info/requires.txt +2 -11
  11. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_rdr.py +19 -18
  12. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_rdr_alchemy.py +3 -3
  13. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_rdr_world.py +2 -2
  14. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_relational_rdr.py +2 -2
  15. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_relational_rdr_alchemy.py +2 -2
  16. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot.json +4 -4
  17. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_sql_model.py +4 -4
  18. ripple_down_rules-0.4.85/src/ripple_down_rules/__init__.py +0 -1
  19. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/.github/workflows/publish-to-test-pypi.yml +0 -0
  20. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]/shelved.patch +0 -0
  21. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]1/shelved.patch +0 -0
  22. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/LICENSE +0 -0
  23. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/README.md +0 -0
  24. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/examples/readme_example.py +0 -0
  25. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/images/thinking_pr2.jpg +0 -0
  26. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/requirements-dev.txt +0 -0
  27. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/requirements-gui.txt +0 -0
  28. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/requirements-viz.txt +0 -0
  29. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/requirements.txt +0 -0
  30. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_mcrdr_extra.dot +0 -0
  31. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_mcrdr_extra.png +0 -0
  32. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_mcrdr_stop_only.dot +0 -0
  33. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_mcrdr_stop_only.png +0 -0
  34. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_mcrdr_stop_plus_rule.dot +0 -0
  35. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_mcrdr_stop_plus_rule.png +0 -0
  36. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_scrdr.dot +0 -0
  37. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_scrdr.png +0 -0
  38. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_scrdr_2.dot +0 -0
  39. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_scrdr_2.png +0 -0
  40. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_scrdr_3.dot +0 -0
  41. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/complete_scrdr_3.png +0 -0
  42. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/grdr_Habitat.dot +0 -0
  43. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/grdr_Habitat.png +0 -0
  44. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/grdr_Species.dot +0 -0
  45. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/grdr_Species.png +0 -0
  46. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/mcrdr_extra.dot +0 -0
  47. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/mcrdr_extra.png +0 -0
  48. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/mcrdr_extra_classify.dot +0 -0
  49. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/mcrdr_extra_classify.png +0 -0
  50. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/mcrdr_stop_plus_rule_combined.dot +0 -0
  51. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/mcrdr_stop_plus_rule_combined.png +0 -0
  52. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/partial_mcrdr_extra.dot +0 -0
  53. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/partial_mcrdr_extra.png +0 -0
  54. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/relational_scrdr_classify.dot +0 -0
  55. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/results/relational_scrdr_classify.png +0 -0
  56. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/setup.cfg +0 -0
  57. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/datasets.py +0 -0
  58. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/datastructures/__init__.py +0 -0
  59. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/datastructures/callable_expression.py +0 -0
  60. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/datastructures/dataclasses.py +0 -0
  61. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/datastructures/enums.py +0 -0
  62. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/experts.py +0 -0
  63. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/failures.py +0 -0
  64. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/helpers.py +0 -0
  65. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/rdr_decorators.py +0 -0
  66. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/rules.py +0 -0
  67. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/start-code-server.sh +0 -0
  68. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/user_interface/__init__.py +0 -0
  69. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/user_interface/gui.py +0 -0
  70. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/user_interface/ipython_custom_shell.py +0 -0
  71. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/user_interface/object_diagram.py +0 -0
  72. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/user_interface/prompt.py +0 -0
  73. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules/user_interface/template_file_creator.py +0 -0
  74. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules.egg-info/dependency_links.txt +0 -0
  75. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/src/ripple_down_rules.egg-info/top_level.txt +0 -0
  76. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/correct_drawer_rdr_expert_answers_fit.json +0 -0
  77. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/grdr_expert_answers_classify.json +0 -0
  78. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/grdr_expert_answers_fit.json +0 -0
  79. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/grdr_expert_answers_fit_extra.json +0 -0
  80. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.json +0 -0
  81. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mcrdr_expert_answers_classify.json +0 -0
  82. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.json +0 -0
  83. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.json +0 -0
  84. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mcrdr_extra_expert_answers_classify.json +0 -0
  85. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mcrdr_extra_expert_answers_fit.json +0 -0
  86. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.json +0 -0
  87. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mcrdr_stop_only_answers_fit.json +0 -0
  88. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mcrdr_stop_plus_rule_answers_fit.json +0 -0
  89. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mcrdr_stop_plus_rule_combined_expert_answers_fit.json +0 -0
  90. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mcrdr_stop_plus_rule_expert_answers_fit.json +0 -0
  91. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/mutagenic_expert_answers.json +0 -0
  92. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/relational_scrdr_expert_answers_classify.json +0 -0
  93. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/scrdr_expert_answers_classify.json +0 -0
  94. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/scrdr_expert_answers_fit.json +0 -0
  95. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.json +0 -0
  96. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.json +0 -0
  97. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/scrdr_world_expert_answers_fit.json +0 -0
  98. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_expert_answers/view_rdr_expert_answers_fit.json +0 -0
  99. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_generated_rdrs/__init__.py +0 -0
  100. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_helpers/__init__.py +0 -0
  101. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_helpers/helpers.py +0 -0
  102. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_helpers/object_diagram_case_query.png +0 -0
  103. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_helpers/object_diagram_person.png +0 -0
  104. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_json_serialization.py +0 -0
  105. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_object_diagram.py +0 -0
  106. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_on_mutagenic.py +0 -0
  107. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_rdr_decorators.py +0 -0
  108. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_results/datasets_physical_object_is_a_robot.json +0 -0
  109. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_template_file_creator.py +0 -0
  110. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_user_interface/__init__.py +0 -0
  111. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_user_interface/test_ipython.py +0 -0
  112. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_user_interface/test_ipython_copilot.py +0 -0
  113. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_user_interface/test_pdb.py +0 -0
  114. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_user_interface/test_qt_gui.py +0 -0
  115. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_user_interface/test_qt_gui_inline.py +0 -0
  116. {ripple_down_rules-0.4.85 → ripple_down_rules-0.4.88}/test/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripple_down_rules
3
- Version: 0.4.85
3
+ Version: 0.4.88
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
@@ -693,20 +693,12 @@ Requires-Dist: colorama
693
693
  Requires-Dist: pygments
694
694
  Requires-Dist: sqlalchemy
695
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"
696
699
  Provides-Extra: gui
697
700
  Requires-Dist: pyqt6; extra == "gui"
698
701
  Requires-Dist: qtconsole; extra == "gui"
699
- Provides-Extra: viz
700
- Requires-Dist: matplotlib; extra == "viz"
701
- Requires-Dist: networkx; extra == "viz"
702
- Provides-Extra: dev
703
- Requires-Dist: pyqt6; extra == "dev"
704
- Requires-Dist: qtconsole; extra == "dev"
705
- Requires-Dist: matplotlib; extra == "dev"
706
- Requires-Dist: networkx; extra == "dev"
707
- Requires-Dist: pytest; extra == "dev"
708
- Requires-Dist: ucimlrepo>=0.0.7; extra == "dev"
709
- Requires-Dist: pdbpp; extra == "dev"
710
702
  Dynamic: license-file
711
703
 
712
704
  # Ripple Down Rules (RDR)
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "ripple_down_rules"
9
- dynamic = ["version", "dependencies"]
9
+ dynamic = ["version", "dependencies", "optional-dependencies"]
10
10
  description = "Implements the various versions of Ripple Down Rules (RDR) for knowledge representation and reasoning."
11
11
  readme = "README.md"
12
12
  authors = [{ name = "Abdelrhman Bassiouny", email = "abassiou@uni-bremen.de" }]
@@ -22,22 +22,5 @@ include = ["ripple_down_rules*"]
22
22
 
23
23
  [tool.setuptools.dynamic]
24
24
  version = {attr = "ripple_down_rules.__version__"}
25
- dependencies = {file = "requirements.txt"}
26
-
27
- [project.optional-dependencies]
28
- gui = [
29
- "pyqt6",
30
- "qtconsole",
31
- ]
32
- viz = [
33
- "matplotlib",
34
- "networkx",
35
- ]
36
- dev = [
37
- "pyqt6",
38
- "qtconsole",
39
- "matplotlib",
40
- "networkx",
41
- "pytest",
42
- "ucimlrepo>=0.0.7",
43
- "pdbpp"]
25
+ dependencies = { file = ["requirements.txt"] }
26
+ optional-dependencies = { viz = {file = ["requirements-viz.txt"]}, gui = {file = ["requirements-gui.txt"]}}
@@ -0,0 +1,3 @@
1
+ [pytest]
2
+ addopts =
3
+ -s
@@ -0,0 +1,5 @@
1
+ __version__ = "0.4.88"
2
+
3
+ import logging
4
+ logger = logging.Logger("rdr")
5
+ logger.setLevel(logging.INFO)
@@ -354,11 +354,13 @@ def show_current_and_corner_cases(case: Any, targets: Optional[Dict[str, Any]] =
354
354
  if last_evaluated_rule and last_evaluated_rule.fired:
355
355
  corner_row_dict = copy_case(corner_case)
356
356
 
357
+ case_dict.update(targets)
358
+ case_dict.update(current_conclusions)
359
+ all_table_rows = [case_dict]
357
360
  if corner_row_dict:
358
361
  corner_conclusion = last_evaluated_rule.conclusion(case)
359
362
  corner_row_dict.update({corner_conclusion.__class__.__name__: corner_conclusion})
360
- print(table_rows_as_str(corner_row_dict))
361
- print("=" * 50)
362
- case_dict.update(targets)
363
- case_dict.update(current_conclusions)
364
- print(table_rows_as_str(case_dict))
363
+ all_table_rows.append(corner_row_dict)
364
+ # print(table_rows_as_str(corner_row_dict))
365
+ print("\n" + "=" * 50)
366
+ print(table_rows_as_str(all_table_rows))
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import copyreg
4
4
  import importlib
5
- import logging
5
+ from . import logger
6
6
  import sys
7
7
  from abc import ABC, abstractmethod
8
8
  from copy import copy
@@ -13,7 +13,7 @@ try:
13
13
  from matplotlib import pyplot as plt
14
14
  Figure = plt.Figure
15
15
  except ImportError as e:
16
- logging.debug(f"{e}: matplotlib is not installed")
16
+ logger.debug(f"{e}: matplotlib is not installed")
17
17
  matplotlib = None
18
18
  Figure = None
19
19
  plt = None
@@ -122,13 +122,13 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
122
122
  all_predictions = [1 if is_matching(self.classify, case_query) else 0 for case_query in case_queries
123
123
  if case_query.target is not None]
124
124
  all_pred = sum(all_predictions)
125
- print(f"Accuracy: {all_pred}/{len(targets)}")
125
+ logger.info(f"Accuracy: {all_pred}/{len(targets)}")
126
126
  all_predicted = targets and all_pred == len(targets)
127
127
  num_iter_reached = n_iter and i >= n_iter
128
128
  stop_iterating = all_predicted or num_iter_reached
129
129
  if stop_iterating:
130
130
  break
131
- print(f"Finished training in {i} iterations")
131
+ logger.info(f"Finished training in {i} iterations")
132
132
  if animate_tree:
133
133
  plt.ioff()
134
134
  plt.show()
@@ -360,15 +360,13 @@ class RDRWithCodeWriter(RippleDownRules, ABC):
360
360
  return importlib.import_module(name).classify
361
361
 
362
362
  @property
363
- def _default_generated_python_file_name(self) -> str:
363
+ def _default_generated_python_file_name(self) -> Optional[str]:
364
364
  """
365
365
  :return: The default generated python file name.
366
366
  """
367
- if isinstance(self.start_rule.corner_case, Case):
368
- name = self.start_rule.corner_case._name
369
- else:
370
- name = self.start_rule.corner_case.__class__.__name__
371
- return f"{name.lower()}_{self.attribute_name}_{self.acronym.lower()}"
367
+ if self.start_rule is None or self.start_rule.conclusion is None:
368
+ return None
369
+ return f"{self.case_type.__name__.lower()}_{self.attribute_name}_{self.acronym.lower()}"
372
370
 
373
371
  @property
374
372
  def generated_python_defs_file_name(self) -> str:
@@ -958,11 +956,7 @@ class GeneralRDR(RippleDownRules):
958
956
  """
959
957
  if self.start_rule is None or self.start_rule.conclusion is None:
960
958
  return None
961
- if isinstance(self.start_rule.corner_case, Case):
962
- name = self.start_rule.corner_case._name
963
- else:
964
- name = self.start_rule.corner_case.__class__.__name__
965
- return f"{name}_rdr".lower()
959
+ return f"{self.case_type.__name__.lower()}_rdr".lower()
966
960
 
967
961
  @property
968
962
  def conclusion_type_hint(self) -> str:
@@ -1098,24 +1098,29 @@ def get_origin_and_args_from_type_hint(type_hint: Type) -> Tuple[Optional[Type],
1098
1098
  return origin, args
1099
1099
 
1100
1100
 
1101
- def table_rows_as_str(row_dict: Dict[str, Any], columns_per_row: int = 9):
1101
+ def table_rows_as_str(row_dicts: List[Dict[str, Any]], columns_per_row: int = 20):
1102
1102
  """
1103
1103
  Print a table row.
1104
1104
 
1105
- :param row_dict: The row to print.
1105
+ :param row_dicts: The rows to print.
1106
1106
  :param columns_per_row: The maximum number of columns per row.
1107
1107
  """
1108
- all_items = list(row_dict.items())
1108
+ all_row_dicts_items = [list(row_dict.items()) for row_dict in row_dicts]
1109
1109
  # make items a list of n rows such that each row has a max size of 4
1110
- all_items = [all_items[i:i + columns_per_row] for i in range(0, len(all_items), columns_per_row)]
1110
+ all_items = [all_items[i:i + columns_per_row] for all_items in all_row_dicts_items
1111
+ for i in range(0, len(all_items), columns_per_row)]
1111
1112
  keys = [list(map(lambda i: i[0], row)) for row in all_items]
1112
1113
  values = [list(map(lambda i: i[1], row)) for row in all_items]
1114
+ zipped_keys = list(zip(*keys))
1115
+ zipped_values = list(zip(*values))
1116
+ keys_values = [list(zip(zipped_keys[i], zipped_values[i])) for i in range(len(zipped_keys))]
1117
+ keys_values = [list(r[0]) + list(r[1]) if len(r) > 1 else r[0] for r in keys_values]
1113
1118
  all_table_rows = []
1114
- for row_keys, row_values in zip(keys, values):
1115
- row_values = [str(v) if v is not None else "" for v in row_values]
1116
- row_values = [v.lower() if v in ["True", "False"] else v for v in row_values]
1117
- table = tabulate([row_values], headers=row_keys, tablefmt='plain', maxcolwidths=[20] * len(row_keys))
1118
- all_table_rows.append(table)
1119
+ row_values = [list(map(lambda v: str(v) if v is not None else "", row)) for row in keys_values]
1120
+ row_values = [list(map(lambda v: v[:150] + '...' if len(v) > 150 else v, row)) for row in row_values]
1121
+ row_values = [list(map(lambda v: v.lower() if v in ["True", "False"] else v, row)) for row in row_values]
1122
+ table = tabulate(row_values, tablefmt='simple_grid', maxcolwidths=[150] * 2)
1123
+ all_table_rows.append(table)
1119
1124
  return "\n".join(all_table_rows)
1120
1125
 
1121
1126
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripple_down_rules
3
- Version: 0.4.85
3
+ Version: 0.4.88
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
@@ -693,20 +693,12 @@ Requires-Dist: colorama
693
693
  Requires-Dist: pygments
694
694
  Requires-Dist: sqlalchemy
695
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"
696
699
  Provides-Extra: gui
697
700
  Requires-Dist: pyqt6; extra == "gui"
698
701
  Requires-Dist: qtconsole; extra == "gui"
699
- Provides-Extra: viz
700
- Requires-Dist: matplotlib; extra == "viz"
701
- Requires-Dist: networkx; extra == "viz"
702
- Provides-Extra: dev
703
- Requires-Dist: pyqt6; extra == "dev"
704
- Requires-Dist: qtconsole; extra == "dev"
705
- Requires-Dist: matplotlib; extra == "dev"
706
- Requires-Dist: networkx; extra == "dev"
707
- Requires-Dist: pytest; extra == "dev"
708
- Requires-Dist: ucimlrepo>=0.0.7; extra == "dev"
709
- Requires-Dist: pdbpp; extra == "dev"
710
702
  Dynamic: license-file
711
703
 
712
704
  # Ripple Down Rules (RDR)
@@ -1,6 +1,7 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
+ pytest.ini
4
5
  requirements-dev.txt
5
6
  requirements-gui.txt
6
7
  requirements-viz.txt
@@ -11,19 +11,10 @@ pygments
11
11
  sqlalchemy
12
12
  pandas
13
13
 
14
- [dev]
15
- pyqt6
16
- qtconsole
17
- matplotlib
18
- networkx
19
- pytest
20
- ucimlrepo>=0.0.7
21
- pdbpp
22
-
23
14
  [gui]
24
15
  pyqt6
25
16
  qtconsole
26
17
 
27
18
  [viz]
28
- matplotlib
29
- networkx
19
+ networkx>=3.1
20
+ matplotlib>=3.7.5
@@ -32,6 +32,7 @@ class TestRDR(TestCase):
32
32
  cache_file: str = f"{test_results_dir}/zoo_dataset.pkl"
33
33
  app: Optional[QApplication] = None
34
34
  viewer: Optional[RDRCaseViewer] = None
35
+ use_gui: bool = False
35
36
 
36
37
  @classmethod
37
38
  def setUpClass(cls):
@@ -42,7 +43,7 @@ class TestRDR(TestCase):
42
43
  for test_dir in [cls.test_results_dir, cls.expert_answers_dir, cls.generated_rdrs_dir]:
43
44
  if not os.path.exists(test_dir):
44
45
  os.makedirs(test_dir)
45
- if RDRCaseViewer is not None:
46
+ if RDRCaseViewer is not None and QApplication is not None and cls.use_gui:
46
47
  cls.app = QApplication(sys.argv)
47
48
  cls.viewer = RDRCaseViewer()
48
49
 
@@ -68,8 +69,8 @@ class TestRDR(TestCase):
68
69
  expert_answers_dir=self.expert_answers_dir,
69
70
  expert_answers_file="scrdr_expert_answers_fit",
70
71
  load_answers=True)
71
- render_tree(scrdr.start_rule, use_dot_exporter=True,
72
- filename=self.test_results_dir + f"/scrdr")
72
+ # render_tree(scrdr.start_rule, use_dot_exporter=True,
73
+ # filename=self.test_results_dir + f"/scrdr")
73
74
 
74
75
  def test_fit_scrdr_with_no_targets(self):
75
76
  # Test with no targets
@@ -78,8 +79,8 @@ class TestRDR(TestCase):
78
79
  expert_answers_file="scrdr_expert_answers_fit_no_targets",
79
80
  load_answers=True,
80
81
  save_answers=False)
81
- render_tree(scrdr.start_rule, use_dot_exporter=True,
82
- filename=self.test_results_dir + f"/scrdr_no_targets")
82
+ # render_tree(scrdr.start_rule, use_dot_exporter=True,
83
+ # filename=self.test_results_dir + f"/scrdr_no_targets")
83
84
 
84
85
  def test_write_scrdr_no_targets_to_python_file(self):
85
86
  # Test with no targets
@@ -100,8 +101,8 @@ class TestRDR(TestCase):
100
101
  expert_answers_file="mcrdr_expert_answers_fit_no_targets",
101
102
  load_answers=True,
102
103
  save_answers=False)
103
- render_tree(mcrdr.start_rule, use_dot_exporter=True,
104
- filename=self.test_results_dir + f"/mcrdr_no_targets")
104
+ # render_tree(mcrdr.start_rule, use_dot_exporter=True,
105
+ # filename=self.test_results_dir + f"/mcrdr_no_targets")
105
106
  for case, target in zip(self.all_cases[:20], self.targets[:20]):
106
107
  cat = mcrdr.classify(case)
107
108
  self.assertEqual(make_set(cat), make_set(target))
@@ -157,8 +158,8 @@ class TestRDR(TestCase):
157
158
  expert_answers_file="scrdr_multi_line_expert_answers_fit",
158
159
  load_answers=True,
159
160
  save_answers=False)
160
- render_tree(scrdr.start_rule, use_dot_exporter=True,
161
- filename=self.test_results_dir + f"/scrdr_multi_line")
161
+ # render_tree(scrdr.start_rule, use_dot_exporter=True,
162
+ # filename=self.test_results_dir + f"/scrdr_multi_line")
162
163
 
163
164
  def test_write_multi_line_scrdr_to_python_file(self):
164
165
  n = 20
@@ -271,8 +272,8 @@ class TestRDR(TestCase):
271
272
  mcrdr = MultiClassRDR()
272
273
  case_queries = self.case_queries
273
274
  mcrdr.fit(case_queries, expert=expert, animate_tree=draw_tree)
274
- render_tree(mcrdr.start_rule, use_dot_exporter=True,
275
- filename=self.test_results_dir + f"/mcrdr_stop_only")
275
+ # render_tree(mcrdr.start_rule, use_dot_exporter=True,
276
+ # filename=self.test_results_dir + f"/mcrdr_stop_only")
276
277
  for case_query in case_queries:
277
278
  cat = mcrdr.classify(case_query.case)
278
279
  self.assertEqual(make_set(cat), make_set(case_query.target_value))
@@ -293,8 +294,8 @@ class TestRDR(TestCase):
293
294
  mcrdr = MultiClassRDR(mode=MCRDRMode.StopPlusRule)
294
295
  case_queries = self.case_queries
295
296
  mcrdr.fit(case_queries, expert=expert, animate_tree=draw_tree)
296
- render_tree(mcrdr.start_rule, use_dot_exporter=True,
297
- filename=self.test_results_dir + f"/mcrdr_stop_plus_rule")
297
+ # render_tree(mcrdr.start_rule, use_dot_exporter=True,
298
+ # filename=self.test_results_dir + f"/mcrdr_stop_plus_rule")
298
299
  for case_query in case_queries:
299
300
  cat = mcrdr.classify(case_query.case)
300
301
  self.assertEqual(make_set(cat), make_set(case_query.target_value))
@@ -315,8 +316,8 @@ class TestRDR(TestCase):
315
316
  mcrdr = MultiClassRDR(mode=MCRDRMode.StopPlusRuleCombined)
316
317
  case_queries = self.case_queries
317
318
  mcrdr.fit(case_queries, expert=expert, animate_tree=draw_tree)
318
- render_tree(mcrdr.start_rule, use_dot_exporter=True,
319
- filename=self.test_results_dir + f"/mcrdr_stop_plus_rule_combined")
319
+ # render_tree(mcrdr.start_rule, use_dot_exporter=True,
320
+ # filename=self.test_results_dir + f"/mcrdr_stop_plus_rule_combined")
320
321
  for case_query in case_queries:
321
322
  cat = mcrdr.classify(case_query.case)
322
323
  self.assertEqual(make_set(cat), make_set(case_query.target_value))
@@ -353,9 +354,9 @@ class TestRDR(TestCase):
353
354
  def test_fit_grdr(self):
354
355
  grdr, all_targets = get_fit_grdr(self.all_cases, self.targets, draw_tree=False,
355
356
  load_answers=True, save_answers=False)
356
- for conclusion_name, rdr in grdr.start_rules_dict.items():
357
- render_tree(rdr.start_rule, use_dot_exporter=True,
358
- filename=self.test_results_dir + f"/grdr_{conclusion_name}")
357
+ # for conclusion_name, rdr in grdr.start_rules_dict.items():
358
+ # render_tree(rdr.start_rule, use_dot_exporter=True,
359
+ # filename=self.test_results_dir + f"/grdr_{conclusion_name}")
359
360
 
360
361
 
361
362
  if __name__ == "__main__":
@@ -131,9 +131,9 @@ class TestAlchemyRDR(TestCase):
131
131
  case_queries.append(CaseQuery(case, attr, (Species,) if attr == 'species' else (HabitatTable,),
132
132
  True if attr == 'species' else False, _target=target))
133
133
  grdr.fit(case_queries, expert=expert, animate_tree=draw_tree)
134
- for rule in grdr.start_rules:
135
- render_tree(rule, use_dot_exporter=True,
136
- filename=self.test_results_dir + f"/grdr_{type(rule.conclusion).__name__}")
134
+ # for rule in grdr.start_rules:
135
+ # render_tree(rule, use_dot_exporter=True,
136
+ # filename=self.test_results_dir + f"/grdr_{type(rule.conclusion).__name__}")
137
137
 
138
138
  for case, case_targets in zip(self.all_cases[:n], habitat_targets):
139
139
  cat = grdr.classify(case)
@@ -112,7 +112,7 @@ class TestRDRWorld(TestCase):
112
112
  view = Drawer(handle, container, world=world)
113
113
  all_possible_drawers.append(view)
114
114
 
115
- print(all_possible_drawers)
115
+ # print(all_possible_drawers)
116
116
  cls.drawer_case_queries = [CaseQuery(possible_drawer, "correct", (bool,), True, default_value=False)
117
117
  for possible_drawer in all_possible_drawers]
118
118
  cls.app = QApplication(sys.argv)
@@ -152,7 +152,7 @@ class TestRDRWorld(TestCase):
152
152
  expert.save_answers(filename)
153
153
 
154
154
  found_views = rdr.classify(self.world)
155
- print(found_views)
155
+ # print(found_views)
156
156
  for view in views:
157
157
  self.assertTrue(len([v for v in found_views["views"] if isinstance(v, view)]) > 0)
158
158
 
@@ -56,8 +56,8 @@ class RelationalRDRTestCase(TestCase):
56
56
 
57
57
  scrdr = SingleClassRDR()
58
58
  cat = scrdr.fit_case(CaseQuery(self.robot, "contained_objects", (PhysicalObject,), False), expert=expert)
59
- render_tree(scrdr.start_rule, use_dot_exporter=True,
60
- filename=self.test_results_dir + "/relational_scrdr_classify")
59
+ # render_tree(scrdr.start_rule, use_dot_exporter=True,
60
+ # filename=self.test_results_dir + "/relational_scrdr_classify")
61
61
  self.assertEqual(cat, self.target)
62
62
 
63
63
  if save_answers:
@@ -155,8 +155,8 @@ class RelationalRDRTestCase(TestCase):
155
155
 
156
156
  scrdr = SingleClassRDR()
157
157
  cat = scrdr.fit_case(CaseQuery(self.robot, "contained_objects", (PhysicalObject,), False), expert=expert)
158
- render_tree(scrdr.start_rule, use_dot_exporter=True,
159
- filename=self.test_results_dir + "/relational_scrdr_classify")
158
+ # render_tree(scrdr.start_rule, use_dot_exporter=True,
159
+ # filename=self.test_results_dir + "/relational_scrdr_classify")
160
160
  self.assertEqual(cat, self.target)
161
161
 
162
162
  if save_answers:
@@ -12,9 +12,9 @@
12
12
  "builtins.bool"
13
13
  ],
14
14
  "scope": {
15
- "List": "typing.List",
15
+ "PhysicalObject": "ripple_down_rules.datasets.PhysicalObject",
16
16
  "Robot": "ripple_down_rules.datasets.Robot",
17
- "PhysicalObject": "ripple_down_rules.datasets.PhysicalObject"
17
+ "List": "typing.List"
18
18
  },
19
19
  "conclusion": {
20
20
  "_type": "builtins.NoneType",
@@ -31,9 +31,9 @@
31
31
  "builtins.list"
32
32
  ],
33
33
  "scope": {
34
- "List": "typing.List",
34
+ "PhysicalObject": "ripple_down_rules.datasets.PhysicalObject",
35
35
  "Robot": "ripple_down_rules.datasets.Robot",
36
- "PhysicalObject": "ripple_down_rules.datasets.PhysicalObject"
36
+ "List": "typing.List"
37
37
  },
38
38
  "conclusion": {
39
39
  "_type": "builtins.NoneType",
@@ -18,17 +18,17 @@ class TestDDL(unittest.TestCase):
18
18
  a1 = MappedAnimal(name="animal", hair=True, feathers=False, eggs=True, milk=False, airborne=False, aquatic=False, predator=False,
19
19
  toothed=True, backbone=True, breathes=True, venomous=False, fins=False, legs=4, tail=True,
20
20
  domestic=False, catsize=True, species=Species.mammal)
21
- print(a1.habitats)
22
- print(isinstance(a1.habitats, set))
21
+ # print(a1.habitats)
22
+ # print(isinstance(a1.habitats, set))
23
23
  self.session.add(a1)
24
24
  self.session.commit()
25
25
 
26
26
  animals = self.session.scalars(select(MappedAnimal)).all()
27
27
 
28
28
  a1.habitats.add(HabitatTable(Habitat.water))
29
- print(a1.habitats)
29
+ # print(a1.habitats)
30
30
  self.session.commit()
31
31
 
32
32
  queried_a1 = self.session.scalars(select(HabitatTable)).first()
33
- print(queried_a1)
33
+ # print(queried_a1)
34
34
 
@@ -1 +0,0 @@
1
- __version__ = "0.4.85"