ripple-down-rules 0.6.28__tar.gz → 0.6.29__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.
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/PKG-INFO +1 -1
- ripple_down_rules-0.6.29/src/ripple_down_rules/__init__.py +5 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/datastructures/callable_expression.py +4 -2
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/experts.py +43 -28
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/rdr.py +7 -3
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/utils.py +21 -8
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules.egg-info/PKG-INFO +1 -1
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules.egg-info/SOURCES.txt +9 -0
- ripple_down_rules-0.6.29/test/test_expert_answers/grdr_expert_answers_fit.py +105 -0
- ripple_down_rules-0.6.29/test/test_expert_answers/grdr_expert_answers_fit_no_targets.py +224 -0
- ripple_down_rules-0.6.29/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.py +573 -0
- ripple_down_rules-0.6.29/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.py +378 -0
- ripple_down_rules-0.6.29/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.py +133 -0
- ripple_down_rules-0.6.29/test/test_expert_answers/scrdr_expert_answers_fit.py +252 -0
- ripple_down_rules-0.6.29/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.py +552 -0
- ripple_down_rules-0.6.29/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.py +111 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_helpers/helpers.py +3 -3
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_rdr.py +1 -0
- ripple_down_rules-0.6.29/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/__init__.py +1 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/physical_object_select_objects_that_are_parts_of_robot_output__mcrdr.py +1 -1
- ripple_down_rules-0.6.28/src/ripple_down_rules/__init__.py +0 -5
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/.github/workflows/build_and_deploy_doc.yml +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/.github/workflows/ci.yml +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/.github/workflows/publish-to-test-pypi.yml +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/.gitignore +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]/shelved.patch +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]1/shelved.patch +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/LICENSE +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/README.md +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/doc/_config.yml +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/doc/_toc.yml +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/doc/bibliography.md +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/doc/intro.md +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/doc/references.bib +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/doc/requirements.txt +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/examples/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/examples/animal_species.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/examples/part_containment_rdr/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/examples/part_containment_rdr/rdr_metadata/part_containment_rdr.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/examples/part_containment_rdr/robot_contained_objects_mcrdr.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/examples/part_containment_rdr/robot_contained_objects_mcrdr_defs.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/examples/part_containment_rdr/robot_rdr.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/examples/relational_example.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/images/scrdr.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/images/scrdr.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/images/thinking_pr2.jpg +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/pyproject.toml +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/pytest.ini +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/requirements-dev-ci.txt +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/requirements-dev.txt +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/requirements-gui.txt +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/requirements-viz.txt +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/requirements.txt +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_mcrdr_extra.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_mcrdr_extra.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_mcrdr_stop_only.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_mcrdr_stop_only.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_mcrdr_stop_plus_rule.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_mcrdr_stop_plus_rule.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_scrdr.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_scrdr.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_scrdr_2.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_scrdr_2.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_scrdr_3.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/complete_scrdr_3.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/grdr_Habitat.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/grdr_Habitat.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/grdr_Species.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/grdr_Species.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/mcrdr_extra.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/mcrdr_extra.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/mcrdr_extra_classify.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/mcrdr_extra_classify.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/mcrdr_stop_plus_rule_combined.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/mcrdr_stop_plus_rule_combined.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/partial_mcrdr_extra.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/partial_mcrdr_extra.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/relational_scrdr_classify.dot +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/results/relational_scrdr_classify.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/scripts/live_dot_server_client.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/setup.cfg +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/datastructures/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/datastructures/case.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/datastructures/dataclasses.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/datastructures/enums.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/helpers.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/rdr_decorators.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/rules.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/start-code-server.sh +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/user_interface/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/user_interface/gui.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/user_interface/ipython_custom_shell.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/user_interface/object_diagram.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/user_interface/prompt.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules/user_interface/template_file_creator.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules.egg-info/dependency_links.txt +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules.egg-info/requires.txt +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules.egg-info/top_level.txt +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/conf/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/conf/world/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/conf/world/base_config.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/conf/world/handles_and_containers.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/conftest.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/datasets.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/factories/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/factories/world/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/factories/world/handles_and_containers.py +0 -0
- {ripple_down_rules-0.6.28/test/test_results/datasets_physical_object_is_a_robot → ripple_down_rules-0.6.29/test/test_expert_answers}/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/correct_drawer_rdr_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/drawer_cabinet_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/grdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/grdr_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/grdr_expert_answers_fit_extra.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mcrdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mcrdr_extra_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mcrdr_extra_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mcrdr_stop_only_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mcrdr_stop_plus_rule_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mcrdr_stop_plus_rule_combined_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mcrdr_stop_plus_rule_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/mutagenic_expert_answers.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/relational_scrdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/scrdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/scrdr_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_expert_answers/scrdr_world_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_generated_rdrs/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_helpers/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_helpers/object_diagram_case_query.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_helpers/object_diagram_person.png +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_json_serialization.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_object_diagram.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_on_mutagenic.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_rdr_alchemy.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_rdr_decorators.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_rdr_helpers_rdrs.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_rdr_world/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_rdr_world/conftest.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_rdr_world/test_rdr_world.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_relational_rdr.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_relational_rdr_alchemy.py +0 -0
- {ripple_down_rules-0.6.28/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot → ripple_down_rules-0.6.29/test/test_results/datasets_physical_object_is_a_robot}/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr_defs.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_rdr.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_results/datasets_physical_object_is_a_robot/rdr_metadata/datasets_physical_object_is_a_robot.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/physical_object_select_objects_that_are_parts_of_robot_output__mcrdr_defs.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/physical_object_select_objects_that_are_parts_of_robot_rdr.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/rdr_metadata/datasets_physical_object_select_objects_that_are_parts_of_robot.json +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_sql_model.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_template_file_creator.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_user_interface/__init__.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_user_interface/test_ipython.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_user_interface/test_ipython_copilot.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_user_interface/test_prompt.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/test/test_user_interface/test_qt_gui_inline.py +0 -0
- {ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/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.6.
|
3
|
+
Version: 0.6.29
|
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
|
@@ -120,7 +120,9 @@ class CallableExpression(SubclassJSONSerializer):
|
|
120
120
|
self.user_defined_name = user_input.split('(')[0].replace('def ', '')
|
121
121
|
else:
|
122
122
|
self.user_defined_name = user_input
|
123
|
-
self.
|
123
|
+
if f"def {self.encapsulating_function_name}" not in user_input:
|
124
|
+
user_input = encapsulate_user_input(user_input, self.get_encapsulating_function())
|
125
|
+
self._user_input: str = user_input
|
124
126
|
if conclusion_type is not None:
|
125
127
|
if is_iterable(conclusion_type):
|
126
128
|
conclusion_type = tuple(conclusion_type)
|
@@ -308,7 +310,7 @@ def parse_string_to_expression(expression_str: str) -> AST:
|
|
308
310
|
:param expression_str: The string which will be parsed.
|
309
311
|
:return: The parsed expression.
|
310
312
|
"""
|
311
|
-
if not expression_str.startswith(CallableExpression.
|
313
|
+
if not expression_str.startswith(f"def {CallableExpression.encapsulating_function_name}"):
|
312
314
|
expression_str = encapsulate_user_input(expression_str, CallableExpression.get_encapsulating_function())
|
313
315
|
mode = 'exec' if expression_str.startswith('def') else 'eval'
|
314
316
|
tree = ast.parse(expression_str, mode=mode)
|
@@ -6,6 +6,8 @@ import logging
|
|
6
6
|
import os
|
7
7
|
import uuid
|
8
8
|
from abc import ABC, abstractmethod
|
9
|
+
from textwrap import dedent, indent
|
10
|
+
from typing import Tuple, Dict
|
9
11
|
|
10
12
|
from typing_extensions import Optional, TYPE_CHECKING, List
|
11
13
|
|
@@ -13,6 +15,7 @@ from .datastructures.callable_expression import CallableExpression
|
|
13
15
|
from .datastructures.enums import PromptFor
|
14
16
|
from .datastructures.dataclasses import CaseQuery
|
15
17
|
from .datastructures.case import show_current_and_corner_cases
|
18
|
+
from .user_interface.template_file_creator import TemplateFileCreator
|
16
19
|
from .utils import extract_imports, extract_function_source, get_imports_from_scope, encapsulate_user_input
|
17
20
|
|
18
21
|
try:
|
@@ -46,14 +49,12 @@ class Expert(ABC):
|
|
46
49
|
answers_save_path: Optional[str] = None):
|
47
50
|
self.all_expert_answers = []
|
48
51
|
self.use_loaded_answers = use_loaded_answers
|
49
|
-
self.append =
|
52
|
+
self.append = True
|
50
53
|
self.answers_save_path = answers_save_path
|
51
54
|
if answers_save_path is not None and os.path.exists(answers_save_path + '.py'):
|
52
55
|
if use_loaded_answers:
|
53
56
|
self.load_answers(answers_save_path)
|
54
|
-
|
55
|
-
os.remove(answers_save_path + '.py')
|
56
|
-
self.append = True
|
57
|
+
os.remove(answers_save_path + '.py')
|
57
58
|
|
58
59
|
@abstractmethod
|
59
60
|
def ask_for_conditions(self, case_query: CaseQuery, last_evaluated_rule: Optional[Rule] = None) \
|
@@ -89,28 +90,26 @@ class Expert(ABC):
|
|
89
90
|
"answers_save_path attribute.")
|
90
91
|
if path is None:
|
91
92
|
path = self.answers_save_path
|
92
|
-
if os.path.exists(path + '.json'):
|
93
|
-
os.remove(path + '.json')
|
94
93
|
if os.path.exists(path + '.py'):
|
95
94
|
os.remove(path + '.py')
|
96
95
|
self.all_expert_answers = []
|
97
96
|
|
98
|
-
def save_answers(self, path: Optional[str] = None):
|
97
|
+
def save_answers(self, path: Optional[str] = None, expert_answers: Optional[List[Tuple[Dict, str]]] = None):
|
99
98
|
"""
|
100
99
|
Save the expert answers to a file.
|
101
100
|
|
102
101
|
:param path: The path to save the answers to.
|
102
|
+
:param expert_answers: The expert answers to save.
|
103
103
|
"""
|
104
|
+
expert_answers = expert_answers if expert_answers else self.all_expert_answers
|
105
|
+
if not any(expert_answers):
|
106
|
+
return
|
104
107
|
if path is None and self.answers_save_path is None:
|
105
108
|
raise ValueError("No path provided to save expert answers, either provide a path or set the "
|
106
109
|
"answers_save_path attribute.")
|
107
110
|
if path is None:
|
108
111
|
path = self.answers_save_path
|
109
|
-
|
110
|
-
if is_json:
|
111
|
-
self._save_to_json(path)
|
112
|
-
else:
|
113
|
-
self._save_to_python(path)
|
112
|
+
self._save_to_python(path, expert_answers=expert_answers)
|
114
113
|
|
115
114
|
def _save_to_json(self, path: str):
|
116
115
|
"""
|
@@ -127,12 +126,14 @@ class Expert(ABC):
|
|
127
126
|
with open(path + '.json', "w") as f:
|
128
127
|
json.dump(all_answers, f)
|
129
128
|
|
130
|
-
def _save_to_python(self, path: str):
|
129
|
+
def _save_to_python(self, path: str, expert_answers: Optional[List[Tuple[Dict, str]]] = None):
|
131
130
|
"""
|
132
131
|
Save the expert answers to a Python file.
|
133
132
|
|
134
133
|
:param path: The path to save the answers to.
|
134
|
+
:param expert_answers: The expert answers to save.
|
135
135
|
"""
|
136
|
+
expert_answers = expert_answers if expert_answers else self.all_expert_answers
|
136
137
|
dir_name = os.path.dirname(path)
|
137
138
|
if not os.path.exists(dir_name + '/__init__.py'):
|
138
139
|
os.makedirs(dir_name, exist_ok=True)
|
@@ -145,18 +146,13 @@ class Expert(ABC):
|
|
145
146
|
current_file_data = f.read()
|
146
147
|
action = 'a' if self.append and current_file_data is not None else 'w'
|
147
148
|
with open(path + '.py', action) as f:
|
148
|
-
for scope, func_source in
|
149
|
+
for scope, func_source in expert_answers:
|
149
150
|
if len(scope) > 0:
|
150
151
|
imports = '\n'.join(get_imports_from_scope(scope)) + '\n\n\n'
|
151
152
|
else:
|
152
153
|
imports = ''
|
153
|
-
if func_source is
|
154
|
-
uid = uuid.uuid4().hex
|
155
|
-
func_source = encapsulate_user_input(func_source, CallableExpression.get_encapsulating_function(f'_{uid}'))
|
156
|
-
else:
|
154
|
+
if func_source is None:
|
157
155
|
func_source = 'pass # No user input provided for this case.\n'
|
158
|
-
if current_file_data is not None and func_source[1:] in current_file_data:
|
159
|
-
continue
|
160
156
|
f.write(imports + func_source + '\n' + '\n\n\n\'===New Answer===\'\n\n\n')
|
161
157
|
|
162
158
|
def load_answers(self, path: Optional[str] = None):
|
@@ -170,11 +166,10 @@ class Expert(ABC):
|
|
170
166
|
"answers_save_path attribute.")
|
171
167
|
if path is None:
|
172
168
|
path = self.answers_save_path
|
173
|
-
|
174
|
-
if is_json:
|
175
|
-
self._load_answers_from_json(path)
|
176
|
-
elif os.path.exists(path + '.py'):
|
169
|
+
if os.path.exists(path + '.py'):
|
177
170
|
self._load_answers_from_python(path)
|
171
|
+
elif os.path.exists(path + '.json'):
|
172
|
+
self._load_answers_from_json(path)
|
178
173
|
|
179
174
|
def _load_answers_from_json(self, path: str):
|
180
175
|
"""
|
@@ -195,15 +190,15 @@ class Expert(ABC):
|
|
195
190
|
file_path = path + '.py'
|
196
191
|
with open(file_path, "r") as f:
|
197
192
|
all_answers = f.read().split('\n\n\n\'===New Answer===\'\n\n\n')[:-1]
|
198
|
-
all_function_sources =
|
199
|
-
all_function_sources_names = list(extract_function_source(file_path, []).keys())
|
193
|
+
all_function_sources = extract_function_source(file_path, [], as_list=True)
|
200
194
|
for i, answer in enumerate(all_answers):
|
201
195
|
answer = answer.strip('\n').strip()
|
202
196
|
if 'def ' not in answer and 'pass' in answer:
|
203
197
|
self.all_expert_answers.append(({}, None))
|
204
198
|
continue
|
205
199
|
scope = extract_imports(tree=ast.parse(answer))
|
206
|
-
|
200
|
+
func_name = all_function_sources[i].split('def ')[1].split('(')[0]
|
201
|
+
function_source = all_function_sources[i].replace(func_name,
|
207
202
|
CallableExpression.encapsulating_function_name)
|
208
203
|
self.all_expert_answers.append((scope, function_source))
|
209
204
|
|
@@ -249,6 +244,8 @@ class Human(Expert):
|
|
249
244
|
if user_input is not None:
|
250
245
|
case_query.scope.update(loaded_scope)
|
251
246
|
condition = CallableExpression(user_input, bool, scope=case_query.scope)
|
247
|
+
if self.answers_save_path is not None and not any(loaded_scope):
|
248
|
+
self.convert_json_answer_to_python_answer(case_query, user_input, condition, PromptFor.Conditions)
|
252
249
|
else:
|
253
250
|
user_input, condition = self.user_prompt.prompt_user_for_expression(case_query, PromptFor.Conditions, prompt_str=data_to_show)
|
254
251
|
if user_input == 'exit':
|
@@ -260,6 +257,20 @@ class Human(Expert):
|
|
260
257
|
case_query.conditions = condition
|
261
258
|
return condition
|
262
259
|
|
260
|
+
def convert_json_answer_to_python_answer(self, case_query: CaseQuery, user_input: str,
|
261
|
+
callable_expression: CallableExpression,
|
262
|
+
prompt_for: PromptFor):
|
263
|
+
case_query.scope['case'] = case_query.case
|
264
|
+
tfc = TemplateFileCreator(case_query, prompt_for=prompt_for)
|
265
|
+
code = tfc.build_boilerplate_code()
|
266
|
+
if user_input.startswith('def'):
|
267
|
+
user_input = '\n'.join(user_input.split('\n')[1:])
|
268
|
+
user_input = indent(dedent(user_input), " " * 4).strip()
|
269
|
+
code = code.replace('pass', user_input)
|
270
|
+
else:
|
271
|
+
code = code.replace('pass', f"return {user_input}")
|
272
|
+
self.save_answers(expert_answers=[({}, code)])
|
273
|
+
|
263
274
|
def ask_for_conclusion(self, case_query: CaseQuery) -> Optional[CallableExpression]:
|
264
275
|
"""
|
265
276
|
Ask the expert to provide a conclusion for the case.
|
@@ -279,13 +290,17 @@ class Human(Expert):
|
|
279
290
|
expression = CallableExpression(expert_input, case_query.attribute_type,
|
280
291
|
scope=case_query.scope,
|
281
292
|
mutually_exclusive=case_query.mutually_exclusive)
|
293
|
+
if self.answers_save_path is not None and not any(loaded_scope):
|
294
|
+
self.convert_json_answer_to_python_answer(case_query, expert_input, expression,
|
295
|
+
PromptFor.Conclusion)
|
282
296
|
except IndexError:
|
283
297
|
self.use_loaded_answers = False
|
284
298
|
if not self.use_loaded_answers:
|
285
299
|
data_to_show = None
|
286
300
|
if self.user_prompt.viewer is None:
|
287
301
|
data_to_show = show_current_and_corner_cases(case_query.case)
|
288
|
-
expert_input, expression = self.user_prompt.prompt_user_for_expression(case_query, PromptFor.Conclusion,
|
302
|
+
expert_input, expression = self.user_prompt.prompt_user_for_expression(case_query, PromptFor.Conclusion,
|
303
|
+
prompt_str=data_to_show)
|
289
304
|
if expert_input is None:
|
290
305
|
self.all_expert_answers.append(({}, None))
|
291
306
|
elif expert_input != 'exit':
|
@@ -230,7 +230,8 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
|
|
230
230
|
num_rules: int = 0
|
231
231
|
while not stop_iterating:
|
232
232
|
for case_query in case_queries:
|
233
|
-
pred_cat = self.fit_case(case_query, expert=expert,
|
233
|
+
pred_cat = self.fit_case(case_query, expert=expert, clear_expert_answers=False,
|
234
|
+
**kwargs_for_fit_case)
|
234
235
|
if case_query.target is None:
|
235
236
|
continue
|
236
237
|
target = {case_query.attribute_name: case_query.target(case_query.case)}
|
@@ -308,6 +309,7 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
|
|
308
309
|
update_existing_rules: bool = True,
|
309
310
|
scenario: Optional[Callable] = None,
|
310
311
|
ask_now: Callable = lambda _: True,
|
312
|
+
clear_expert_answers: bool = True,
|
311
313
|
**kwargs) \
|
312
314
|
-> Union[CallableExpression, Dict[str, CallableExpression]]:
|
313
315
|
"""
|
@@ -319,7 +321,8 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
|
|
319
321
|
:param update_existing_rules: Whether to update the existing same conclusion type rules that already gave
|
320
322
|
some conclusions with the type required by the case query.
|
321
323
|
:param scenario: The scenario at which the case was created, this is used to recreate the case if needed.
|
322
|
-
:ask_now: Whether to ask the expert for refinements or alternatives.
|
324
|
+
:param ask_now: Whether to ask the expert for refinements or alternatives.
|
325
|
+
:param clear_expert_answers: Whether to clear expert answers after saving the new rule.
|
323
326
|
:return: The category that the case belongs to.
|
324
327
|
"""
|
325
328
|
if case_query is None:
|
@@ -348,7 +351,8 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
|
|
348
351
|
|
349
352
|
if self.save_dir is not None:
|
350
353
|
self.save()
|
351
|
-
|
354
|
+
if clear_expert_answers:
|
355
|
+
expert.clear_answers()
|
352
356
|
|
353
357
|
return fit_case_result
|
354
358
|
|
@@ -146,7 +146,8 @@ def extract_imports(file_path: Optional[str] = None, tree: Optional[ast.AST] = N
|
|
146
146
|
def extract_function_source(file_path: str,
|
147
147
|
function_names: List[str], join_lines: bool = True,
|
148
148
|
return_line_numbers: bool = False,
|
149
|
-
include_signature: bool = True
|
149
|
+
include_signature: bool = True,
|
150
|
+
as_list: bool = False) \
|
150
151
|
-> Union[Dict[str, Union[str, List[str]]],
|
151
152
|
Tuple[Dict[str, Union[str, List[str]]], Dict[str, Tuple[int, int]]]]:
|
152
153
|
"""
|
@@ -157,6 +158,8 @@ def extract_function_source(file_path: str,
|
|
157
158
|
:param join_lines: Whether to join the lines of the function.
|
158
159
|
:param return_line_numbers: Whether to return the line numbers of the function.
|
159
160
|
:param include_signature: Whether to include the function signature in the source code.
|
161
|
+
:param as_list: Whether to return a list of function sources instead of dict (useful when there is multiple
|
162
|
+
functions with same name).
|
160
163
|
:return: A dictionary mapping function names to their source code as a string if join_lines is True,
|
161
164
|
otherwise as a list of strings.
|
162
165
|
"""
|
@@ -167,7 +170,9 @@ def extract_function_source(file_path: str,
|
|
167
170
|
tree = ast.parse(source)
|
168
171
|
function_names = make_list(function_names)
|
169
172
|
functions_source: Dict[str, Union[str, List[str]]] = {}
|
173
|
+
functions_source_list: List[Union[str, List[str]]] = []
|
170
174
|
line_numbers: Dict[str, Tuple[int, int]] = {}
|
175
|
+
line_numbers_list: List[Tuple[int, int]] = []
|
171
176
|
for node in tree.body:
|
172
177
|
if isinstance(node, ast.FunctionDef) and (node.name in function_names or len(function_names) == 0):
|
173
178
|
# Get the line numbers of the function
|
@@ -175,16 +180,24 @@ def extract_function_source(file_path: str,
|
|
175
180
|
func_lines = lines[node.lineno - 1:node.end_lineno]
|
176
181
|
if not include_signature:
|
177
182
|
func_lines = func_lines[1:]
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
+
if as_list:
|
184
|
+
line_numbers_list.append((node.lineno, node.end_lineno))
|
185
|
+
else:
|
186
|
+
line_numbers[node.name] = (node.lineno, node.end_lineno)
|
187
|
+
parsed_function = dedent("\n".join(func_lines)) if join_lines else func_lines
|
188
|
+
if as_list:
|
189
|
+
functions_source_list.append(parsed_function)
|
190
|
+
else:
|
191
|
+
functions_source[node.name] = parsed_function
|
192
|
+
if len(function_names) > 0:
|
193
|
+
if len(functions_source) >= len(function_names) or len(functions_source_list) >= len(function_names):
|
194
|
+
break
|
195
|
+
if len(functions_source) < len(function_names) and len(functions_source_list) < len(function_names):
|
183
196
|
logger.warning(f"Could not find all functions in {file_path}: {function_names} not found, "
|
184
197
|
f"functions not found: {set(function_names) - set(functions_source.keys())}")
|
185
198
|
if return_line_numbers:
|
186
|
-
return functions_source, line_numbers
|
187
|
-
return functions_source
|
199
|
+
return functions_source if not as_list else functions_source_list, line_numbers if not as_list else line_numbers_list
|
200
|
+
return functions_source if not as_list else functions_source_list
|
188
201
|
|
189
202
|
|
190
203
|
def encapsulate_user_input(user_input: str, func_signature: str, func_doc: Optional[str] = None) -> str:
|
{ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules.egg-info/PKG-INFO
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.6.
|
3
|
+
Version: 0.6.29
|
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
|
{ripple_down_rules-0.6.28 → ripple_down_rules-0.6.29}/src/ripple_down_rules.egg-info/SOURCES.txt
RENAMED
@@ -103,18 +103,24 @@ test/conf/world/handles_and_containers.py
|
|
103
103
|
test/factories/__init__.py
|
104
104
|
test/factories/world/__init__.py
|
105
105
|
test/factories/world/handles_and_containers.py
|
106
|
+
test/test_expert_answers/__init__.py
|
106
107
|
test/test_expert_answers/correct_drawer_rdr_expert_answers_fit.json
|
107
108
|
test/test_expert_answers/drawer_cabinet_expert_answers_fit.json
|
108
109
|
test/test_expert_answers/grdr_expert_answers_classify.json
|
109
110
|
test/test_expert_answers/grdr_expert_answers_fit.json
|
111
|
+
test/test_expert_answers/grdr_expert_answers_fit.py
|
110
112
|
test/test_expert_answers/grdr_expert_answers_fit_extra.json
|
111
113
|
test/test_expert_answers/grdr_expert_answers_fit_no_targets.json
|
114
|
+
test/test_expert_answers/grdr_expert_answers_fit_no_targets.py
|
112
115
|
test/test_expert_answers/mcrdr_expert_answers_classify.json
|
113
116
|
test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.json
|
117
|
+
test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.py
|
114
118
|
test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.json
|
119
|
+
test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.py
|
115
120
|
test/test_expert_answers/mcrdr_extra_expert_answers_classify.json
|
116
121
|
test/test_expert_answers/mcrdr_extra_expert_answers_fit.json
|
117
122
|
test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.json
|
123
|
+
test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.py
|
118
124
|
test/test_expert_answers/mcrdr_stop_only_answers_fit.json
|
119
125
|
test/test_expert_answers/mcrdr_stop_plus_rule_answers_fit.json
|
120
126
|
test/test_expert_answers/mcrdr_stop_plus_rule_combined_expert_answers_fit.json
|
@@ -123,8 +129,11 @@ test/test_expert_answers/mutagenic_expert_answers.json
|
|
123
129
|
test/test_expert_answers/relational_scrdr_expert_answers_classify.json
|
124
130
|
test/test_expert_answers/scrdr_expert_answers_classify.json
|
125
131
|
test/test_expert_answers/scrdr_expert_answers_fit.json
|
132
|
+
test/test_expert_answers/scrdr_expert_answers_fit.py
|
126
133
|
test/test_expert_answers/scrdr_expert_answers_fit_no_targets.json
|
134
|
+
test/test_expert_answers/scrdr_expert_answers_fit_no_targets.py
|
127
135
|
test/test_expert_answers/scrdr_multi_line_expert_answers_fit.json
|
136
|
+
test/test_expert_answers/scrdr_multi_line_expert_answers_fit.py
|
128
137
|
test/test_expert_answers/scrdr_world_expert_answers_fit.json
|
129
138
|
test/test_generated_rdrs/__init__.py
|
130
139
|
test/test_helpers/__init__.py
|
@@ -0,0 +1,105 @@
|
|
1
|
+
from typing_extensions import Any, Callable, List, Optional, Tuple, Type
|
2
|
+
from test.datasets import Habitat, Species, load_zoo_cases
|
3
|
+
from ripple_down_rules.datastructures.case import Case
|
4
|
+
from ripple_down_rules.datastructures.dataclasses import CaseQuery
|
5
|
+
from ripple_down_rules.datastructures.enums import Category
|
6
|
+
from ripple_down_rules.experts import Human
|
7
|
+
from ripple_down_rules.rdr import GeneralRDR, MultiClassRDR, SingleClassRDR
|
8
|
+
from ripple_down_rules.utils import make_set
|
9
|
+
from test.test_helpers.helpers import get_fit_grdr, get_fit_mcrdr, get_fit_scrdr, get_habitat
|
10
|
+
from pandas.core.frame import DataFrame
|
11
|
+
|
12
|
+
def conditions_for_animal_habitats_of_type_habitat(case: DataFrame) -> bool:
|
13
|
+
"""Get conditions on whether it's possible to conclude a value for Animal.habitats of type Habitat."""
|
14
|
+
# Write your code here
|
15
|
+
return case.species=='mammal' and case.aquatic==0
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
'===New Answer==='
|
20
|
+
|
21
|
+
|
22
|
+
from typing_extensions import Any, Callable, List, Optional, Tuple, Type
|
23
|
+
from test.datasets import Habitat, Species, load_zoo_cases
|
24
|
+
from ripple_down_rules.datastructures.case import Case
|
25
|
+
from ripple_down_rules.datastructures.dataclasses import CaseQuery
|
26
|
+
from ripple_down_rules.datastructures.enums import Category
|
27
|
+
from ripple_down_rules.experts import Human
|
28
|
+
from ripple_down_rules.rdr import GeneralRDR, MultiClassRDR, SingleClassRDR
|
29
|
+
from ripple_down_rules.utils import make_set
|
30
|
+
from test.test_helpers.helpers import get_fit_grdr, get_fit_mcrdr, get_fit_scrdr, get_habitat
|
31
|
+
from pandas.core.frame import DataFrame
|
32
|
+
|
33
|
+
def conditions_for_animal_habitats_of_type_habitat(case: DataFrame) -> bool:
|
34
|
+
"""Get conditions on whether it's possible to conclude a value for Animal.habitats of type Habitat."""
|
35
|
+
# Write your code here
|
36
|
+
return case.species=='fish'
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
'===New Answer==='
|
41
|
+
|
42
|
+
|
43
|
+
from typing_extensions import Any, Callable, List, Optional, Tuple, Type
|
44
|
+
from test.datasets import Habitat, Species, load_zoo_cases
|
45
|
+
from ripple_down_rules.datastructures.case import Case
|
46
|
+
from ripple_down_rules.datastructures.dataclasses import CaseQuery
|
47
|
+
from ripple_down_rules.datastructures.enums import Category
|
48
|
+
from ripple_down_rules.experts import Human
|
49
|
+
from ripple_down_rules.rdr import GeneralRDR, MultiClassRDR, SingleClassRDR
|
50
|
+
from ripple_down_rules.utils import make_set
|
51
|
+
from test.test_helpers.helpers import get_fit_grdr, get_fit_mcrdr, get_fit_scrdr, get_habitat
|
52
|
+
from pandas.core.frame import DataFrame
|
53
|
+
|
54
|
+
def conditions_for_animal_habitats_of_type_habitat(case: DataFrame) -> bool:
|
55
|
+
"""Get conditions on whether it's possible to conclude a value for Animal.habitats of type Habitat."""
|
56
|
+
# Write your code here
|
57
|
+
return case.species=='bird' and case.legs>0
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
'===New Answer==='
|
62
|
+
|
63
|
+
|
64
|
+
from typing_extensions import Any, Callable, List, Optional, Tuple, Type
|
65
|
+
from test.datasets import Habitat, Species, load_zoo_cases
|
66
|
+
from ripple_down_rules.datastructures.case import Case
|
67
|
+
from ripple_down_rules.datastructures.dataclasses import CaseQuery
|
68
|
+
from ripple_down_rules.datastructures.enums import Category
|
69
|
+
from ripple_down_rules.experts import Human
|
70
|
+
from ripple_down_rules.rdr import GeneralRDR, MultiClassRDR, SingleClassRDR
|
71
|
+
from ripple_down_rules.utils import make_set
|
72
|
+
from test.test_helpers.helpers import get_fit_grdr, get_fit_mcrdr, get_fit_scrdr, get_habitat
|
73
|
+
from pandas.core.frame import DataFrame
|
74
|
+
|
75
|
+
def conditions_for_animal_habitats_of_type_habitat(case: DataFrame) -> bool:
|
76
|
+
"""Get conditions on whether it's possible to conclude a value for Animal.habitats of type Habitat."""
|
77
|
+
# Write your code here
|
78
|
+
return case.species=='molusc' and case.aquatic==0
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
'===New Answer==='
|
83
|
+
|
84
|
+
|
85
|
+
from typing_extensions import Any, Callable, List, Optional, Tuple, Type
|
86
|
+
from test.datasets import Habitat, Species, load_zoo_cases
|
87
|
+
from ripple_down_rules.datastructures.case import Case
|
88
|
+
from ripple_down_rules.datastructures.dataclasses import CaseQuery
|
89
|
+
from ripple_down_rules.datastructures.enums import Category
|
90
|
+
from ripple_down_rules.experts import Human
|
91
|
+
from ripple_down_rules.rdr import GeneralRDR, MultiClassRDR, SingleClassRDR
|
92
|
+
from ripple_down_rules.utils import make_set
|
93
|
+
from test.test_helpers.helpers import get_fit_grdr, get_fit_mcrdr, get_fit_scrdr, get_habitat
|
94
|
+
from pandas.core.frame import DataFrame
|
95
|
+
|
96
|
+
def conditions_for_animal_habitats_of_type_habitat(case: DataFrame) -> bool:
|
97
|
+
"""Get conditions on whether it's possible to conclude a value for Animal.habitats of type Habitat."""
|
98
|
+
# Write your code here
|
99
|
+
return case.species=='molusc' and case.aquatic==1
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
'===New Answer==='
|
104
|
+
|
105
|
+
|