├── .coveragerc
├── .flake8
├── .github
└── workflows
│ ├── tests.yml
│ └── wheels.yml
├── .gitignore
├── .readthedocs.yaml
├── INSTALL.md
├── MANUAL_INSTALL.md
├── README.md
├── _layouts
└── default.html
├── developer_tools
├── deep_get_referrers.py
├── list_quibbler_methods.py
├── notes
│ ├── thoughts_on_divergence_1.ipynb
│ ├── thoughts_on_divergence_2.ipynb
│ └── thoughts_on_divergence_3.ipynb
└── old_code
│ ├── rounding.py
│ └── unoverride_all.py
├── google56763903e901c5f9.html
├── install.py
├── license
├── pyquibbler-documentations
├── Makefile
├── README.md
├── convert_doc_notebooks_to_rst.py
├── docs
│ ├── Diverged-evaluation.rst
│ ├── Examples.rst
│ ├── Graphics.rst
│ ├── Installation.rst
│ ├── Introduction.rst
│ ├── Inverse-assignments.rst
│ ├── Jupyter-lab-ext.rst
│ ├── List-of-quiby-functions.rst
│ ├── List_of_functions.rst
│ ├── Overriding-default-functionality.rst
│ ├── Project-save-load.rst
│ ├── Quib-naming.rst
│ ├── Quib-relationships.rst
│ ├── Quibbler_Enums.rst
│ ├── Quibbler_display_classes.rst
│ ├── Quiby-ipywidgets.rst
│ ├── Quickstart.rst
│ ├── Random-functions.rst
│ ├── Rationale.md
│ ├── User-defined-functions.rst
│ ├── What-is-it.md
│ ├── _static
│ │ └── custom.css
│ ├── _templates
│ │ ├── custom-class-template.rst
│ │ └── custom-module-template.rst
│ ├── classes
│ │ ├── pyquibbler.AssignmentTemplate.rst
│ │ ├── pyquibbler.CacheMode.rst
│ │ ├── pyquibbler.CacheStatus.rst
│ │ ├── pyquibbler.GraphicsUpdateType.rst
│ │ ├── pyquibbler.QuibPropertiesViewer.rst
│ │ ├── pyquibbler.SaveFormat.rst
│ │ ├── pyquibbler.ipywidget_viewer.QuibWidget.rst
│ │ └── pyquibbler.quib_network.Direction.rst
│ ├── conceptual_view.gif
│ ├── conf.py
│ ├── examples
│ │ ├── quibdemo_COVID_analysis.rst
│ │ ├── quibdemo_CheckButtons.rst
│ │ ├── quibdemo_LotkaVolterra.rst
│ │ ├── quibdemo_Mandelbrot.rst
│ │ ├── quibdemo_compare_images.rst
│ │ ├── quibdemo_default_overriding.rst
│ │ ├── quibdemo_default_overriding_two_levels.rst
│ │ ├── quibdemo_drag_fixed_values.rst
│ │ ├── quibdemo_drag_multiple_points.rst
│ │ ├── quibdemo_drag_on_curve.rst
│ │ ├── quibdemo_drag_segments.rst
│ │ ├── quibdemo_drag_vertical_horizontal.rst
│ │ ├── quibdemo_drag_whole_object_vs_individual_points.rst
│ │ ├── quibdemo_drag_xy.rst
│ │ ├── quibdemo_dragging_fixed_object.rst
│ │ ├── quibdemo_fft.rst
│ │ ├── quibdemo_fit_stocks.rst
│ │ ├── quibdemo_gear.rst
│ │ ├── quibdemo_image_ROI.rst
│ │ ├── quibdemo_image_probing.rst
│ │ ├── quibdemo_image_thresholding.rst
│ │ ├── quibdemo_ipywidgets_quadratic_eq.rst
│ │ ├── quibdemo_making_the_quib_icon.rst
│ │ ├── quibdemo_percolation.rst
│ │ ├── quibdemo_periodic_functions.rst
│ │ ├── quibdemo_pythagoras.rst
│ │ ├── quibdemo_quiby_axes.rst
│ │ ├── quibdemo_random_quibs_dice.rst
│ │ ├── quibdemo_repressilator.rst
│ │ ├── quibdemo_rushhour.rst
│ │ ├── quibdemo_same_data_in_many_forms.rst
│ │ └── quibdemo_slider.rst
│ ├── functions
│ │ ├── pyquibbler.can_redo.rst
│ │ ├── pyquibbler.can_undo.rst
│ │ ├── pyquibbler.default.rst
│ │ ├── pyquibbler.get_project.rst
│ │ ├── pyquibbler.get_project_directory.rst
│ │ ├── pyquibbler.initialize_quibbler.rst
│ │ ├── pyquibbler.iquib.rst
│ │ ├── pyquibbler.is_quiby.rst
│ │ ├── pyquibbler.list_quiby_funcs.rst
│ │ ├── pyquibbler.load_quibs.rst
│ │ ├── pyquibbler.obj2quib.rst
│ │ ├── pyquibbler.q.rst
│ │ ├── pyquibbler.quib_network.dependency_graph.rst
│ │ ├── pyquibbler.quibapp.rst
│ │ ├── pyquibbler.quiby.rst
│ │ ├── pyquibbler.redo.rst
│ │ ├── pyquibbler.refresh_graphics.rst
│ │ ├── pyquibbler.reset_file_loading_quibs.rst
│ │ ├── pyquibbler.reset_impure_quibs.rst
│ │ ├── pyquibbler.reset_random_quibs.rst
│ │ ├── pyquibbler.save_quibs.rst
│ │ ├── pyquibbler.set_project_directory.rst
│ │ ├── pyquibbler.sync_quibs.rst
│ │ └── pyquibbler.undo.rst
│ ├── images
│ │ ├── Quickstart_assign_d_and_drag.gif
│ │ ├── Quickstart_assign_xy_and_drag.gif
│ │ ├── Quickstart_interactive_image_cut.gif
│ │ ├── Quickstart_load_image.gif
│ │ ├── Quickstart_widget_box_size.gif
│ │ ├── User_defined_functions_pass_quibs.gif
│ │ ├── assignments_assignment_template.gif
│ │ ├── assignments_jupyter_undo_redo.gif
│ │ ├── conceptual_view.gif
│ │ ├── conceptual_view.png
│ │ ├── demo_gif
│ │ │ ├── quibdemo_COVID_analysis.gif
│ │ │ ├── quibdemo_CheckButtons.gif
│ │ │ ├── quibdemo_LotkaVolterra.gif
│ │ │ ├── quibdemo_Mandelbrot.gif
│ │ │ ├── quibdemo_compare_images.gif
│ │ │ ├── quibdemo_default_overriding.gif
│ │ │ ├── quibdemo_default_overriding_two_levels.gif
│ │ │ ├── quibdemo_drag_fixed_values.gif
│ │ │ ├── quibdemo_drag_multiple_points.gif
│ │ │ ├── quibdemo_drag_on_curve.gif
│ │ │ ├── quibdemo_drag_vertical_horizontal.gif
│ │ │ ├── quibdemo_drag_whole_object_vs_individual_points.gif
│ │ │ ├── quibdemo_drag_xy.gif
│ │ │ ├── quibdemo_dragging_fixed_object.gif
│ │ │ ├── quibdemo_fft.gif
│ │ │ ├── quibdemo_fit_stocks.gif
│ │ │ ├── quibdemo_gear.gif
│ │ │ ├── quibdemo_image_ROI.gif
│ │ │ ├── quibdemo_image_probing.gif
│ │ │ ├── quibdemo_image_thresholding.gif
│ │ │ ├── quibdemo_ipywidgets_quadratic_eq.gif
│ │ │ ├── quibdemo_making_the_quib_icon.gif
│ │ │ ├── quibdemo_percolation.gif
│ │ │ ├── quibdemo_periodic_functions.gif
│ │ │ ├── quibdemo_pythagoras.gif
│ │ │ ├── quibdemo_quiby_axes.gif
│ │ │ ├── quibdemo_random_quibs_dice.gif
│ │ │ ├── quibdemo_repressilator.gif
│ │ │ ├── quibdemo_rushhour.gif
│ │ │ ├── quibdemo_same_data_in_many_forms.gif
│ │ │ └── quibdemo_slider.gif
│ │ ├── dependency_graph_1.png
│ │ ├── dialog_box_per_item_factor.png
│ │ ├── divergence_gif
│ │ │ ├── Divergence_arrows.gif
│ │ │ └── Divergence_passquibs.gif
│ │ ├── graphics_gif
│ │ │ ├── graphics_rgb_probing_of_image.gif
│ │ │ ├── graphics_slider_for_box_size.gif
│ │ │ ├── graphics_xy_axis_labels.gif
│ │ │ ├── graphics_xy_drag.gif
│ │ │ ├── graphics_xy_drag_horz_vert.gif
│ │ │ └── graphics_xy_refresh.gif
│ │ ├── graphics_inverse.gif
│ │ ├── graphics_refresh.gif
│ │ ├── inverse_assignment_age_dob.gif
│ │ ├── inverse_assignment_choice.png
│ │ ├── inverse_assignment_illustrate.gif
│ │ ├── labext_open.png
│ │ ├── labext_quibbler_menu.png
│ │ ├── labext_undo_redo.gif
│ │ ├── minimal_app_3.gif
│ │ ├── network_tracing.png
│ │ ├── overriding_default_by_dragging.gif
│ │ ├── overriding_set_back_to_default.gif
│ │ ├── quib_editor_save_load.gif
│ │ ├── quib_editor_thresholds_rgb.gif
│ │ ├── quib_transparent.png
│ │ ├── quibicon.gif
│ │ ├── quiby_ipywidgets_gif
│ │ │ ├── quiby-ipywidgets-bidirectional.gif
│ │ │ ├── quiby-ipywidgets-bob-alice.gif
│ │ │ ├── quiby-ipywidgets-linked-widgets-quiby.gif
│ │ │ ├── quiby-ipywidgets-linked-widgets.gif
│ │ │ ├── quiby-ipywidgets-lorenz.gif
│ │ │ └── quiby-ipywidgets-min-max.gif
│ │ ├── tile_7_5_inverse.gif
│ │ └── tile_7_5_override.gif
│ ├── index.rst
│ ├── major_classes
│ │ ├── Project_class.rst
│ │ └── Quib_class.rst
│ ├── requirements.txt
│ └── zips_for_download
│ │ └── examples.zip
├── docs_notebooks
│ ├── Diverged-evaluation.ipynb
│ ├── Graphics.ipynb
│ ├── Introduction.ipynb
│ ├── Inverse-assignments.ipynb
│ ├── Jupyter-lab-ext.ipynb
│ ├── List-of-quiby-functions.ipynb
│ ├── Overriding-default-functionality.ipynb
│ ├── Project-save-load.ipynb
│ ├── Quib-naming.ipynb
│ ├── Quib-relationships.ipynb
│ ├── Quiby-ipywidgets.ipynb
│ ├── Quickstart.ipynb
│ ├── Random-functions.ipynb
│ ├── User-defined-functions.ipynb
│ ├── bacteria_drop.tif
│ ├── bacteria_in_a_droplet.tif
│ ├── bacteria_in_droplets.tif
│ └── notebook_for_videos
│ │ └── Quiby-ipywidgets-videos.ipynb
├── examples
│ ├── AAPL.csv
│ ├── README.md
│ ├── bacteria_drop.tif
│ ├── bacteria_in_droplets.tif
│ ├── covid_fatality.csv
│ ├── pipes.jpg
│ ├── quibdemo_COVID_analysis.ipynb
│ ├── quibdemo_CheckButtons.ipynb
│ ├── quibdemo_LotkaVolterra.ipynb
│ ├── quibdemo_Mandelbrot.ipynb
│ ├── quibdemo_compare_images.ipynb
│ ├── quibdemo_default_overriding.ipynb
│ ├── quibdemo_default_overriding_two_levels.ipynb
│ ├── quibdemo_drag_fixed_values.ipynb
│ ├── quibdemo_drag_multiple_points.ipynb
│ ├── quibdemo_drag_on_curve.ipynb
│ ├── quibdemo_drag_segments.ipynb
│ ├── quibdemo_drag_vertical_horizontal.ipynb
│ ├── quibdemo_drag_whole_object_vs_individual_points.ipynb
│ ├── quibdemo_drag_xy.ipynb
│ ├── quibdemo_dragging_fixed_object.ipynb
│ ├── quibdemo_fft.ipynb
│ ├── quibdemo_fit_stocks.ipynb
│ ├── quibdemo_gear.ipynb
│ ├── quibdemo_image_ROI.ipynb
│ ├── quibdemo_image_probing.ipynb
│ ├── quibdemo_image_thresholding.ipynb
│ ├── quibdemo_ipywidgets_quadratic_eq.ipynb
│ ├── quibdemo_making_the_quib_icon.ipynb
│ ├── quibdemo_percolation.ipynb
│ ├── quibdemo_periodic_functions.ipynb
│ ├── quibdemo_pythagoras.ipynb
│ ├── quibdemo_quiby_axes.ipynb
│ ├── quibdemo_random_quibs_dice.ipynb
│ ├── quibdemo_repressilator.ipynb
│ ├── quibdemo_rushhour.ipynb
│ ├── quibdemo_same_data_in_many_forms.ipynb
│ └── quibdemo_slider.ipynb
├── make.bat
└── powerpoint_files
│ ├── images_lab_extension.pptx
│ ├── inverse.pptx
│ └── network_tracing.pptx
├── pyquibbler-labextension
├── .github_temp
│ └── workflows
│ │ ├── binder-on-pr.yml
│ │ ├── build.yml
│ │ └── check-release.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .stylelintrc
├── CHANGELOG.md
├── MANIFEST.in
├── README.md
├── RELEASE.md
├── binder
│ ├── environment.yml
│ └── postBuild
├── images
│ └── close.svg
├── install.json
├── package-lock.json
├── package.json
├── pyproject.toml
├── pyquibbler_labextension
│ ├── __init__.py
│ └── _version.py
├── schema
│ └── settings.json
├── setup.py
├── src
│ ├── custom.d.ts
│ ├── globalConfig.ts
│ ├── index.ts
│ ├── requester.ts
│ ├── session.ts
│ ├── toolbarButtonExtension.ts
│ └── utils.ts
├── style
│ ├── base.css
│ ├── index.css
│ └── index.js
└── tsconfig.json
├── pyquibbler
├── README.md
├── internal_docs
│ └── nomenclature.md
├── pyproject.toml
├── pyquibbler
│ ├── __init__.py
│ ├── assignment
│ │ ├── __init__.py
│ │ ├── assignment.py
│ │ ├── assignment_template.py
│ │ ├── assignment_to_from_text.py
│ │ ├── default_value.py
│ │ ├── exceptions.py
│ │ ├── override_choice
│ │ │ ├── __init__.py
│ │ │ ├── choice_context.py
│ │ │ ├── exceptions.py
│ │ │ ├── override_choice.py
│ │ │ ├── override_dialog.py
│ │ │ └── types.py
│ │ ├── overrider.py
│ │ ├── rounding.py
│ │ ├── simplify_assignment.py
│ │ └── utils.py
│ ├── cache
│ │ ├── __init__.py
│ │ ├── cache.py
│ │ ├── cache_utils.py
│ │ ├── holistic_cache.py
│ │ └── shallow
│ │ │ ├── __init__.py
│ │ │ ├── dict_cache.py
│ │ │ ├── indexable_cache.py
│ │ │ ├── nd_cache
│ │ │ ├── __init__.py
│ │ │ ├── nd_field_array_cache.py
│ │ │ ├── nd_indexable_cache.py
│ │ │ ├── nd_unstructured_array_cache.py
│ │ │ └── nd_void_cache.py
│ │ │ └── shallow_cache.py
│ ├── debug_utils
│ │ ├── __init__.py
│ │ ├── logger.py
│ │ ├── timer.py
│ │ └── track_instances.py
│ ├── env.py
│ ├── exceptions.py
│ ├── file_syncing
│ │ ├── __init__.py
│ │ ├── file_syncer.py
│ │ ├── quib_file_syncer.py
│ │ └── types.py
│ ├── function_definitions
│ │ ├── __init__.py
│ │ ├── definitions.py
│ │ ├── func_call.py
│ │ ├── func_definition.py
│ │ ├── location.py
│ │ ├── types.py
│ │ └── utils.py
│ ├── function_overriding
│ │ ├── __init__.py
│ │ ├── attribute_override.py
│ │ ├── defintion_without_override
│ │ │ ├── __init__.py
│ │ │ └── python_functions.py
│ │ ├── exceptionhook.py
│ │ ├── function_override.py
│ │ ├── is_initiated.py
│ │ ├── override_all.py
│ │ ├── quib_overrides
│ │ │ ├── __init__.py
│ │ │ ├── operators
│ │ │ │ ├── __init__.py
│ │ │ │ ├── func_definitions.py
│ │ │ │ ├── helpers.py
│ │ │ │ └── overrides.py
│ │ │ └── quib_methods.py
│ │ └── third_party_overriding
│ │ │ ├── __init__.py
│ │ │ ├── general_helpers.py
│ │ │ ├── ipywidgets
│ │ │ ├── __init__.py
│ │ │ ├── denounce_timer.py
│ │ │ ├── overrides.py
│ │ │ └── quiby_widget_trait.py
│ │ │ ├── matplotlib
│ │ │ ├── __init__.py
│ │ │ ├── func_definitions.py
│ │ │ ├── helpers.py
│ │ │ └── overrides.py
│ │ │ ├── non_quib_overrides
│ │ │ ├── __init__.py
│ │ │ ├── axes_overrides.py
│ │ │ └── widgets_override.py
│ │ │ └── numpy
│ │ │ ├── __init__.py
│ │ │ ├── func_definitions.py
│ │ │ ├── helpers.py
│ │ │ ├── inverse_functions.py
│ │ │ ├── overrides.py
│ │ │ ├── quiby_attributes.py
│ │ │ └── vectorize_overrides.py
│ ├── graphics
│ │ ├── __init__.py
│ │ ├── global_collecting.py
│ │ ├── graphics_collection.py
│ │ ├── process_plot_var_args.py
│ │ ├── update_new_artists.py
│ │ ├── utils.py
│ │ ├── widget_utils.py
│ │ └── widgets
│ │ │ ├── __init__.py
│ │ │ ├── base_q_widget.py
│ │ │ ├── q_radio_buttons.py
│ │ │ ├── q_rectangle_selector.py
│ │ │ ├── q_slider.py
│ │ │ ├── q_text_box.py
│ │ │ └── utils.py
│ ├── inversion
│ │ ├── __init__.py
│ │ ├── invert.py
│ │ ├── inverter.py
│ │ └── inverters
│ │ │ ├── __init__.py
│ │ │ ├── casting.py
│ │ │ ├── elementwise.py
│ │ │ ├── elementwise_single_arg_no_shape.py
│ │ │ ├── getitem.py
│ │ │ ├── list_operators.py
│ │ │ ├── numpy.py
│ │ │ ├── obj2quib.py
│ │ │ └── transpositional.py
│ ├── ipywidget_viewer
│ │ ├── __init__.py
│ │ └── quib_widget.py
│ ├── optional_packages
│ │ ├── __init__.py
│ │ ├── emulate_missing_packages.py
│ │ ├── exceptions.py
│ │ ├── get_IPython.py
│ │ ├── get_ipycytoscape.py
│ │ └── get_ipywidgets.py
│ ├── path
│ │ ├── __init__.py
│ │ ├── data_accessing.py
│ │ ├── hashable.py
│ │ ├── path_component.py
│ │ └── utils.py
│ ├── path_translation
│ │ ├── __init__.py
│ │ ├── array_index_codes.py
│ │ ├── array_translation_utils.py
│ │ ├── base_translators.py
│ │ ├── create_source_func_call.py
│ │ ├── exceptions.py
│ │ ├── source_func_call.py
│ │ ├── translate.py
│ │ ├── translators
│ │ │ ├── __init__.py
│ │ │ ├── apply_along_axis.py
│ │ │ ├── axis_accumulation.py
│ │ │ ├── axis_all_to_all.py
│ │ │ ├── axis_reduction.py
│ │ │ ├── elementwise.py
│ │ │ ├── getitem.py
│ │ │ ├── list_operators.py
│ │ │ ├── numpy.py
│ │ │ ├── obj2quib.py
│ │ │ ├── quiby_name.py
│ │ │ ├── shape_only.py
│ │ │ ├── transpositional.py
│ │ │ └── vectorize.py
│ │ ├── types.py
│ │ └── utils.py
│ ├── project
│ │ ├── __init__.py
│ │ ├── actions.py
│ │ ├── exceptions.py
│ │ ├── jupyer_project
│ │ │ ├── __init__.py
│ │ │ ├── archive_folder.py
│ │ │ ├── flask_dialog_server.py
│ │ │ ├── jupyter_project.py
│ │ │ └── utils.py
│ │ ├── project.py
│ │ └── undo_group.py
│ ├── quib
│ │ ├── __init__.py
│ │ ├── consts.py
│ │ ├── exceptions.py
│ │ ├── external_call_failed_exception_handling.py
│ │ ├── factory.py
│ │ ├── func_calling
│ │ │ ├── __init__.py
│ │ │ ├── cache_mode.py
│ │ │ ├── cached_quib_func_call.py
│ │ │ ├── func_calls
│ │ │ │ ├── __init__.py
│ │ │ │ ├── apply_along_axis_call.py
│ │ │ │ ├── known_graphics
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── plot_call.py
│ │ │ │ │ └── widgets
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── checkbuttons_call.py
│ │ │ │ │ │ ├── radio_buttons_call.py
│ │ │ │ │ │ ├── rectangle_selector_call.py
│ │ │ │ │ │ ├── slider_call.py
│ │ │ │ │ │ ├── textbox_call.py
│ │ │ │ │ │ └── widget_call.py
│ │ │ │ └── vectorize
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ ├── vectorize_call.py
│ │ │ │ │ └── vectorize_metadata.py
│ │ │ ├── iquib_call.py
│ │ │ ├── quib_func_call.py
│ │ │ ├── quiby_name_func_call.py
│ │ │ └── utils.py
│ │ ├── get_value_context_manager.py
│ │ ├── graphics
│ │ │ ├── __init__.py
│ │ │ ├── artist_wrapper.py
│ │ │ ├── event_handling
│ │ │ │ ├── __init__.py
│ │ │ │ ├── affected_args_and_paths.py
│ │ │ │ ├── canvas_event_handler.py
│ │ │ │ ├── enhance_pick_event.py
│ │ │ │ ├── graphics_inverse_assigner.py
│ │ │ │ ├── graphics_inverse_assigners.py
│ │ │ │ ├── graphics_inverse_assignment.py
│ │ │ │ ├── plt_plot_parser.py
│ │ │ │ ├── set_lim_inverse_assigner.py
│ │ │ │ ├── solvers.py
│ │ │ │ └── utils.py
│ │ │ ├── graphics_assignment_mode.py
│ │ │ ├── graphics_update.py
│ │ │ ├── persist.py
│ │ │ └── redraw.py
│ │ ├── pretty_converters
│ │ │ ├── __init__.py
│ │ │ ├── math_expressions
│ │ │ │ ├── __init__.py
│ │ │ │ ├── call_method_expression.py
│ │ │ │ ├── func_call_expression.py
│ │ │ │ ├── getattr_expression.py
│ │ │ │ ├── getitem_expression.py
│ │ │ │ ├── math_expression.py
│ │ │ │ ├── operators_expressions.py
│ │ │ │ └── simple_expressions.py
│ │ │ ├── math_precedence.py
│ │ │ ├── operators.py
│ │ │ └── pretty_convert.py
│ │ ├── quib.py
│ │ ├── quib_guard.py
│ │ ├── quib_properties_viewer.py
│ │ ├── specialized_functions
│ │ │ ├── __init__.py
│ │ │ ├── getattr.py
│ │ │ ├── iquib.py
│ │ │ ├── proxy.py
│ │ │ └── quiby_methods.py
│ │ ├── types.py
│ │ ├── utils
│ │ │ ├── __init__.py
│ │ │ ├── iterators.py
│ │ │ └── miscellaneous.py
│ │ └── variable_metadata.py
│ ├── quib_network
│ │ ├── __init__.py
│ │ ├── network_properties.py
│ │ ├── quib_network.py
│ │ └── types.py
│ ├── reset_all.py
│ ├── type_translation
│ │ ├── __init__.py
│ │ ├── run_conditions.py
│ │ ├── translate.py
│ │ ├── translators.py
│ │ └── utils.py
│ ├── user_utils
│ │ ├── __init__.py
│ │ ├── gui_apps.py
│ │ ├── obj2quib.py
│ │ ├── project_wraps.py
│ │ ├── quibapp.py
│ │ └── quiby_funcs.py
│ └── utilities
│ │ ├── __init__.py
│ │ ├── basic_types.py
│ │ ├── decorators.py
│ │ ├── file_path.py
│ │ ├── general_utils.py
│ │ ├── get_original_func.py
│ │ ├── input_validation_utils.py
│ │ ├── iterators.py
│ │ ├── missing_value.py
│ │ ├── multiple_instance_runner.py
│ │ ├── numpy_original_functions.py
│ │ ├── operators_with_reverse.py
│ │ ├── unpacker.py
│ │ └── warning_messages.py
└── setup.py
├── tests
├── __init__.py
├── conftest.py
├── functional
│ ├── __init__.py
│ ├── assignment
│ │ ├── __init__.py
│ │ ├── overriding_choice
│ │ │ ├── __init__.py
│ │ │ ├── test_override_choice.py
│ │ │ └── test_override_dialog.py
│ │ ├── test_assignment_simplifier.py
│ │ ├── test_assignment_template.py
│ │ ├── test_assignment_to_from_text.py
│ │ └── test_overrider.py
│ ├── cache
│ │ ├── __init__.py
│ │ ├── cache_test.py
│ │ ├── test_dict_cache.py
│ │ ├── test_indexable_cache.py
│ │ ├── test_nd_field_array_cache.py
│ │ ├── test_nd_unstructured_array_cache.py
│ │ ├── test_nd_void_cache.py
│ │ └── test_shallow_cache.py
│ ├── conftest.py
│ ├── file_syncing
│ │ ├── __init__.py
│ │ └── test_file_syncer.py
│ ├── graphics
│ │ ├── __init__.py
│ │ └── test_global_collecting.py
│ ├── inversion
│ │ ├── __init__.py
│ │ ├── inverters
│ │ │ ├── __init__.py
│ │ │ ├── test_elementwise_inverter.py
│ │ │ ├── test_getitem_inverter.py
│ │ │ ├── test_no_shape_elementwise_inverter.py
│ │ │ ├── test_transpositional_inverter.py
│ │ │ └── utils.py
│ │ └── test_invert.py
│ ├── path
│ │ ├── __init__.py
│ │ ├── test_hashable.py
│ │ └── test_utils.py
│ ├── quib
│ │ ├── __init__.py
│ │ ├── assignment
│ │ │ ├── __init__.py
│ │ │ └── test_assignments.py
│ │ ├── conftest.py
│ │ ├── graphics
│ │ │ ├── __init__.py
│ │ │ ├── event_handling
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_canvas_event_handler.py
│ │ │ │ ├── test_plot_inverse_assigner.py
│ │ │ │ └── test_set_lim_inverse_assigner.py
│ │ │ ├── test_redraw.py
│ │ │ └── test_solvers.py
│ │ ├── quib_widget
│ │ │ ├── __init__.py
│ │ │ └── test_quib_widget.py
│ │ ├── test_iquib.py
│ │ ├── test_quib
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── get_value
│ │ │ │ ├── __init__.py
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_accumulation.py
│ │ │ │ ├── test_apply_along_axis.py
│ │ │ │ ├── test_axiswise.py
│ │ │ │ ├── test_elementwise.py
│ │ │ │ ├── test_general.py
│ │ │ │ ├── test_iquib.py
│ │ │ │ ├── test_list_operatos.py
│ │ │ │ ├── test_minor_sources.py
│ │ │ │ ├── test_proxy.py
│ │ │ │ ├── test_reduction.py
│ │ │ │ ├── test_transpositional.py
│ │ │ │ ├── test_vectorize_call.py
│ │ │ │ ├── test_vectorize_metadata.py
│ │ │ │ └── utils.py
│ │ │ ├── invalidation
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_accumulation.py
│ │ │ │ ├── test_apply_along_axis.py
│ │ │ │ ├── test_axiswise.py
│ │ │ │ ├── test_elementwise.py
│ │ │ │ ├── test_general.py
│ │ │ │ ├── test_list_operators.py
│ │ │ │ ├── test_proxy.py
│ │ │ │ ├── test_reduction.py
│ │ │ │ ├── test_shape_only_data_arg.py
│ │ │ │ ├── test_transpositional.py
│ │ │ │ ├── test_vectorize_call.py
│ │ │ │ └── utils.py
│ │ │ ├── pretty_repr
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_general.py
│ │ │ │ ├── test_operators.py
│ │ │ │ ├── test_overrider.py
│ │ │ │ └── test_vectorize.py
│ │ │ ├── test_array_operator_quib.py
│ │ │ ├── test_assign_default.py
│ │ │ ├── test_cache_behavior.py
│ │ │ ├── test_display_props.py
│ │ │ ├── test_exception_causing_assignments.py
│ │ │ ├── test_exception_handling.py
│ │ │ ├── test_file_management.py
│ │ │ ├── test_functions_returning_array_view.py
│ │ │ ├── test_general.py
│ │ │ ├── test_get_shape_and_type.py
│ │ │ ├── test_getattr.py
│ │ │ ├── test_graphics.py
│ │ │ ├── test_invalidate_and_redraw.py
│ │ │ ├── test_inversal.py
│ │ │ ├── test_list_operator_inveral.py
│ │ │ ├── test_naming.py
│ │ │ ├── test_operators.py
│ │ │ ├── test_overriding.py
│ │ │ ├── test_quib_callback.py
│ │ │ ├── test_quib_creation.py
│ │ │ ├── test_quib_persistence.py
│ │ │ ├── test_quib_relationships.py
│ │ │ ├── test_quiby_methods.py
│ │ │ ├── test_quiby_name.py
│ │ │ └── test_set_get_quib_properties.py
│ │ ├── test_quib_guard.py
│ │ └── test_uninitiated.py
│ ├── quib_network
│ │ ├── __init__.py
│ │ ├── test_quib_network.py
│ │ └── test_quib_network_without_ipywidgets.py
│ ├── test_iterators.py
│ ├── test_performance_utils.py
│ ├── test_project.py
│ ├── test_project_wraps.py
│ ├── test_quibapp.py
│ ├── test_quibbler_user_function.py
│ ├── test_utilities.py
│ ├── test_utils.py
│ ├── third_party_overriding
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── test_graphics_definition.py
│ │ ├── test_not_implemented.py
│ │ ├── test_numpy_special.py
│ │ ├── test_overriding_definition.py
│ │ ├── test_overriding_ipywidgets.py
│ │ ├── test_patches.py
│ │ └── test_q_rectangle_selector.py
│ └── utils.py
├── integration
│ ├── __init__.py
│ ├── benchmarks
│ │ ├── __init__.py
│ │ └── test_benchmarks.py
│ ├── demos
│ │ ├── __init__.py
│ │ ├── baseline_images
│ │ │ ├── test_covid_demo
│ │ │ │ └── covid_demo.png
│ │ │ └── test_gear_demo
│ │ │ │ └── gear_demo.png
│ │ ├── covid_fatality.csv
│ │ ├── test_covid_demo.py
│ │ └── test_gear_demo.py
│ └── quib
│ │ ├── __init__.py
│ │ └── graphics
│ │ ├── __init__.py
│ │ ├── test_general.py
│ │ ├── test_graphics_assignment.py
│ │ ├── test_graphics_assignment_x_y_conflict.py
│ │ └── widgets
│ │ ├── __init__.py
│ │ ├── baseline_images
│ │ ├── test_checkbuttons
│ │ │ ├── multiple_sets.png
│ │ │ └── unset.png
│ │ ├── test_radio_buttons
│ │ │ └── set_active_multiple_times.png
│ │ ├── test_rectangle_selector
│ │ │ ├── move.png
│ │ │ └── move_list.png
│ │ └── test_slider
│ │ │ ├── keeps_same_widget.png
│ │ │ ├── multiple_times.png
│ │ │ └── press_and_release_changes.png
│ │ ├── conftest.py
│ │ ├── test_checkbuttons.py
│ │ ├── test_normal_slider.py
│ │ ├── test_radio_buttons.py
│ │ ├── test_range_slider.py
│ │ ├── test_rectangle_selector.py
│ │ ├── test_slider.py
│ │ ├── test_textbox.py
│ │ └── utils.py
└── lab_extension
│ ├── README.md
│ ├── __init__.py
│ ├── notebooks
│ ├── example_notebook.ipynb
│ ├── notebook_with_error.ipynb
│ └── test_saving.ipynb
│ └── test_labextension.py
└── tox.ini
/.coveragerc:
--------------------------------------------------------------------------------
1 | [report]
2 | exclude_lines =
3 | pragma: no cover
4 | if TYPE_CHECKING:
5 | raise AssertionError
6 | raise NotImplementedError
7 | omit =
8 | pyquibbler/user_utils.py
9 |
10 | [run]
11 | concurrency = multiprocessing, thread
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | max-line-length = 120
3 |
4 | per-file-ignores =
5 | __init__.py:F401
6 | function_overriding/third_party_overriding/numpy/overrides.py:E241
7 | function_overriding/operators/overrides.py:E241
8 |
9 | ignore = E731,W503,E126,E121,W504
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yaml
2 | # Read the Docs configuration file
3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4 |
5 | # Required
6 | version: 2
7 |
8 | build:
9 | os: "ubuntu-20.04"
10 | tools:
11 | python: "3.10"
12 |
13 | sphinx:
14 | configuration: pyquibbler-documentations/docs/conf.py
15 |
16 | python:
17 | # Install our python package before building the docs
18 | install:
19 | - method: pip
20 | path: ./pyquibbler
21 | extra_requirements:
22 | - sphinx
23 |
--------------------------------------------------------------------------------
/MANUAL_INSTALL.md:
--------------------------------------------------------------------------------
1 | ## Manual install for development.
2 |
3 | For users, we recommend installing using `pip install` (see [here](INSTALL.md)).
4 |
5 |
6 | For development, we recommend installing using the `install.py` script
7 | ([here](INSTALL.md)).
8 |
9 | If `install.py` fails, or you otherwise prefer to install manually, follow these steps:
10 |
11 | #### 1. Create environment:
12 |
13 | ```conda create -n pyquibbler --override-channels --strict-channel-priority -c conda-forge -c nodefaults jupyterlab=3 cookiecutter nodejs jupyter-packaging git```
14 |
15 | ```conda activate pyquibbler```
16 |
17 | #### 2. Install pyquibbler-labextension:
18 | In the quibbler root directory:
19 |
20 | ```cd pyquibbler-labextension```
21 |
22 | ```pip install -e .```
23 |
24 | ```jupyter labextension develop . --overwrite```
25 |
26 | ```jlpm run build```
27 |
28 | ```jupyter lab build --minimize=False```
29 |
30 | If you are developing the client code, then to automatically build following changes, run:
31 |
32 | ```jlpm run watch```
33 |
34 |
35 | #### 3. Install pyquibbler:
36 |
37 | ```cd ../pyquibbler```
38 |
39 | ```pip install -e ".[dev, sphinx]"```
40 |
41 | #### 4. Install chromedriver (for lab tests)
42 |
43 | If you are developing the *pyquibbler jupyter-lab extension*, to be able to run
44 | the specific jupyterlab-extension tests, you will also need to install
45 | `chromedriver` (see [here](tests/lab_extension/README.md)).
46 |
--------------------------------------------------------------------------------
/developer_tools/deep_get_referrers.py:
--------------------------------------------------------------------------------
1 | import gc
2 |
3 |
4 | def deep_get_referrers(obj, depth: int, number_sequence=None):
5 | if obj is None:
6 | return
7 | if depth < 0:
8 | return
9 | number_sequence = number_sequence or []
10 | refs = gc.get_referrers(obj)
11 | for num, ref in enumerate(refs):
12 | current_number_sequence = [*number_sequence, num]
13 | print(f'SEQ={current_number_sequence}: TYPE={type(ref)}', ref, end='\n\n')
14 | deep_get_referrers(ref, depth-1, current_number_sequence)
15 |
--------------------------------------------------------------------------------
/developer_tools/list_quibbler_methods.py:
--------------------------------------------------------------------------------
1 | from pyquibbler import iquib, initialize_quibbler
2 | initialize_quibbler()
3 | import numpy as np
4 |
5 | quib = iquib(None)
6 |
7 | dir_quib = np.array(dir(quib))
8 |
9 | is_magic = np.vectorize(lambda x: x.startswith('__') and x.endswith('__'))(dir_quib)
10 | is_private = np.vectorize(lambda x: x.startswith('__') and not x.endswith('__'))(dir_quib)
11 | is_protected = np.vectorize(lambda x: x.startswith('_') and not x.startswith('__'))(dir_quib)
12 | is_public = ~(is_magic | is_private | is_protected)
13 |
14 | print('Public properties/methods:')
15 | for prop in dir_quib[is_public]:
16 | print(prop)
17 |
18 | print('Protected attributes/methods:')
19 | for prop in dir_quib[is_protected]:
20 | print(prop)
21 |
--------------------------------------------------------------------------------
/developer_tools/old_code/rounding.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | TYPE_TO_NUMBER_DIGITS = dict()
4 |
5 |
6 | def get_number_of_digits(value):
7 | type_ = type(value)
8 | if type_ not in TYPE_TO_NUMBER_DIGITS:
9 |
10 | eps = type_(1)
11 | while 1 + eps > 1:
12 | eps = type_(eps / 10)
13 | TYPE_TO_NUMBER_DIGITS[type_] = -np.log10(eps)
14 |
15 | return TYPE_TO_NUMBER_DIGITS[type_]
16 |
17 |
--------------------------------------------------------------------------------
/developer_tools/old_code/unoverride_all.py:
--------------------------------------------------------------------------------
1 | import importlib
2 |
3 |
4 | def deactivate_pyquibbler():
5 |
6 | import matplotlib
7 | importlib.reload(matplotlib)
8 |
9 | import numpy
10 | importlib.reload(numpy)
11 |
12 | from pyquibbler.quib import quib
13 | importlib.reload(quib)
14 |
15 | import ipywidgets
16 | from pyquibbler.function_overriding import override_all
17 | importlib.reload(ipywidgets)
18 | importlib.reload(override_all)
19 |
--------------------------------------------------------------------------------
/google56763903e901c5f9.html:
--------------------------------------------------------------------------------
1 | google-site-verification: google56763903e901c5f9.html
--------------------------------------------------------------------------------
/license:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Kishony lab, Technion - Israel Institute of Technology
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = docs
9 | BUILDDIR = build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/README.md:
--------------------------------------------------------------------------------
1 | ## Building pyquibbler documentations
2 |
3 | Documentations are written mostly as Jupyter lab notebooks,
4 | stored in `./examples` and `./docs_notebooks.`
5 |
6 | Run `convert_doc_notebooks_to_rst` to convert the notebooks
7 | into rst files which will be created in the `docs` and `docs/examples`.
8 |
9 | There are also `rst` and `md` files in the `docs` folder that are not generated
10 | from notebooks, and can instead be edited directly:
11 | `index.rst`, `Examples.rst`, `What-is-it.md`,
12 | `Rationale.md`, `Quibbler_Enums.rst`, `List_of_functions.rst`
13 | `Installation.rst`.
14 |
15 | The documentations are built by `readthedocs` with any push to master.
16 |
17 | To build the documentations into html locally, run at the project route directory:
18 | `make html`
19 |
20 | happy documenting!
21 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/Installation.rst:
--------------------------------------------------------------------------------
1 | Installing Quibbler
2 | -------------------
3 |
4 | To install *pyquibbler* run:
5 |
6 | ``pip install pyquibbler``
7 |
8 | If you have Jupyter lab installed, you can also add the
9 | *pyquibbler Jupyter Lab extensions*:
10 |
11 | ``pip install pyquibbler_labextension``
12 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/Quibbler_Enums.rst:
--------------------------------------------------------------------------------
1 | Quibbler special property classes
2 | =================================
3 | .. currentmodule:: pyquibbler
4 |
5 | .. autosummary::
6 | :toctree: classes
7 | :nosignatures:
8 |
9 | SaveFormat
10 | GraphicsUpdateType
11 | CacheMode
12 | CacheStatus
13 | AssignmentTemplate
14 |
15 |
16 | .. currentmodule:: pyquibbler.quib_network
17 |
18 | .. autosummary::
19 | :toctree: classes
20 | :nosignatures:
21 |
22 | Direction
23 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/Quibbler_display_classes.rst:
--------------------------------------------------------------------------------
1 | Quibbler display classes
2 | ========================
3 | .. currentmodule:: pyquibbler
4 |
5 | .. autosummary::
6 | :toctree: classes
7 | :nosignatures:
8 |
9 | QuibPropertiesViewer
10 |
11 |
12 | .. currentmodule:: pyquibbler.ipywidget_viewer
13 |
14 | .. autosummary::
15 | :toctree: classes
16 | :nosignatures:
17 |
18 | QuibWidget
19 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/_static/custom.css:
--------------------------------------------------------------------------------
1 | .highlight-none {
2 | color: #a0a0a0;
3 | background: none;
4 | border: none;
5 | }
6 |
7 | .highlight-python {
8 | color: #000000;
9 | background: #f8f8f8;
10 | }
11 |
12 | .highlight {
13 | background: none;
14 | }
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/_templates/custom-class-template.rst:
--------------------------------------------------------------------------------
1 | {{ fullname | escape | underline}}
2 |
3 | .. currentmodule:: {{ module }}
4 |
5 | .. autoclass:: {{ objname }}
6 | :members:
7 | :show-inheritance:
8 | :inherited-members:
9 |
10 | {% block methods %}
11 | .. automethod:: __init__
12 |
13 | {% if methods %}
14 | .. rubric:: {{ _('Methods') }}
15 |
16 | .. autosummary::
17 | {% for item in methods %}
18 | ~{{ name }}.{{ item }}
19 | {%- endfor %}
20 | {% endif %}
21 | {% endblock %}
22 |
23 | {% block attributes %}
24 | {% if attributes %}
25 | .. rubric:: {{ _('Attributes') }}
26 |
27 | .. autosummary::
28 | {% for item in attributes %}
29 | ~{{ name }}.{{ item }}
30 | {%- endfor %}
31 | {% endif %}
32 | {% endblock %}
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/_templates/custom-module-template.rst:
--------------------------------------------------------------------------------
1 | {{ fullname | escape | underline}}
2 |
3 | .. automodule:: {{ fullname }}
4 |
5 | {% block attributes %}
6 | {% if attributes %}
7 | .. rubric:: Module Attributes
8 |
9 | .. autosummary::
10 | :toctree:
11 | {% for item in attributes %}
12 | {{ item }}
13 | {%- endfor %}
14 | {% endif %}
15 | {% endblock %}
16 |
17 | {% block functions %}
18 | {% if functions %}
19 | .. rubric:: {{ _('Functions') }}
20 |
21 | .. autosummary::
22 | :toctree:
23 | {% for item in functions %}
24 | {{ item }}
25 | {%- endfor %}
26 | {% endif %}
27 | {% endblock %}
28 |
29 | {% block classes %}
30 | {% if classes %}
31 | .. rubric:: {{ _('Classes') }}
32 |
33 | .. autosummary::
34 | :toctree:
35 | :template: custom-class-template.rst
36 | {% for item in classes %}
37 | {{ item }}
38 | {%- endfor %}
39 | {% endif %}
40 | {% endblock %}
41 |
42 | {% block exceptions %}
43 | {% if exceptions %}
44 | .. rubric:: {{ _('Exceptions') }}
45 |
46 | .. autosummary::
47 | :toctree:
48 | {% for item in exceptions %}
49 | {{ item }}
50 | {%- endfor %}
51 | {% endif %}
52 | {% endblock %}
53 |
54 | {% block modules %}
55 | {% if modules %}
56 | .. rubric:: Modules
57 |
58 | .. autosummary::
59 | :toctree:
60 | :template: custom-module-template.rst
61 | :recursive:
62 | {% for item in modules %}
63 | {{ item }}
64 | {%- endfor %}
65 | {% endif %}
66 | {% endblock %}
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/classes/pyquibbler.AssignmentTemplate.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.AssignmentTemplate
2 | =============================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autoclass:: AssignmentTemplate
7 |
8 |
9 | .. automethod:: __init__
10 |
11 |
12 | .. rubric:: Methods
13 |
14 | .. autosummary::
15 |
16 | ~AssignmentTemplate.__init__
17 | ~AssignmentTemplate.convert
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/classes/pyquibbler.CacheMode.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.CacheMode
2 | ====================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autoclass:: CacheMode
7 |
8 |
9 | .. automethod:: __init__
10 |
11 |
12 |
13 |
14 |
15 |
16 | .. rubric:: Attributes
17 |
18 | .. autosummary::
19 |
20 | ~CacheMode.AUTO
21 | ~CacheMode.OFF
22 | ~CacheMode.ON
23 |
24 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/classes/pyquibbler.CacheStatus.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.CacheStatus
2 | ======================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autoclass:: CacheStatus
7 |
8 |
9 | .. automethod:: __init__
10 |
11 |
12 |
13 |
14 |
15 |
16 | .. rubric:: Attributes
17 |
18 | .. autosummary::
19 |
20 | ~CacheStatus.ALL_INVALID
21 | ~CacheStatus.ALL_VALID
22 | ~CacheStatus.PARTIAL
23 |
24 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/classes/pyquibbler.GraphicsUpdateType.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.GraphicsUpdateType
2 | =============================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autoclass:: GraphicsUpdateType
7 |
8 |
9 | .. automethod:: __init__
10 |
11 |
12 |
13 |
14 |
15 |
16 | .. rubric:: Attributes
17 |
18 | .. autosummary::
19 |
20 | ~GraphicsUpdateType.DRAG
21 | ~GraphicsUpdateType.DROP
22 | ~GraphicsUpdateType.CENTRAL
23 | ~GraphicsUpdateType.NEVER
24 |
25 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/classes/pyquibbler.QuibPropertiesViewer.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.QuibPropertiesViewer
2 | ===============================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autoclass:: QuibPropertiesViewer
7 |
8 |
9 | .. automethod:: __init__
10 |
11 |
12 | .. rubric:: Methods
13 |
14 | .. autosummary::
15 |
16 | ~QuibPropertiesViewer.__init__
17 | ~QuibPropertiesViewer.get_html_repr
18 | ~QuibPropertiesViewer.get_text_repr
19 |
20 |
21 |
22 |
23 |
24 | .. rubric:: Attributes
25 |
26 | .. autosummary::
27 |
28 | ~QuibPropertiesViewer.quib
29 |
30 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/classes/pyquibbler.SaveFormat.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.SaveFormat
2 | =====================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autoclass:: SaveFormat
7 |
8 |
9 | .. automethod:: __init__
10 |
11 |
12 |
13 |
14 |
15 |
16 | .. rubric:: Attributes
17 |
18 | .. autosummary::
19 |
20 | ~SaveFormat.OFF
21 | ~SaveFormat.TXT
22 | ~SaveFormat.BIN
23 |
24 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/classes/pyquibbler.ipywidget_viewer.QuibWidget.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.ipywidget\_viewer.QuibWidget
2 | =======================================
3 |
4 | .. currentmodule:: pyquibbler.ipywidget_viewer
5 |
6 | .. autoclass:: QuibWidget
7 |
8 |
9 | .. automethod:: __init__
10 |
11 |
12 | .. rubric:: Methods
13 |
14 | .. autosummary::
15 |
16 | ~QuibWidget.__init__
17 | ~QuibWidget.build_widget
18 | ~QuibWidget.disable_widget
19 | ~QuibWidget.get_widget
20 | ~QuibWidget.refresh
21 | ~QuibWidget.show_quib_properties_as_pop_up
22 |
23 |
24 |
25 |
26 |
27 | .. rubric:: Attributes
28 |
29 | .. autosummary::
30 |
31 | ~QuibWidget.quib
32 | ~QuibWidget.quib_ref
33 |
34 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/classes/pyquibbler.quib_network.Direction.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.quib\_network.Direction
2 | ==================================
3 |
4 | .. currentmodule:: pyquibbler.quib_network
5 |
6 | .. autoclass:: Direction
7 |
8 |
9 | .. automethod:: __init__
10 |
11 |
12 |
13 |
14 |
15 |
16 | .. rubric:: Attributes
17 |
18 | .. autosummary::
19 |
20 | ~Direction.UPSTREAM
21 | ~Direction.DOWNSTREAM
22 | ~Direction.BOTH
23 | ~Direction.ALL
24 |
25 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/conceptual_view.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/conceptual_view.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/examples/quibdemo_CheckButtons.rst:
--------------------------------------------------------------------------------
1 | Quib-linked CheckButtons widget
2 | -------------------------------
3 |
4 | **A demo of interactive quib-linked matplotlib CheckButtons widget.**
5 |
6 | - **Features:**
7 |
8 | - Quiby widgets.
9 | - Quiby axis attributes.
10 |
11 | - **Try me:**
12 |
13 | - Try playing with the check-buttons.
14 |
15 | .. code:: python
16 |
17 | from pyquibbler import iquib, initialize_quibbler, q
18 | initialize_quibbler()
19 | import matplotlib.pyplot as plt
20 | from matplotlib import widgets
21 | %matplotlib tk
22 |
23 | .. code:: python
24 |
25 | # Prepare figure
26 | plt.figure(figsize=(3, 3))
27 | ax = plt.gca()
28 |
29 | .. code:: python
30 |
31 | # Define input quib for colors
32 | colors = iquib([True, True, True])
33 |
34 | .. code:: python
35 |
36 | # Define a quib-widget
37 | widgets.CheckButtons(ax=ax, labels=['Red', 'Green', 'Blue'], actives=colors);
38 |
39 | .. code:: python
40 |
41 | # Set the color of the axis to the quib colors
42 | ax.set_facecolor(colors);
43 | .. image:: ../images/demo_gif/quibdemo_CheckButtons.gif
44 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/examples/quibdemo_drag_on_curve.rst:
--------------------------------------------------------------------------------
1 | Dragging graphics along a curved line
2 | -------------------------------------
3 |
4 | **A demo of interactively dragging a point along a curved line.**
5 |
6 | - **Features**
7 |
8 | - Graphics quibs
9 | - Graphics-driven assignments
10 | - Dragging with functional constrains
11 |
12 | - **Try me**
13 |
14 | - Try dragging the circle along the functional curve.
15 |
16 | .. code:: python
17 |
18 | from pyquibbler import iquib, initialize_quibbler, q
19 | initialize_quibbler()
20 | import matplotlib.pyplot as plt
21 | import numpy as np
22 | %matplotlib tk
23 |
24 | .. code:: python
25 |
26 | # Define and plot a curve:
27 | curve_function = lambda v: 4 * v ** 2 - v ** 3
28 | graph_xs = np.arange(0, 4, .2)
29 | graph_ys = curve_function(graph_xs)
30 | plt.figure(figsize=(4, 3))
31 | plt.plot(graph_xs, graph_ys, 'k')
32 | plt.axis([0, 4, 0, 12])
33 |
34 | # Define x-y quibs:
35 | point_x = iquib(3.)
36 | point_y = q(curve_function, point_x)
37 |
38 | # Plot the x-y point:
39 | plt.plot(point_x, point_y,
40 | marker='o', markerfacecolor='c',
41 | markersize=18, pickradius=20)
42 |
43 | # Define and plot text:
44 | xy_str = q("X={:.2f}, Y={:.2f}".format, point_x, point_y)
45 | plt.text(point_x, point_y + .6, xy_str,
46 | ha="center", va="bottom", fontsize=13);
47 | .. image:: ../images/demo_gif/quibdemo_drag_on_curve.gif
48 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/examples/quibdemo_drag_segments.rst:
--------------------------------------------------------------------------------
1 | Dragging graphics vertically/horizontally
2 | =========================================
3 |
4 | **A demo of interactive graphics-driven assignments with
5 | vertical/horizontal dragging.**
6 |
7 | - **Features**
8 |
9 | - Graphics-driven assignments
10 | - Horizontal/vertical dragging
11 | - Inverse assignments
12 |
13 | - **Try me**
14 |
15 | - Try dragging the corners ver
16 | - Try dragging the edge
17 |
18 | .. code:: python
19 |
20 | from pyquibbler import iquib, initialize_quibbler, q
21 | initialize_quibbler()
22 | import matplotlib.pyplot as plt
23 | import numpy as np
24 | %matplotlib tk
25 |
26 | .. code:: python
27 |
28 | # Figure setup and graphic properties
29 | plt.figure(figsize=(4, 4))
30 | plt.axis('square')
31 | plt.axis([-4, 10, -1, 11])
32 |
33 | # Define x-y coordinates
34 | x0 = iquib(0.)
35 | x1 = iquib(6.)
36 | x2 = iquib(6.)
37 | y = 8.
38 |
39 | # Plot parallelogram
40 | plt.plot([x0, x2 - x1 + x0, x2 + x0, x1 + x0, x0], [0, y, y, 0, 0], 'k:D', linewidth=2);
41 |
42 |
43 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/examples/quibdemo_drag_xy.rst:
--------------------------------------------------------------------------------
1 | Dragging graphics affects upstream quibs
2 | ----------------------------------------
3 |
4 | **A simple demo of interactive graphics-driven assignments.**
5 |
6 | - **Features:**
7 |
8 | - Graphics quibs
9 | - Graphics-driven assignments
10 | - Inverse assignments
11 |
12 | - **Try me:**
13 |
14 | - Try dragging the red marker; note the change in X,Y text, square,
15 | ellipse.
16 |
17 | .. code:: python
18 |
19 | from pyquibbler import iquib, initialize_quibbler, q
20 | import matplotlib.pyplot as plt
21 | import numpy as np
22 | initialize_quibbler()
23 | %matplotlib tk
24 |
25 | .. code:: python
26 |
27 | # Figure setup:
28 | fig1 = plt.figure(figsize=(4, 3))
29 | plt.axis('square')
30 | plt.axis([-10, 10, -10, 10]);
31 |
32 | .. code:: python
33 |
34 | # Define input quibs for x-y coordinates:
35 | xy = iquib(np.array([3., 4.]))
36 | x, y = xy
37 |
38 | .. code:: python
39 |
40 | # Plot graphics based on x and y:
41 |
42 | # Text:
43 | plt.text(-9, 9, q('X={:.2f}, Y={:.2f}'.format, x, y),
44 | fontsize=16, va='top')
45 |
46 | # Rectangle:
47 | plt.plot(x * np.array([-1, 1, 1, -1, -1]),
48 | y * np.array([-1, -1, 1, 1, -1]),
49 | 'k--o', linewidth=1)
50 |
51 | # Ellipse:
52 | phi = np.linspace(0, 2 * np.pi, 50)
53 | plt.plot(x * np.cos(phi), y * np.sin(phi), 'r-', linewidth=4);
54 |
55 | .. image:: ../images/demo_gif/quibdemo_drag_xy.gif
56 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/examples/quibdemo_dragging_fixed_object.rst:
--------------------------------------------------------------------------------
1 | Dragging a fixed object to affect another
2 | -----------------------------------------
3 |
4 | **A demo of interactively “dragging” a non-movable object.**
5 |
6 | - **Features**
7 |
8 | - Graphics quibs
9 | - Graphics-driven assignments
10 | - Inverse assignments of binary operators
11 |
12 | - **Try me**
13 |
14 | - Try dragging the fixed diamond. It won’t move but will affect the
15 | position of the circle.
16 |
17 | .. code:: python
18 |
19 | from pyquibbler import iquib, initialize_quibbler, q
20 | initialize_quibbler()
21 | import matplotlib.pyplot as plt
22 | import numpy as np
23 | %matplotlib tk
24 |
25 | .. code:: python
26 |
27 | # define and plot a point at xy coordinates:
28 | xy = iquib(np.array([2., 3.]))
29 | plt.axis('square')
30 | plt.axis([-10, 10, -10, 10])
31 | plt.plot(xy[0], xy[1], 'o', markersize=20)
32 | plt.text(-9, 9, np.array2string(xy, precision=2))
33 |
34 | # define and plot a differential function quib,
35 | # which is by defintion fixed at [0, 0]:
36 | dxy = xy - xy
37 | plt.plot(dxy[0], dxy[1], 'd', markersize=20);
38 | .. image:: ../images/demo_gif/quibdemo_dragging_fixed_object.gif
39 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/examples/quibdemo_image_probing.rst:
--------------------------------------------------------------------------------
1 | Simple quib-app for probing image RGB
2 | -------------------------------------
3 |
4 | **A simple demo of a quib-based GUI.**
5 |
6 | - **Features**
7 |
8 | - Graphics quibs
9 | - Graphics-driven assignments
10 | - Inverse assignments
11 |
12 | - **Try me**
13 |
14 | - Try dragging the marker and see the RGB values of the image.
15 |
16 | .. code:: python
17 |
18 | from pyquibbler import iquib, initialize_quibbler, q
19 | initialize_quibbler()
20 | import matplotlib.pyplot as plt
21 | import numpy as np
22 | %matplotlib tk
23 |
24 | .. code:: python
25 |
26 | # Load and plot an image:
27 | file = iquib('bacteria_drop.tif')
28 | img = plt.imread(file)
29 | plt.figure(figsize=(8, 3))
30 | plt.subplot(1, 2, 1)
31 | plt.imshow(img)
32 |
33 | # Choose and plot an x-y point:
34 | xy = iquib([50, 45])
35 | x, y = xy
36 | plt.plot(x, y, 'w+', markersize=18)
37 | plt.text(5, 10, xy, color='w', fontsize=14)
38 |
39 | # Plot the RGB at the chosen point:
40 | ax = plt.subplot(1, 2, 2)
41 | rgb = img[y, x, :]
42 | plt.bar(['R', 'G', 'B'], rgb, color=list('rgb'))
43 | ax.set_ylim([0, 255]);
44 |
45 | .. image:: ../images/demo_gif/quibdemo_image_probing.gif
46 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.can_redo.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.can\_redo
2 | ====================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: can_redo
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.can_undo.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.can\_undo
2 | ====================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: can_undo
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.default.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.default
2 | ==================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autodata:: default
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.get_project.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.get\_project
2 | =======================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: get_project
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.get_project_directory.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.get\_project\_directory
2 | ==================================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: get_project_directory
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.initialize_quibbler.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.initialize\_quibbler
2 | ===============================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: initialize_quibbler
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.iquib.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.iquib
2 | ================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: iquib
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.is_quiby.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.is\_quiby
2 | ====================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: is_quiby
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.list_quiby_funcs.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.list\_quiby\_funcs
2 | =============================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: list_quiby_funcs
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.load_quibs.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.load\_quibs
2 | ======================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: load_quibs
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.obj2quib.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.obj2quib
2 | ===================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: obj2quib
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.q.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.q
2 | ============
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: q
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.quib_network.dependency_graph.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.quib\_network.dependency\_graph
2 | ==========================================
3 |
4 | .. currentmodule:: pyquibbler.quib_network
5 |
6 | .. autofunction:: dependency_graph
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.quibapp.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.quibapp
2 | ==================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: quibapp
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.quiby.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.quiby
2 | ================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: quiby
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.redo.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.redo
2 | ===============
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: redo
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.refresh_graphics.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.refresh\_graphics
2 | ============================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: refresh_graphics
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.reset_file_loading_quibs.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.reset\_file\_loading\_quibs
2 | ======================================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: reset_file_loading_quibs
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.reset_impure_quibs.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.reset\_impure\_quibs
2 | ===============================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: reset_impure_quibs
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.reset_random_quibs.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.reset\_random\_quibs
2 | ===============================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: reset_random_quibs
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.save_quibs.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.save\_quibs
2 | ======================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: save_quibs
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.set_project_directory.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.set\_project\_directory
2 | ==================================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: set_project_directory
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.sync_quibs.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.sync\_quibs
2 | ======================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: sync_quibs
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/functions/pyquibbler.undo.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.undo
2 | ===============
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autofunction:: undo
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/Quickstart_assign_d_and_drag.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/Quickstart_assign_d_and_drag.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/Quickstart_assign_xy_and_drag.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/Quickstart_assign_xy_and_drag.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/Quickstart_interactive_image_cut.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/Quickstart_interactive_image_cut.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/Quickstart_load_image.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/Quickstart_load_image.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/Quickstart_widget_box_size.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/Quickstart_widget_box_size.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/User_defined_functions_pass_quibs.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/User_defined_functions_pass_quibs.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/assignments_assignment_template.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/assignments_assignment_template.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/assignments_jupyter_undo_redo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/assignments_jupyter_undo_redo.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/conceptual_view.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/conceptual_view.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/conceptual_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/conceptual_view.png
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_COVID_analysis.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_COVID_analysis.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_CheckButtons.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_CheckButtons.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_LotkaVolterra.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_LotkaVolterra.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_Mandelbrot.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_Mandelbrot.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_compare_images.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_compare_images.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_default_overriding.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_default_overriding.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_default_overriding_two_levels.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_default_overriding_two_levels.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_fixed_values.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_fixed_values.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_multiple_points.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_multiple_points.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_on_curve.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_on_curve.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_vertical_horizontal.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_vertical_horizontal.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_whole_object_vs_individual_points.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_whole_object_vs_individual_points.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_xy.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_drag_xy.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_dragging_fixed_object.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_dragging_fixed_object.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_fft.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_fft.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_fit_stocks.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_fit_stocks.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_gear.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_gear.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_image_ROI.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_image_ROI.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_image_probing.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_image_probing.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_image_thresholding.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_image_thresholding.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_ipywidgets_quadratic_eq.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_ipywidgets_quadratic_eq.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_making_the_quib_icon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_making_the_quib_icon.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_percolation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_percolation.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_periodic_functions.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_periodic_functions.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_pythagoras.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_pythagoras.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_quiby_axes.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_quiby_axes.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_random_quibs_dice.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_random_quibs_dice.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_repressilator.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_repressilator.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_rushhour.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_rushhour.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_same_data_in_many_forms.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_same_data_in_many_forms.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/demo_gif/quibdemo_slider.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/demo_gif/quibdemo_slider.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/dependency_graph_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/dependency_graph_1.png
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/dialog_box_per_item_factor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/dialog_box_per_item_factor.png
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/divergence_gif/Divergence_arrows.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/divergence_gif/Divergence_arrows.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/divergence_gif/Divergence_passquibs.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/divergence_gif/Divergence_passquibs.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/graphics_gif/graphics_rgb_probing_of_image.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/graphics_gif/graphics_rgb_probing_of_image.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/graphics_gif/graphics_slider_for_box_size.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/graphics_gif/graphics_slider_for_box_size.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/graphics_gif/graphics_xy_axis_labels.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/graphics_gif/graphics_xy_axis_labels.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/graphics_gif/graphics_xy_drag.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/graphics_gif/graphics_xy_drag.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/graphics_gif/graphics_xy_drag_horz_vert.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/graphics_gif/graphics_xy_drag_horz_vert.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/graphics_gif/graphics_xy_refresh.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/graphics_gif/graphics_xy_refresh.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/graphics_inverse.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/graphics_inverse.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/graphics_refresh.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/graphics_refresh.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/inverse_assignment_age_dob.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/inverse_assignment_age_dob.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/inverse_assignment_choice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/inverse_assignment_choice.png
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/inverse_assignment_illustrate.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/inverse_assignment_illustrate.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/labext_open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/labext_open.png
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/labext_quibbler_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/labext_quibbler_menu.png
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/labext_undo_redo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/labext_undo_redo.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/minimal_app_3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/minimal_app_3.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/network_tracing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/network_tracing.png
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/overriding_default_by_dragging.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/overriding_default_by_dragging.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/overriding_set_back_to_default.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/overriding_set_back_to_default.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/quib_editor_save_load.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/quib_editor_save_load.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/quib_editor_thresholds_rgb.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/quib_editor_thresholds_rgb.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/quib_transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/quib_transparent.png
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/quibicon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/quibicon.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-bidirectional.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-bidirectional.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-bob-alice.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-bob-alice.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-linked-widgets-quiby.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-linked-widgets-quiby.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-linked-widgets.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-linked-widgets.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-lorenz.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-lorenz.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-min-max.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/quiby_ipywidgets_gif/quiby-ipywidgets-min-max.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/tile_7_5_inverse.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/tile_7_5_inverse.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/images/tile_7_5_override.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/images/tile_7_5_override.gif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. image:: images/quibicon.gif
2 | :width: 300
3 | :align: right
4 |
5 | Data Quibbler
6 | =============
7 |
8 | **Interactive, transparent, and efficient data analytics.**
9 |
10 | .. toctree::
11 | :maxdepth: 1
12 |
13 | What-is-it
14 | Rationale
15 |
16 |
17 | Getting started
18 | ---------------
19 |
20 | .. toctree::
21 | :maxdepth: 1
22 |
23 | Installation
24 | Quickstart
25 | Examples
26 |
27 |
28 | User guide
29 | ----------
30 | .. toctree::
31 | :maxdepth: 1
32 |
33 | Introduction
34 | Graphics
35 | Inverse-assignments
36 | Overriding-default-functionality
37 | User-defined-functions
38 | Diverged-evaluation
39 | Random-functions
40 | Quib-naming
41 | Project-save-load
42 | Jupyter-lab-ext
43 | Quiby-ipywidgets
44 | Quib-relationships
45 |
46 |
47 | Functions
48 | ---------
49 | .. toctree::
50 | :maxdepth: 1
51 |
52 | List_of_functions
53 | List-of-quiby-functions
54 |
55 |
56 | Classes
57 | -------
58 | .. toctree::
59 | :maxdepth: 1
60 |
61 | major_classes/Quib_class
62 | major_classes/Project_class
63 | Quibbler_Enums
64 | Quibbler_display_classes
65 |
66 |
67 | Index
68 | -----
69 |
70 | * :ref:`genindex`
71 |
72 |
73 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/major_classes/Project_class.rst:
--------------------------------------------------------------------------------
1 | pyquibbler.Project
2 | ==================
3 |
4 | .. currentmodule:: pyquibbler
5 |
6 | .. autoclass:: Project
7 | :members:
8 | :show-inheritance:
9 | :inherited-members:
10 |
11 |
12 | .. rubric:: Project
13 |
14 | .. autosummary::
15 |
16 | ~Project.get_or_create
17 | ~Project.quibs
18 |
19 |
20 | .. rubric:: Undo/Redo
21 |
22 | .. autosummary::
23 |
24 | ~Project.undo
25 | ~Project.redo
26 | ~Project.can_undo
27 | ~Project.can_redo
28 | ~Project.clear_undo_and_redo_stacks
29 |
30 |
31 | .. rubric:: File syncing
32 |
33 | .. autosummary::
34 |
35 | ~Project.DEFAULT_SAVE_FORMAT
36 | ~Project.save_format
37 | ~Project.directory
38 | ~Project.load_quibs
39 | ~Project.save_quibs
40 | ~Project.sync_quibs
41 |
42 |
43 | .. rubric:: Reset quibs
44 |
45 | .. autosummary::
46 |
47 | ~Project.reset_file_loading_quibs
48 | ~Project.reset_impure_quibs
49 | ~Project.reset_random_quibs
50 |
51 |
52 | .. rubric:: Graphics
53 |
54 | .. autosummary::
55 |
56 | ~Project.DEFAULT_GRAPHICS_UPDATE
57 | ~Project.graphics_update
58 | ~Project.refresh_graphics
59 |
60 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | sphinx
2 | myst_parser
3 | pydata_sphinx_theme
4 | prometheus_client
5 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs/zips_for_download/examples.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs/zips_for_download/examples.zip
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs_notebooks/bacteria_drop.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs_notebooks/bacteria_drop.tif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs_notebooks/bacteria_in_a_droplet.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs_notebooks/bacteria_in_a_droplet.tif
--------------------------------------------------------------------------------
/pyquibbler-documentations/docs_notebooks/bacteria_in_droplets.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/docs_notebooks/bacteria_in_droplets.tif
--------------------------------------------------------------------------------
/pyquibbler-documentations/examples/README.md:
--------------------------------------------------------------------------------
1 | # Notebook examples
2 | ## Prerequisites
3 | For interactive matplotlib plots we use `ipympl` (`%matplotlib widget`). To install it run:
4 | ```bash
5 | pip install ipympl
6 | pip install ipywidgets
7 | jupyter nbextension install --py widgetsnbextension --user
8 | jupyter nbextension enable widgetsnbextension --user --py
9 | ```
10 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/examples/bacteria_drop.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/examples/bacteria_drop.tif
--------------------------------------------------------------------------------
/pyquibbler-documentations/examples/bacteria_in_droplets.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/examples/bacteria_in_droplets.tif
--------------------------------------------------------------------------------
/pyquibbler-documentations/examples/pipes.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/examples/pipes.jpg
--------------------------------------------------------------------------------
/pyquibbler-documentations/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=source
11 | set BUILDDIR=build
12 |
13 | %SPHINXBUILD% >NUL 2>NUL
14 | if errorlevel 9009 (
15 | echo.
16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17 | echo.installed, then set the SPHINXBUILD environment variable to point
18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
19 | echo.may add the Sphinx directory to PATH.
20 | echo.
21 | echo.If you don't have Sphinx installed, grab it from
22 | echo.https://www.sphinx-doc.org/
23 | exit /b 1
24 | )
25 |
26 | if "%1" == "" goto help
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/pyquibbler-documentations/powerpoint_files/images_lab_extension.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/powerpoint_files/images_lab_extension.pptx
--------------------------------------------------------------------------------
/pyquibbler-documentations/powerpoint_files/inverse.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/powerpoint_files/inverse.pptx
--------------------------------------------------------------------------------
/pyquibbler-documentations/powerpoint_files/network_tracing.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler-documentations/powerpoint_files/network_tracing.pptx
--------------------------------------------------------------------------------
/pyquibbler-labextension/.github_temp/workflows/binder-on-pr.yml:
--------------------------------------------------------------------------------
1 | # Reference https://mybinder.readthedocs.io/en/latest/howto/gh-actions-badges.html
2 | name: Binder Badge
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | permissions:
8 | pull-requests: write
9 |
10 |
11 | jobs:
12 | binder:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: comment on PR with Binder link
16 | uses: actions/github-script@v3
17 | with:
18 | github-token: ${{secrets.GITHUB_TOKEN}}
19 | script: |
20 | var PR_HEAD_USERREPO = process.env.PR_HEAD_USERREPO;
21 | var PR_HEAD_REF = process.env.PR_HEAD_REF;
22 | github.issues.createComment({
23 | issue_number: context.issue.number,
24 | owner: context.repo.owner,
25 | repo: context.repo.repo,
26 | body: `[](https://mybinder.org/v2/gh/${PR_HEAD_USERREPO}/${PR_HEAD_REF}?urlpath=lab) :point_left: Launch a Binder on branch _${PR_HEAD_USERREPO}/${PR_HEAD_REF}_`
27 | })
28 | env:
29 | PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
30 | PR_HEAD_USERREPO: ${{ github.event.pull_request.head.repo.full_name }}
31 |
32 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | **/node_modules
3 | **/lib
4 | **/package.json
5 | pyquibbler_labextension
6 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "none",
4 | "arrowParens": "avoid"
5 | }
6 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/.stylelintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "stylelint-config-recommended",
4 | "stylelint-config-standard",
5 | "stylelint-prettier/recommended"
6 | ],
7 | "rules": {
8 | "property-no-vendor-prefix": null,
9 | "selector-no-vendor-prefix": null,
10 | "value-no-vendor-prefix": null,
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include LICENSE
2 | include *.md
3 | include pyproject.toml
4 |
5 | include package.json
6 | include install.json
7 | include ts*.json
8 | include yarn.lock
9 |
10 | graft pyquibbler_labextension/labextension
11 |
12 | # Javascript files
13 | graft src
14 | graft style
15 | prune **/node_modules
16 | prune lib
17 | prune binder
18 |
19 | # Patterns to exclude from any directory
20 | global-exclude *~
21 | global-exclude *.pyc
22 | global-exclude *.pyo
23 | global-exclude .git
24 | global-exclude .ipynb_checkpoints
25 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/binder/environment.yml:
--------------------------------------------------------------------------------
1 | # a mybinder.org-ready environment for demoing pyquibbler_labextension
2 | # this environment may also be used locally on Linux/MacOS/Windows, e.g.
3 | #
4 | # conda env update --file binder/environment.yml
5 | # conda activate pyquibbler-labextension-demo
6 | #
7 | name: pyquibbler-labextension-demo
8 |
9 | channels:
10 | - conda-forge
11 |
12 | dependencies:
13 | # runtime dependencies
14 | - python >=3.8,<3.9.0a0
15 | - jupyterlab >=3,<4.0.0a0
16 | # labextension build dependencies
17 | - nodejs >=14,<15
18 | - pip
19 | - wheel
20 | # additional packages for demos
21 | # - ipywidgets
22 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/images/close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/install.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageManager": "python",
3 | "packageName": "pyquibbler_labextension",
4 | "uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package pyquibbler_labextension"
5 | }
6 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = [
3 | "setuptools>=68",
4 | "wheel",
5 | "jupyter_packaging>=0.12",
6 | "jupyterlab>=3,<4"
7 | ]
8 | build-backend = "setuptools.build_meta"
9 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/pyquibbler_labextension/__init__.py:
--------------------------------------------------------------------------------
1 | import json
2 | from pathlib import Path
3 |
4 | from ._version import __version__
5 |
6 |
7 | HERE = Path(__file__).parent.resolve()
8 |
9 |
10 | with (HERE / "labextension" / "package.json").open() as fid:
11 | data = json.load(fid)
12 |
13 |
14 | def _jupyter_labextension_paths():
15 | return [{
16 | "src": "labextension",
17 | "dest": data["name"]
18 | }]
19 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/pyquibbler_labextension/_version.py:
--------------------------------------------------------------------------------
1 | import json
2 | from pathlib import Path
3 |
4 | __all__ = ["__version__"]
5 | HERE = Path(__file__).parent.resolve()
6 |
7 |
8 | def _fetchVersion():
9 | for settings in HERE.rglob("package.json"):
10 | try:
11 | with settings.open() as f:
12 | version = json.load(f)["version"]
13 | return (
14 | version.replace("-alpha.", "a")
15 | .replace("-beta.", "b")
16 | .replace("-rc.", "rc")
17 | )
18 | except FileNotFoundError:
19 | pass
20 |
21 | raise FileNotFoundError(f"Could not find package.json under dir {HERE!s}")
22 |
23 |
24 | __version__ = _fetchVersion()
25 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/schema/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Settings",
3 | "description": "Settings.",
4 | "jupyter.lab.menus": {
5 | "main": [
6 | {
7 | "id": "pyquibbler-menu",
8 | "label": "Quibbler",
9 | "rank": 80,
10 | "items": [
11 | {
12 | "command": "quibbler:save"
13 | },
14 | {
15 | "command": "quibbler:load"
16 | },
17 | {
18 | "command": "quibbler:sync"
19 | },
20 | {
21 | "command": "quibbler:save-in-notebook"
22 | },
23 | {
24 | "command": "quibbler:clear-data"
25 | }
26 | ]
27 | }
28 | ]
29 | },
30 | "additionalProperties": false,
31 | "type": "object"
32 | }
33 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/src/custom.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.svg' {
2 | import React = require('react');
3 | export const ReactComponent: React.FC>;
4 | const src: string;
5 | export default src;
6 | }
--------------------------------------------------------------------------------
/pyquibbler-labextension/src/globalConfig.ts:
--------------------------------------------------------------------------------
1 |
2 | let shouldSaveLoadWithinNotebook = true;
3 |
4 | export const getShouldSaveLoadWithinNotebook = () => {
5 | return shouldSaveLoadWithinNotebook;
6 | }
7 |
8 | export const setShouldSaveLoadWithinNotebook = (should: boolean) => {
9 | shouldSaveLoadWithinNotebook = should;
10 | }
11 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/src/toolbarButtonExtension.ts:
--------------------------------------------------------------------------------
1 | import { DocumentRegistry } from '@jupyterlab/docregistry';
2 | import { INotebookModel, NotebookPanel } from '@jupyterlab/notebook';
3 | import { IDisposable } from '@lumino/disposable';
4 | import { ToolbarButton } from '@jupyterlab/apputils';
5 |
6 | export class ButtonExtension implements DocumentRegistry.IWidgetExtension {
7 |
8 | private readonly label: string;
9 | private readonly callback: () => void;
10 | button: ToolbarButton
11 |
12 | constructor(label: string, callback: () => void) {
13 | this.label = label;
14 | this.callback = callback;
15 | this.button = new ToolbarButton();
16 | }
17 |
18 | createNew(panel: NotebookPanel): IDisposable {
19 | const button = new ToolbarButton({
20 | label: this.label,
21 | onClick: this.callback
22 | });
23 |
24 | panel.toolbar.insertItem(10, this.label, button);
25 | button.enabled = false
26 | this.button = button
27 | return button;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/style/base.css:
--------------------------------------------------------------------------------
1 | /*
2 | See the JupyterLab Developer Guide for useful CSS Patterns:
3 |
4 | https://jupyterlab.readthedocs.io/en/stable/developer/css.html
5 | */
6 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/style/index.css:
--------------------------------------------------------------------------------
1 |
2 | @import url('base.css');
3 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/style/index.js:
--------------------------------------------------------------------------------
1 | import './base.css';
2 |
--------------------------------------------------------------------------------
/pyquibbler-labextension/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "composite": true,
5 | "declaration": true,
6 | "esModuleInterop": true,
7 | "incremental": true,
8 | "jsx": "react",
9 | "module": "esnext",
10 | "moduleResolution": "node",
11 | "noEmitOnError": true,
12 | "noImplicitAny": true,
13 | "noUnusedLocals": true,
14 | "preserveWatchOutput": true,
15 | "resolveJsonModule": true,
16 | "outDir": "lib",
17 | "rootDir": "src",
18 | "strict": true,
19 | "strictNullChecks": true,
20 | "target": "es2017",
21 | "types": []
22 | },
23 | "include": ["src"]
24 | }
25 |
--------------------------------------------------------------------------------
/pyquibbler/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools>=64", "wheel"]
3 | build-backend = "setuptools.build_meta"
4 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/__init__.py:
--------------------------------------------------------------------------------
1 | from .cache import CacheStatus
2 | from .quib.factory import create_quib
3 | from .assignment import Assignment, AssignmentTemplate
4 | from .quib import CacheMode, iquib, Quib
5 | from .file_syncing import SaveFormat, ResponseToFileNotDefined
6 | from .quib.graphics import GraphicsUpdateType
7 | from .function_overriding.override_all import initialize_quibbler
8 | from .quib.quib_properties_viewer import QuibPropertiesViewer
9 | from .utilities.file_path import NotebookArchiveMirrorPath
10 | from pyquibbler.debug_utils.timer import timer, timeit
11 | from .user_utils.gui_apps import quibapp
12 | from .user_utils.quiby_funcs import list_quiby_funcs, is_quiby, quiby, q
13 | from .user_utils.project_wraps import get_project, reset_random_quibs, reset_file_loading_quibs, reset_impure_quibs, \
14 | get_project_directory, set_project_directory, load_quibs, save_quibs, sync_quibs, undo, redo, can_undo, can_redo, \
15 | refresh_graphics
16 | from .user_utils.obj2quib import obj2quib
17 | from .assignment.default_value import default
18 | from .project import Project
19 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/assignment/__init__.py:
--------------------------------------------------------------------------------
1 | from .overrider import Overrider
2 | from .assignment import Assignment, AssignmentToQuib, AssignmentWithTolerance, create_assignment
3 | from .assignment_template import AssignmentTemplate, RangeAssignmentTemplate, BoundAssignmentTemplate, \
4 | BoundMaxBelowMinException, RangeStopBelowStartException, InvalidTypeException, \
5 | TypesMustBeSameInAssignmentTemplateException, create_assignment_template
6 | from .override_choice import get_override_group_for_quib_change, OverrideChoice, OverrideGroup, \
7 | override_dialog, AssignmentCancelledByUserException, OverrideOptionsTree, CannotChangeQuibAtPathException, \
8 | OverrideChoiceType, get_override_group_for_quib_changes
9 | from .simplify_assignment import AssignmentSimplifier
10 | from .utils import get_axes_x_y_tolerance
11 | from .default_value import default
12 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/assignment/default_value.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.utilities.basic_types import Singleton
2 |
3 |
4 | class Default(Singleton):
5 | """
6 | A default value for reverting overriding assignments.
7 |
8 | `default` is a singleton instance which is used as value in quib assignments to indicate
9 | reseting the quib's value back to its default functional value (namely, overruling prior overriding assignments).
10 |
11 | Examples
12 | --------
13 | >>> n = iquib(7)
14 | >>> x = np.arange(n).setp(allow_overriding=True)
15 | >>> x.get_value()
16 | array([ 0, 1, 2, 3, 4, 5, 6])
17 | >>>
18 | >>> x[1:-1] = 100 # override functional values
19 | >>> x.get_value()
20 | array([ 0, 100, 100, 100, 100, 100, 6])
21 | >>>
22 | >>> x[2:-2] = default # set specified elements back to default
23 | >>> x.get_value()
24 | array([ 0, 100, 2, 3, 4, 100, 6])
25 | >>>
26 | >>> x.assign(default) # reset all the array back to default
27 | >>> x.get_value()
28 | array([ 0, 1, 2, 3, 4, 5, 6])
29 | """
30 |
31 | def __repr__(self):
32 | return 'default'
33 |
34 |
35 | default = Default()
36 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/assignment/exceptions.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 | from dataclasses import dataclass
3 |
4 | from pyquibbler.exceptions import PyQuibblerException
5 |
6 |
7 | @dataclass
8 | class CannotConvertTextToAssignmentsException(PyQuibblerException):
9 | text: str
10 |
11 | def __str__(self):
12 | return f'Failed loading assignments from file: {self.text}'
13 |
14 |
15 | @dataclass
16 | class CannotConvertAssignmentsToTextException(PyQuibblerException):
17 |
18 | def __str__(self):
19 | return "The quib assignments contain objects that cannot be converted to text." \
20 | "To save the quib, set the save_format to binary (quib.save_format = 'bin')."
21 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/assignment/override_choice/__init__.py:
--------------------------------------------------------------------------------
1 | from .override_choice import get_override_group_for_quib_change, CannotChangeQuibAtPathException, OverrideOptionsTree, \
2 | get_override_group_for_quib_changes
3 | from .types import OverrideGroup, QuibChangeWithOverrideRemovals
4 | from .override_dialog import AssignmentCancelledByUserException, OverrideChoice, OverrideChoiceType, \
5 | choose_override_dialog
6 | from .choice_context import ChoiceContext
7 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/assignment/override_choice/choice_context.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 | from dataclasses import dataclass
3 | from typing import TYPE_CHECKING, Tuple
4 |
5 | if TYPE_CHECKING:
6 | from pyquibbler.quib.quib import Quib
7 |
8 |
9 | @dataclass(frozen=True)
10 | class ChoiceContext:
11 | """
12 | The context in which a choice was taken.
13 | Implements __hash__ and __eq__ to allow caching of user override choices.
14 | A choice can be reused in the context of a new assignment, if the options are the same.
15 | The override options for an inversed quib might change because when different indices are assigned to, the
16 | inversion tree might change (for example if one of the quib's parents is concat).
17 | """
18 | quibs_available_for_override: Tuple[Quib, ...]
19 | can_diverge: bool
20 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/assignment/override_choice/exceptions.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 | from pyquibbler.assignment import AssignmentToQuib
4 | from pyquibbler.exceptions import PyQuibblerException
5 |
6 |
7 | @dataclass
8 | class CannotChangeQuibAtPathException(PyQuibblerException):
9 | quib_change: AssignmentToQuib
10 |
11 | def __str__(self):
12 | return f'Cannot perform {self.quib_change.assignment} on {self.quib_change.quib}.\n' \
13 | f'The quib cannot be overridden and an overridable parent quib to inverse assign into was not found.\n' \
14 | f'Note that function quibs are not overridable by default.\n' \
15 | f'To allow overriding, try setting "{self.quib_change.quib}.allow_overriding = True"'
16 |
17 |
18 | @dataclass
19 | class AssignmentCancelledByUserException(PyQuibblerException):
20 |
21 | def __str__(self):
22 | return "User canceled inverse assignment dialog."
23 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/cache/__init__.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 |
3 | from .holistic_cache import HolisticCache
4 | from .shallow import NdVoidCache
5 | from .shallow.dict_cache import DictCache
6 | from .shallow.indexable_cache import IndexableCache
7 | from .shallow.nd_cache import NdFieldArrayShallowCache, NdUnstructuredArrayCache
8 | from .shallow.shallow_cache import ShallowCache
9 | from .cache import Cache, CacheStatus
10 | from .holistic_cache import PathCannotHaveComponentsException
11 | from .cache_utils import get_uncached_paths_matching_path, \
12 | get_cached_data_at_truncated_path_given_result_at_uncached_path
13 |
14 |
15 | def create_cache(result: Any) -> ShallowCache:
16 | """
17 | Create a new cache object matching the result- if no cache is found that specifically supports the requested
18 | object, a shallow cache will be created which does not support partial invalidation (paths must be whole in
19 | validation and invalidation)
20 | """
21 |
22 | cache_classes = {
23 | NdFieldArrayShallowCache,
24 | NdUnstructuredArrayCache,
25 | IndexableCache,
26 | NdVoidCache,
27 | DictCache
28 | }
29 | for cache_class in cache_classes:
30 | if cache_class.supports_result(result):
31 | return cache_class.create_invalid_cache_from_result(result)
32 | return HolisticCache.create_invalid_cache_from_result(result)
33 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/cache/shallow/__init__.py:
--------------------------------------------------------------------------------
1 | from .dict_cache import DictCache
2 | from .indexable_cache import IndexableCache
3 | from .nd_cache import NdUnstructuredArrayCache, NdFieldArrayShallowCache, NdVoidCache
4 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/cache/shallow/nd_cache/__init__.py:
--------------------------------------------------------------------------------
1 | from .nd_unstructured_array_cache import NdUnstructuredArrayCache
2 | from .nd_field_array_cache import NdFieldArrayShallowCache
3 | from .nd_void_cache import NdVoidCache
4 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/cache/shallow/nd_cache/nd_indexable_cache.py:
--------------------------------------------------------------------------------
1 | from abc import ABC
2 | from typing import List
3 |
4 | import numpy as np
5 |
6 | from pyquibbler.path import PathComponent
7 | from pyquibbler.cache.shallow.shallow_cache import ShallowCache
8 |
9 |
10 | class NdIndexableCache(ShallowCache, ABC):
11 | """
12 | A base class for an ndarray cache (both unstructured and field array)
13 | """
14 |
15 | SUPPORTING_TYPES = (np.ndarray,)
16 |
17 | def matches_result(self, result) -> bool:
18 | return super(NdIndexableCache, self).matches_result(result) \
19 | and result.shape == self.get_value().shape and result.dtype == self.get_value().dtype
20 |
21 | def _set_valid_at_all_paths(self):
22 | mask = np.full(self._value.shape, False, dtype=self._invalid_mask.dtype)
23 | if isinstance(self._invalid_mask, np.void):
24 | self._invalid_mask = np.void(mask)
25 | else:
26 | self._invalid_mask = mask
27 |
28 | @staticmethod
29 | def _filter_empty_paths(paths):
30 | return list(filter(lambda p: np.any(p[-1].component), paths))
31 |
32 | def _get_all_uncached_paths(self) -> List[List[PathComponent]]:
33 | return self._get_uncached_paths_at_path_component(PathComponent(True))
34 |
35 | def make_a_copy_if_value_is_a_view(self):
36 | if isinstance(self._value, np.ndarray) and self._value.base is not None:
37 | # array is a "view". We need to make a copy.
38 | self._value = np.array(self._value)
39 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/debug_utils/__init__.py:
--------------------------------------------------------------------------------
1 | from .timer import timer, timeit
2 | from .logger import logger
3 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/debug_utils/logger.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from pathlib import Path
3 |
4 | from pyquibbler.env import LOG_TO_STDOUT, LOG_TO_FILE
5 |
6 | logger = logging.getLogger('pyquibblerLogger')
7 | logger.setLevel(logging.ERROR)
8 |
9 |
10 | if LOG_TO_STDOUT:
11 | logger.addHandler(logging.StreamHandler())
12 |
13 | if LOG_TO_FILE:
14 | import __main__
15 | file = Path(__main__.__file__).parent / "pyquibbler.log"
16 | logger.addHandler(logging.FileHandler(file))
17 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/debug_utils/track_instances.py:
--------------------------------------------------------------------------------
1 | import contextlib
2 | import functools
3 | import gc
4 | from weakref import WeakSet
5 | from typing import Type
6 |
7 |
8 | @contextlib.contextmanager
9 | def track_instances_of_class(cls: Type, raise_if_any_left_alive=True):
10 | """
11 | Track all instances of a class (weak pointers)
12 | """
13 | prev_init = cls.__init__
14 | live_instances = WeakSet()
15 |
16 | @functools.wraps(prev_init)
17 | def _wrapped_init(self, *args, **kwargs):
18 | res = prev_init(self, *args, **kwargs)
19 | live_instances.add(self)
20 | return res
21 |
22 | cls.__init__ = _wrapped_init
23 |
24 | try:
25 | yield live_instances
26 | finally:
27 | gc.collect()
28 | cls.__init__ = prev_init
29 | if raise_if_any_left_alive and len(live_instances) > 0:
30 | raise ValueError(f"Found {len(live_instances)} instances of {cls} left alive")
31 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/exceptions.py:
--------------------------------------------------------------------------------
1 | from abc import ABCMeta, abstractmethod
2 | from dataclasses import dataclass
3 |
4 |
5 | @dataclass
6 | class PyQuibblerException(Exception, metaclass=ABCMeta):
7 | @abstractmethod
8 | def __str__(self):
9 | pass
10 |
11 |
12 | @dataclass
13 | class DebugException(PyQuibblerException, metaclass=ABCMeta):
14 | pass
15 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/file_syncing/__init__.py:
--------------------------------------------------------------------------------
1 | from .types import SaveFormat, ResponseToFileNotDefined, FileNotDefinedException
2 | from .quib_file_syncer import QuibFileSyncer
3 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_definitions/__init__.py:
--------------------------------------------------------------------------------
1 | from .definitions import get_definition_for_function, add_definition_for_function
2 | from .types import KeywordArgument, PositionalArgument, SubArgument
3 | from .location import SourceLocation, PositionalSourceLocation, KeywordSourceLocation
4 | from .func_call import FuncCall, FuncArgsKwargs
5 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/function_overriding/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/attribute_override.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 | from pyquibbler.function_definitions.func_definition import FuncDefinition
4 |
5 |
6 | @dataclass
7 | class AttributeOverride:
8 | attribute: str
9 | func_definition: FuncDefinition
10 |
11 |
12 | class MethodOverride(AttributeOverride):
13 | pass
14 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/defintion_without_override/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/function_overriding/defintion_without_override/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/is_initiated.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.utilities.basic_types import Flag
2 | from pyquibbler.utilities.warning_messages import no_header_warn
3 |
4 | IS_QUIBBLER_INITIATED = Flag(False)
5 |
6 |
7 | def set_quibbler_initialized(value: bool = True):
8 | IS_QUIBBLER_INITIATED.val = value
9 |
10 |
11 | def is_quibbler_initialized():
12 | return IS_QUIBBLER_INITIATED.val
13 |
14 |
15 | def warn_if_quibbler_not_initialized(message: str = ''):
16 | if not is_quibbler_initialized():
17 | no_header_warn(message + 'WARNING:\n'
18 | 'Quibbler has not been initialized.\n'
19 | 'Your code will run without quibs.\n'
20 | 'To initiate Quibbler, run initialize_quibbler()\n',
21 | once_only=True)
22 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/quib_overrides/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/function_overriding/quib_overrides/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/quib_overrides/operators/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/function_overriding/quib_overrides/operators/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/quib_overrides/operators/func_definitions.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.function_definitions.func_definition import create_or_reuse_func_definition
2 |
3 | from pyquibbler.inversion.inverters.list_operators import ListOperatorInverter
4 | from pyquibbler.path_translation.translators.list_operators import \
5 | ListOperatorBackwardsPathTranslator, ListOperatorForwardsPathTranslator
6 |
7 | from pyquibbler.function_overriding.third_party_overriding.numpy.func_definitions import \
8 | FUNC_DEFINITION_BINARY_ELEMENTWISE
9 |
10 | FUNC_DEFINITION_BINARY_ELEMENTWISE_AND_LIST = create_or_reuse_func_definition(
11 | base_func_definition=FUNC_DEFINITION_BINARY_ELEMENTWISE,
12 | backwards_path_translators=[ListOperatorBackwardsPathTranslator,
13 | *FUNC_DEFINITION_BINARY_ELEMENTWISE.backwards_path_translators],
14 | forwards_path_translators=[ListOperatorForwardsPathTranslator,
15 | *FUNC_DEFINITION_BINARY_ELEMENTWISE.forwards_path_translators],
16 | inverters=[ListOperatorInverter] + FUNC_DEFINITION_BINARY_ELEMENTWISE.inverters)
17 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/third_party_overriding/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/function_overriding/third_party_overriding/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/third_party_overriding/ipywidgets/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/function_overriding/third_party_overriding/ipywidgets/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/third_party_overriding/matplotlib/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/function_overriding/third_party_overriding/matplotlib/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/third_party_overriding/matplotlib/func_definitions.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.function_definitions.func_definition import create_or_reuse_func_definition
2 |
3 |
4 | FUNC_DEFINITION_GRAPHICS = create_or_reuse_func_definition(
5 | is_graphics=True,
6 | )
7 |
8 | FUNC_DEFINITION_GRAPHICS_AXES_SETTER = create_or_reuse_func_definition(
9 | is_graphics=True,
10 | is_artist_setter=True,
11 | )
12 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/third_party_overriding/non_quib_overrides/__init__.py:
--------------------------------------------------------------------------------
1 | from .axes_overrides import override_axes_methods
2 | from .widgets_override import switch_widgets_to_quib_supporting_widgets
3 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/third_party_overriding/non_quib_overrides/widgets_override.py:
--------------------------------------------------------------------------------
1 | import matplotlib.widgets
2 |
3 | from pyquibbler.graphics.widgets import QRadioButtons, QSlider, QRangeSlider, \
4 | QRectangleSelector, QTextBox
5 |
6 | widget_class_names_to_quib_supporting_widget = {
7 | 'RadioButtons': QRadioButtons,
8 | 'Slider': QSlider,
9 | 'RangeSlider': QRangeSlider,
10 | 'RectangleSelector': QRectangleSelector,
11 | 'TextBox': QTextBox,
12 | }
13 |
14 |
15 | def switch_widgets_to_quib_supporting_widgets():
16 | for widget_class_name, quib_supporting_widget in widget_class_names_to_quib_supporting_widget.items():
17 | setattr(matplotlib.widgets, widget_class_name, quib_supporting_widget)
18 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/function_overriding/third_party_overriding/numpy/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/function_overriding/third_party_overriding/numpy/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/graphics/__init__.py:
--------------------------------------------------------------------------------
1 | from .graphics_collection import GraphicsCollection
2 |
3 | SUPPORTED_BACKENDS = {'MacOSX', 'TkAgg'}
4 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/graphics/process_plot_var_args.py:
--------------------------------------------------------------------------------
1 | from typing import Optional, Callable
2 |
3 | from matplotlib.axes._base import _process_plot_var_args
4 |
5 |
6 | class quibbler_process_plot_var_args(_process_plot_var_args):
7 | """
8 | make _idx a property to be able to set a callback on it
9 | """
10 | callback: Optional[Callable] = None
11 |
12 | @property
13 | def _idx(self):
14 | return self.__idx
15 |
16 | @_idx.setter
17 | def _idx(self, value):
18 | if self.callback:
19 | self.callback(self, self.__idx)
20 | self.__idx = value
21 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/graphics/widgets/__init__.py:
--------------------------------------------------------------------------------
1 | from .q_slider import QSlider, QRangeSlider
2 | from .q_radio_buttons import QRadioButtons
3 | from .q_rectangle_selector import QRectangleSelector
4 | from .q_text_box import QTextBox
5 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/graphics/widgets/base_q_widget.py:
--------------------------------------------------------------------------------
1 | import contextlib
2 |
3 | from matplotlib.widgets import Widget
4 |
5 | from pyquibbler.quib.get_value_context_manager import is_within_get_value_context
6 |
7 |
8 | class QWidget(Widget):
9 |
10 | def __init__(self, *args, **kwargs):
11 | self.created_in_get_value_context = False
12 | super().__init__(*args, **kwargs)
13 | self.created_in_get_value_context = is_within_get_value_context()
14 |
15 | @contextlib.contextmanager
16 | def avoid_redraws_if_created_in_get_value_context(self):
17 | if self.created_in_get_value_context:
18 | drawon = self.drawon
19 | self.drawon = False
20 | try:
21 | yield
22 | finally:
23 | self.drawon = drawon
24 | else:
25 | yield
26 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/graphics/widgets/q_radio_buttons.py:
--------------------------------------------------------------------------------
1 | from matplotlib.axes import Axes
2 | from matplotlib.widgets import RadioButtons
3 | from typing import List
4 |
5 | from .base_q_widget import QWidget
6 |
7 |
8 | class QRadioButtons(QWidget, RadioButtons):
9 | """
10 | Like Radio buttons, also featuring:
11 | - Exposing selected index via the selected_index attribute
12 | """
13 |
14 | def __init__(self, ax: Axes, labels: List[str], active=0, **kwargs):
15 | self.selected_index = active
16 | super().__init__(ax, labels, active=active, **kwargs)
17 |
18 | def set_active(self, index: int):
19 | self.selected_index = index
20 | with self.avoid_redraws_if_created_in_get_value_context():
21 | super().set_active(index)
22 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/graphics/widgets/q_text_box.py:
--------------------------------------------------------------------------------
1 | from matplotlib.widgets import TextBox
2 |
3 |
4 | class QTextBox(TextBox):
5 | """
6 | Like TextBox, also featuring:
7 | - text does not need to be a str. If text is not str, it is converted to str and then converted back to original
8 | type for callback functions.
9 | """
10 |
11 | def __init__(self, ax, label, initial, **kwargs):
12 | self._type = type(initial)
13 | initial = str(initial)
14 | super().__init__(ax, label, initial, **kwargs)
15 |
16 | def convert_text_to_original_type(self, text):
17 | return self._type(text)
18 |
19 | def on_text_change(self, func):
20 | super().on_text_change(lambda text: func(self.convert_text_to_original_type(text)))
21 |
22 | def on_submit(self, func):
23 | super().on_submit(lambda text: func(self.convert_text_to_original_type(text)))
24 |
25 | # old matplotlib:
26 | # def _rendercursor(self):
27 | # # Matplotlib has a bug - does not update on MacOSX. To fix, we run our own redraw_canvas:
28 | # super()._rendercursor()
29 | # redraw_canvas(self.ax.figure.canvas)
30 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/graphics/widgets/utils.py:
--------------------------------------------------------------------------------
1 | from matplotlib import get_backend
2 | from pyquibbler.utilities.general_utils import Args, Kwargs
3 |
4 |
5 | def prevent_squash(args: Args, kwargs: Kwargs):
6 | obj = args[0]
7 | return not (obj.created_in_get_value_context and get_backend() == 'TkAgg')
8 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/inversion/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/inversion/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/inversion/invert.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 | from typing import List
3 |
4 | from pyquibbler.assignment import Assignment, default
5 | from pyquibbler.path.data_accessing import deep_get
6 | from pyquibbler.path_translation.source_func_call import SourceFuncCall
7 | from pyquibbler.path_translation.types import Inversal
8 | from pyquibbler.utilities.multiple_instance_runner import MultipleInstanceRunner
9 |
10 |
11 | def invert(func_call: SourceFuncCall, assignment: Assignment, previous_result) -> List[Inversal]:
12 | """
13 | Get all the inversions for a given assignment on the result of a funccall
14 | """
15 |
16 | is_default = assignment.is_default()
17 | if is_default:
18 | actual_assignment = Assignment(value=deep_get(previous_result, assignment.path),
19 | path=assignment.path)
20 | else:
21 | actual_assignment = assignment
22 |
23 | inversals = MultipleInstanceRunner(run_condition=None, runner_types=func_call.func_definition.inverters,
24 | func_call=func_call, assignment=actual_assignment,
25 | previous_result=previous_result).run()
26 |
27 | for inversal in inversals:
28 | if is_default:
29 | inversal.assignment.value = default
30 | else:
31 | inversal.cast_assigned_value_by_source_value()
32 |
33 | return inversals
34 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/inversion/inverters/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/inversion/inverters/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/inversion/inverters/getitem.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | from pyquibbler.assignment.assignment import create_assignment_from_nominal_down_up_values
4 | from pyquibbler.path_translation.base_translators import BackwardsTranslationRunCondition
5 | from pyquibbler.path_translation.translate import backwards_translate
6 | from pyquibbler.path_translation.types import Inversal
7 |
8 | from ..inverter import Inverter
9 |
10 |
11 | class GetItemInverter(Inverter):
12 |
13 | def get_inversals(self):
14 | sources_to_paths_in_sources = backwards_translate(
15 | run_condition=BackwardsTranslationRunCondition.WITH_SHAPE_AND_TYPE,
16 | func_call=self._func_call,
17 | path=self._assignment.path,
18 | shape=np.shape(self._previous_result),
19 | type_=type(self._previous_result)
20 | )
21 | if len(sources_to_paths_in_sources) != 1:
22 | self._raise_run_failed_exception()
23 |
24 | source = list(sources_to_paths_in_sources.keys())[0]
25 | path_in_source = sources_to_paths_in_sources[source]
26 | nominal_down_up_values = self._get_assignment_nominal_down_up_values()
27 | new_assignment = create_assignment_from_nominal_down_up_values(nominal_down_up_values=nominal_down_up_values,
28 | path=path_in_source)
29 | return [Inversal(source=source, assignment=new_assignment)]
30 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/inversion/inverters/transpositional.py:
--------------------------------------------------------------------------------
1 | from typing import Type, Any
2 |
3 | from pyquibbler.path import Path
4 | from pyquibbler.function_definitions import SourceLocation
5 | from pyquibbler.path_translation import BackwardsPathTranslator, ForwardsPathTranslator, Source
6 | from pyquibbler.path_translation.translators.transpositional import \
7 | TranspositionalBackwardsPathTranslator, TranspositionalForwardsPathTranslator
8 |
9 | from .numpy import NumpyInverter
10 |
11 |
12 | class TranspositionalOneToOneInverter(NumpyInverter):
13 | """
14 | Inverts assignments to transpositional functions (like `rot90`, `transpose`, `concatenate`, etc).
15 | Uses the transpositional path translators (based on array index code masks).
16 | """
17 | BACKWARDS_TRANSLATOR_TYPE: Type[BackwardsPathTranslator] = TranspositionalBackwardsPathTranslator
18 | FORWARDS_TRANSLATOR_TYPE: Type[ForwardsPathTranslator] = TranspositionalForwardsPathTranslator
19 | IS_ONE_TO_MANY_FUNC: bool = False
20 |
21 | def _invert_value(self, source: Source, source_location: SourceLocation, path_in_source: Path,
22 | result_value: Any, path_in_result: Path) -> Any:
23 | return result_value
24 |
25 |
26 | class TranspositionalOneToManyInverter(TranspositionalOneToOneInverter):
27 | """
28 | Inverts assignments to transpositional functions that can create multiple copies of each element.
29 | (like `full`, `repeat`, etc).
30 | """
31 | IS_ONE_TO_MANY_FUNC: bool = True
32 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/ipywidget_viewer/__init__.py:
--------------------------------------------------------------------------------
1 | from .quib_widget import QuibWidget
2 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/optional_packages/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/optional_packages/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/optional_packages/emulate_missing_packages.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.utilities.basic_types import Mutable
2 |
3 | EMULATE_MISSING_PACKAGES = Mutable([])
4 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/optional_packages/exceptions.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 | from typing import List
3 |
4 | from pyquibbler.exceptions import PyQuibblerException
5 |
6 |
7 | @dataclass
8 | class MissingPackagesForFunctionException(PyQuibblerException):
9 | function_name: str
10 | package_names: List[str]
11 |
12 | def __str__(self):
13 | return f'Using {self.function_name} requires installing the following packages:\n' \
14 | ', '.join(self.package_names)
15 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/optional_packages/get_IPython.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.optional_packages.emulate_missing_packages import EMULATE_MISSING_PACKAGES
2 |
3 | PACKAGE_NAME = 'IPython'
4 |
5 | if PACKAGE_NAME in EMULATE_MISSING_PACKAGES.val:
6 | raise ImportError
7 |
8 | from IPython.display import display, HTML # noqa: F401, E402
9 | from IPython import get_ipython # noqa: F401, E402
10 |
11 | # noinspection PyPackageRequirements
12 | from ipykernel.comm import Comm # noqa: F401, E402
13 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/optional_packages/get_ipycytoscape.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.optional_packages.emulate_missing_packages import EMULATE_MISSING_PACKAGES
2 |
3 | PACKAGE_NAME = 'ipycytoscape'
4 |
5 | if PACKAGE_NAME in EMULATE_MISSING_PACKAGES.val:
6 | raise ImportError
7 |
8 | # noinspection PyPackageRequirements
9 | import ipycytoscape # noqa
10 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/optional_packages/get_ipywidgets.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.optional_packages.emulate_missing_packages import EMULATE_MISSING_PACKAGES
2 |
3 | PACKAGE_NAME = 'ipywidgets'
4 |
5 | if PACKAGE_NAME in EMULATE_MISSING_PACKAGES.val:
6 | raise ImportError
7 |
8 | # noinspection PyPackageRequirements
9 | import ipywidgets # noqa: F401, E402
10 |
11 | # noinspection PyPackageRequirements
12 | from traitlets import TraitType # noqa: F401, E402
13 |
14 | from ipywidgets.widgets.widget_int import _BoundedIntRange # noqa: F401, E402
15 | from ipywidgets.widgets.widget_float import _BoundedFloatRange # noqa: F401, E402
16 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/path/__init__.py:
--------------------------------------------------------------------------------
1 | from .path_component import Path, Paths, PathComponent, SpecialComponent
2 | from .data_accessing import deep_get, deep_set, FailedToDeepAssignException
3 | from .hashable import get_hashable_path
4 | from .utils import split_path_at_end_of_object
5 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/path/hashable.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 | import numpy as np
4 |
5 | from pyquibbler.path import Path
6 |
7 |
8 | @dataclass(frozen=True)
9 | class FrozenSlice:
10 | start: int
11 | step: int
12 | stop: int
13 |
14 |
15 | def _hash_component_value(inner_component):
16 | if isinstance(inner_component, list):
17 | return tuple([_hash_component_value(x) for x in inner_component])
18 | elif isinstance(inner_component, np.ndarray):
19 | return inner_component.tobytes()
20 | elif isinstance(inner_component, slice):
21 | return FrozenSlice(inner_component.start, inner_component.step, inner_component.stop)
22 | elif isinstance(inner_component, tuple):
23 | return tuple([_hash_component_value(x) for x in inner_component])
24 | return inner_component
25 |
26 |
27 | def get_hashable_path(path: Path):
28 | """
29 | Get a hashable path (list of pathcomponents)- this supports known indexing methods
30 | """
31 | return tuple([
32 | _hash_component_value(p.component) for p in path
33 | ])
34 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/path_translation/__init__.py:
--------------------------------------------------------------------------------
1 | from .base_translators import BackwardsPathTranslator, ForwardsPathTranslator
2 | from .source_func_call import SourceFuncCall
3 | from .types import Source, NoMetadataSource, Inversal
4 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/path_translation/array_index_codes.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 | from typing import Union
3 |
4 | import numpy as np
5 | from numpy.typing import NDArray
6 |
7 |
8 | INDEX_TYPE = np.int64
9 |
10 |
11 | class IndexCode(INDEX_TYPE, Enum):
12 | """
13 | Codes for array elements representing a focal source or other objects
14 | """
15 | OTHERS_ELEMENT = -7
16 | NON_CHOSEN_ELEMENT = -6
17 | SCALAR_NOT_CONTAINING_FOCAL_SOURCE = -5
18 | LIST_NOT_CONTAINING_CHOSEN_ELEMENTS = -4
19 | LIST_CONTAINING_CHOSEN_ELEMENTS = -3
20 | SCALAR_CONTAINING_FOCAL_SOURCE = -2
21 | FOCAL_SOURCE_SCALAR = -1
22 | # otherwise, source elements are represented by their linear index ( >= 0)
23 |
24 |
25 | IndexCodeArray = NDArray[Union[INDEX_TYPE, IndexCode]]
26 |
27 |
28 | MAXIMAL_NON_CHOSEN_ELEMENTS = IndexCode.LIST_NOT_CONTAINING_CHOSEN_ELEMENTS
29 |
30 |
31 | def is_focal_element(obj: NDArray):
32 | return obj > MAXIMAL_NON_CHOSEN_ELEMENTS
33 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/path_translation/exceptions.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from pyquibbler.exceptions import PyQuibblerException
4 | from pyquibbler.utilities.multiple_instance_runner import BaseRunnerFailedException
5 |
6 |
7 | class FailedToTranslateException(BaseRunnerFailedException):
8 | def __str__(self):
9 | return "Failed to translate func call"
10 |
11 |
12 | class PyQuibblerRaggedArrayException(PyQuibblerException):
13 | def __str__(self):
14 | return 'Arrays of ragged arrays or lists are not supported.'
15 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/path_translation/translators/__init__.py:
--------------------------------------------------------------------------------
1 | from .transpositional import TranspositionalForwardsPathTranslator, TranspositionalBackwardsPathTranslator
2 | from .getitem import GetItemBackwardsPathTranslator, GetItemForwardsPathTranslator
3 | from .axis_reduction import AxisReductionForwardsPathTranslator, AxisReductionBackwardsPathTranslator
4 | from .axis_accumulation import \
5 | AxisAccumulationForwardsPathTranslator, AxisAccumulationBackwardsPathTranslator
6 | from .axis_all_to_all import AxisAllToAllBackwardsPathTranslator, AxisAllToAllForwardsPathTranslator
7 | from .shape_only import ShapeOnlyBackwardsPathTranslator, ShapeOnlyForwardsPathTranslator
8 | from .elementwise import BinaryElementwiseBackwardsPathTranslator, BinaryElementwiseForwardsPathTranslator
9 | from .elementwise import UnaryElementwiseBackwardsPathTranslator, UnaryElementwiseForwardsPathTranslator
10 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/path_translation/translators/obj2quib.py:
--------------------------------------------------------------------------------
1 | from typing import Dict
2 |
3 | from pyquibbler.utilities.iterators import iter_objects_of_type_in_object_recursively
4 | from pyquibbler.path import Path, Paths, split_path_at_end_of_object
5 |
6 | from ..base_translators import BackwardsTranslationRunCondition, BackwardsPathTranslator, ForwardsPathTranslator
7 | from ..types import Source
8 |
9 |
10 | class Obj2QuibBackwardsPathTranslator(BackwardsPathTranslator):
11 |
12 | RUN_CONDITIONS = [BackwardsTranslationRunCondition.NO_SHAPE_AND_TYPE]
13 |
14 | def _backwards_translate(self) -> Dict[Source, Path]:
15 | path_within_object, remaining_path, obj = split_path_at_end_of_object(self._func_call.args[0], self._path)
16 |
17 | if isinstance(obj, Source):
18 | return {obj: remaining_path}
19 |
20 | sources_within_the_referenced_path = iter_objects_of_type_in_object_recursively(Source, obj)
21 | return {source: [] for source in sources_within_the_referenced_path}
22 |
23 |
24 | class Obj2QuibForwardsPathTranslator(ForwardsPathTranslator):
25 |
26 | def _forward_translate(self) -> Paths:
27 | return [self._source_location.path + self._path]
28 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/path_translation/translators/quiby_name.py:
--------------------------------------------------------------------------------
1 | from typing import Dict
2 |
3 | from pyquibbler.path.path_component import Path, Paths
4 |
5 | from pyquibbler.path_translation.base_translators import ForwardsPathTranslator, BackwardsPathTranslator
6 | from pyquibbler.path_translation.types import Source
7 |
8 |
9 | class QuibyNameBackwardsPathTranslator(BackwardsPathTranslator):
10 | """
11 | We need no data from the sources.
12 | """
13 | def _backwards_translate(self) -> Dict[Source, Path]:
14 | sources_to_paths = {}
15 | for source in self._func_call.get_data_sources():
16 | sources_to_paths[source] = []
17 | return sources_to_paths
18 |
19 |
20 | class QuibyNameForwardsPathTranslator(ForwardsPathTranslator):
21 | """
22 | We are not affected by change the sources.
23 | """
24 | def _forward_translate(self) -> Paths:
25 | return []
26 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/path_translation/translators/shape_only.py:
--------------------------------------------------------------------------------
1 | from typing import Dict
2 |
3 | from pyquibbler.path.path_component import PathComponent, Path, Paths
4 |
5 | from pyquibbler.path_translation.base_translators import ForwardsPathTranslator, BackwardsPathTranslator
6 | from pyquibbler.path_translation.types import Source
7 |
8 |
9 | class ShapeOnlyBackwardsPathTranslator(BackwardsPathTranslator):
10 | """
11 | For functions like, np.ones_like, np.zeros_like, np.shape,
12 | we only need the shape of sources. Not their value.
13 | """
14 | def _backwards_translate(self) -> Dict[Source, Path]:
15 | sources_to_paths = {}
16 | for source in self._func_call.get_data_sources():
17 | sources_to_paths[source] = [PathComponent(None)]
18 | return sources_to_paths
19 |
20 |
21 | class ShapeOnlyForwardsPathTranslator(ForwardsPathTranslator):
22 | """
23 | We are only affected if sources change their shape. Element-wise changes are not affecting us.
24 | We need to take care of lists that can change their size due to assignment.
25 | """
26 | def _forward_translate(self) -> Paths:
27 | path = self._path
28 | is_list_extension_possible = \
29 | len(path) \
30 | and self._get_source_type() is list \
31 | and isinstance(path[0].component, slice)
32 | return [] if len(path) and not is_list_extension_possible else [[]]
33 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/path_translation/utils.py:
--------------------------------------------------------------------------------
1 | from copy import copy
2 | from typing import Any
3 |
4 | from pyquibbler.utilities.iterators import SHALLOW_MAX_LENGTH, SHALLOW_MAX_DEPTH, recursively_run_func_on_object
5 |
6 | from .types import Source
7 |
8 |
9 | def copy_and_replace_sources_with_vals(obj: Any):
10 | """
11 | Copy `obj` while replacing quibs with their values, with a limited depth and length.
12 | """
13 | from matplotlib.artist import Artist
14 |
15 | def replace_with_value_if_source_or_copy(o):
16 | if isinstance(o, Source):
17 | return o.value
18 | if isinstance(o, Artist):
19 | return o
20 | try:
21 | return copy(o)
22 | except NotImplementedError:
23 | return o
24 |
25 | result = recursively_run_func_on_object(func=replace_with_value_if_source_or_copy, max_depth=SHALLOW_MAX_DEPTH,
26 | max_length=SHALLOW_MAX_LENGTH, obj=obj)
27 | return result
28 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/project/__init__.py:
--------------------------------------------------------------------------------
1 | from .project import Project, NothingToUndoException, NothingToRedoException
2 | from .actions import Action, AddAssignmentAction
3 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/project/exceptions.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 | from pyquibbler.exceptions import PyQuibblerException
4 |
5 |
6 | class NothingToUndoException(PyQuibblerException):
7 |
8 | def __str__(self):
9 | return "There are no actions left to undo."
10 |
11 |
12 | class NothingToRedoException(PyQuibblerException):
13 |
14 | def __str__(self):
15 | return "There are no actions left to redo."
16 |
17 |
18 | @dataclass
19 | class NoProjectDirectoryException(PyQuibblerException):
20 | action: str
21 |
22 | def __str__(self):
23 | return f"The project directory is not defined.\n" \
24 | f"To {self.action} quibs, set the project directory (see set_project_directory)."
25 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/project/jupyer_project/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/project/jupyer_project/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/project/jupyer_project/flask_dialog_server.py:
--------------------------------------------------------------------------------
1 |
2 | # TODO: werkzeug version compatibility fix.
3 | # Need to resolve werkzeug version
4 | # I tried setting the version to 2.0.3 in setup.py, which has
5 | # the matching import, but then the installation fails on the build of matplotlib.
6 | # For now, I'm doing his ad-hoc patch.
7 | try:
8 | from flask import Flask, request
9 | except ImportError:
10 | from urllib.parse import quote as url_quote
11 | from werkzeug import urls
12 | urls.url_quote = url_quote
13 | from flask import Flask, request
14 |
15 | from flask_cors import CORS
16 |
17 |
18 | def run_flask_app(port, answer_queue):
19 | app = Flask(__name__)
20 | CORS(app)
21 |
22 | @app.route('/ping')
23 | def pong():
24 | return 'pong'
25 |
26 | @app.route('/answer', methods=['POST'])
27 | def dialog_answer():
28 | answer_queue.put(request.json["option"])
29 | return 'done'
30 |
31 | app.run('0.0.0.0', port=port)
32 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/project/jupyer_project/utils.py:
--------------------------------------------------------------------------------
1 | import socket
2 | import sys
3 |
4 |
5 | def find_free_port():
6 | with socket.socket() as s:
7 | s.bind(('', 0)) # Bind to a free port provided by the host.
8 | return s.getsockname()[1] # Return the port number assigned.
9 |
10 |
11 | def is_within_jupyter_lab() -> bool:
12 | try:
13 | from pyquibbler.optional_packages.get_IPython import get_ipython, Comm # noqa: F401
14 | shell = get_ipython().__class__.__name__
15 | if shell == 'ZMQInteractiveShell':
16 | return True # Jupyter notebook or qtconsole
17 | elif shell == 'TerminalInteractiveShell':
18 | return False # Terminal running IPython
19 | else:
20 | return False # Other type (?)
21 | except (NameError, ImportError):
22 | return False # Probably standard Python interpreter
23 |
24 |
25 | def is_within_colab() -> bool:
26 | return 'google.colab' in sys.modules
27 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/__init__.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.quib.specialized_functions.iquib import iquib
2 | from .func_calling.cache_mode import CacheMode
3 | from .quib import Quib
4 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/consts.py:
--------------------------------------------------------------------------------
1 | MAX_BYTES_PER_SECOND = 2 ** 30
2 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/__init__.py:
--------------------------------------------------------------------------------
1 | from .quib_func_call import QuibFuncCall, WholeValueNonGraphicQuibFuncCall
2 | from .cached_quib_func_call import CachedQuibFuncCall
3 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/cache_mode.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.utilities.basic_types import StrEnum
2 |
3 |
4 | class CacheMode(StrEnum):
5 | """
6 | Modes of quib caching.
7 |
8 | Dictates whether a quib should cache its function result, to avoid recalculations on repeated calls.
9 |
10 | Options are listed below (see Attributes).
11 |
12 | Note
13 | ----
14 | Quibs with random functions and graphics quibs are always cached (even with cache mode set to ``'off'``).
15 |
16 | See Also
17 | --------
18 | Quib.cache_mode, CacheStatus
19 | """
20 | AUTO = 'auto'
21 | "Auto cache decision based on the ratio between evaluation time and memory consumption (``'auto'``)."
22 |
23 | OFF = 'off'
24 | "Do not cache, unless the quib's function is random or graphics (``'off'``)."
25 |
26 | ON = 'on'
27 | "Always cache (``'on'``)."
28 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/func_calls/__init__.py:
--------------------------------------------------------------------------------
1 | from .known_graphics import PlotQuibFuncCall, SliderQuibFuncCall, RangeSliderQuibFuncCall, RadioButtonsQuibFuncCall, \
2 | RectangleSelectorQuibFuncCall, CheckButtonsQuibFuncCall
3 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/func_calls/known_graphics/__init__.py:
--------------------------------------------------------------------------------
1 | from .widgets import SliderQuibFuncCall, RangeSliderQuibFuncCall, RadioButtonsQuibFuncCall, \
2 | RectangleSelectorQuibFuncCall, CheckButtonsQuibFuncCall
3 | from .plot_call import PlotQuibFuncCall
4 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/func_calls/known_graphics/plot_call.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.path.path_component import Path
2 | from pyquibbler.quib.func_calling import CachedQuibFuncCall
3 |
4 |
5 | class PlotQuibFuncCall(CachedQuibFuncCall):
6 |
7 | def _run_on_path(self, valid_path: Path):
8 | res = super(PlotQuibFuncCall, self)._run_on_path(valid_path)
9 | graphics_collection = self.graphics_collections[()]
10 | for i, artist in enumerate(graphics_collection.artists):
11 | artist._index_in_plot = i
12 |
13 | return res
14 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/func_calls/known_graphics/widgets/__init__.py:
--------------------------------------------------------------------------------
1 | from .slider_call import SliderQuibFuncCall, RangeSliderQuibFuncCall
2 | from .radio_buttons_call import RadioButtonsQuibFuncCall
3 | from .rectangle_selector_call import RectangleSelectorQuibFuncCall
4 | from .checkbuttons_call import CheckButtonsQuibFuncCall
5 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/func_calls/known_graphics/widgets/checkbuttons_call.py:
--------------------------------------------------------------------------------
1 | import functools
2 | from typing import Optional
3 |
4 | from matplotlib.widgets import CheckButtons
5 |
6 | from pyquibbler.path import PathComponent
7 | from .widget_call import WidgetQuibFuncCall
8 |
9 |
10 | class CheckButtonsQuibFuncCall(WidgetQuibFuncCall):
11 |
12 | @staticmethod
13 | def _get_control_variable() -> Optional[str]:
14 | return 'actives'
15 |
16 | def on_change_checkbuttons(self, widget, new_value):
17 | from pyquibbler.quib.quib import Quib
18 | actives = self.func_args_kwargs.get('actives')
19 | buttons_checked = widget.get_status()
20 | labels = self.func_args_kwargs.get('labels')
21 | new_value_index = labels.index(new_value)
22 | if isinstance(actives, Quib):
23 | self._inverse_assign(actives, [PathComponent(new_value_index)],
24 | value=buttons_checked[new_value_index])
25 | elif isinstance(actives[new_value_index], Quib):
26 | self._inverse_assign(actives[new_value_index], [],
27 | value=buttons_checked[new_value_index])
28 |
29 | def _connect_callbacks(self, widget: CheckButtons):
30 | widget.on_clicked(functools.partial(self.on_change_checkbuttons, widget))
31 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/func_calls/known_graphics/widgets/radio_buttons_call.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | from matplotlib.widgets import RadioButtons
4 |
5 | from pyquibbler.quib.func_calling.func_calls.known_graphics.widgets.widget_call import WidgetQuibFuncCall
6 |
7 |
8 | class RadioButtonsQuibFuncCall(WidgetQuibFuncCall):
9 |
10 | @staticmethod
11 | def _get_control_variable() -> Optional[str]:
12 | return 'active'
13 |
14 | def _on_clicked(self, new_value):
15 | from pyquibbler.quib.quib import Quib
16 | active = self.func_args_kwargs.get('active')
17 | if isinstance(active, Quib):
18 | self._inverse_assign(active, [], self.func_args_kwargs.get('labels').index(new_value))
19 |
20 | def _connect_callbacks(self, widget: RadioButtons):
21 | widget.on_clicked(self._on_clicked)
22 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/func_calls/known_graphics/widgets/textbox_call.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | from matplotlib.widgets import TextBox
4 |
5 | from pyquibbler.quib.quib import Quib
6 | from .widget_call import WidgetQuibFuncCall
7 |
8 |
9 | class TextBoxQuibFuncCall(WidgetQuibFuncCall):
10 |
11 | @staticmethod
12 | def _get_control_variable() -> Optional[str]:
13 | return 'initial'
14 |
15 | def _on_change(self, new_value: str):
16 | val = self.func_args_kwargs.get('initial')
17 | if isinstance(val, Quib):
18 | self._inverse_assign(val, [], new_value)
19 |
20 | def _connect_callbacks(self, widget: TextBox):
21 | widget.on_submit(self._on_change)
22 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/func_calls/vectorize/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/quib/func_calling/func_calls/vectorize/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/iquib_call.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from typing import Any, List, Union
4 |
5 | from pyquibbler.path import Path
6 | from pyquibbler.quib.func_calling import WholeValueNonGraphicQuibFuncCall
7 |
8 |
9 | class IQuibFuncCall(WholeValueNonGraphicQuibFuncCall):
10 | """
11 | Represents a FuncCall with identity function applied to a single argument with no quibs.
12 | No need to cache. Also no graphics.
13 | """
14 |
15 | @property
16 | def _value(self):
17 | return self.func_args_kwargs.get_arg_values_by_position()[0]
18 |
19 | def _run(self, valid_paths: List[Union[None, Path]]) -> Any:
20 | # func is identity_function, so we this will simply return the "value", which is the first argument:
21 | return self._value
22 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/func_calling/quiby_name_func_call.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from typing import Any, List, Union
4 |
5 | from pyquibbler.path import Path
6 | from pyquibbler.quib.func_calling.quib_func_call import WholeValueNonGraphicQuibFuncCall
7 |
8 |
9 | class QuibyNameFuncCall(WholeValueNonGraphicQuibFuncCall):
10 | """
11 | Represents a FuncCall that of a quiby_name quib: returning the name of its quib argument.
12 | """
13 |
14 | def _run(self, valid_paths: List[Union[None, Path]]) -> Any:
15 | # func is get_quib_name
16 | return self.func_args_kwargs.func(*self.func_args_kwargs.args, **self.func_args_kwargs.kwargs)
17 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/get_value_context_manager.py:
--------------------------------------------------------------------------------
1 | from contextlib import contextmanager
2 | from typing import Optional
3 |
4 | GET_VALUE_CONTEXT_PASS_QUIBS: Optional[bool] = None
5 |
6 |
7 | def reset_all_get_value_context():
8 | """
9 | Reset all global variables to their initial state
10 | """
11 | global GET_VALUE_CONTEXT_PASS_QUIBS
12 | GET_VALUE_CONTEXT_PASS_QUIBS = None
13 |
14 |
15 | def is_reset_all_get_value_context() -> bool:
16 | """
17 | Check if all the global variables are in their initial state
18 | """
19 | return GET_VALUE_CONTEXT_PASS_QUIBS is None
20 |
21 |
22 | @contextmanager
23 | def get_value_context(pass_quibs: bool = False):
24 | """
25 | Change IS_WITHIN_GET_VALUE_CONTEXT while in the process of running get_value.
26 | This has to be a static method as the IS_WITHIN_GET_VALUE_CONTEXT is a global state for all quib types
27 | """
28 | global GET_VALUE_CONTEXT_PASS_QUIBS
29 | if GET_VALUE_CONTEXT_PASS_QUIBS is not None:
30 | yield
31 | else:
32 | GET_VALUE_CONTEXT_PASS_QUIBS = pass_quibs
33 | try:
34 | yield
35 | finally:
36 | GET_VALUE_CONTEXT_PASS_QUIBS = None
37 |
38 |
39 | def is_within_get_value_context() -> bool:
40 | return GET_VALUE_CONTEXT_PASS_QUIBS is not None
41 |
42 |
43 | def get_value_context_pass_quibs() -> Optional[bool]:
44 | return GET_VALUE_CONTEXT_PASS_QUIBS
45 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/graphics/__init__.py:
--------------------------------------------------------------------------------
1 | from .graphics_update import GraphicsUpdateType
2 | from .redraw import aggregate_redraw_mode, redraw_quib_with_graphics_or_add_in_aggregate_mode
3 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/graphics/event_handling/__init__.py:
--------------------------------------------------------------------------------
1 | from .graphics_inverse_assigners import get_override_group_for_axes_plot, get_override_group_for_axes_scatter
2 | from .set_lim_inverse_assigner import get_override_group_for_axes_set_lim
3 | from .canvas_event_handler import CanvasEventHandler
4 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/graphics/graphics_assignment_mode.py:
--------------------------------------------------------------------------------
1 | from contextlib import contextmanager
2 | from typing import Optional
3 |
4 | from matplotlib.axes import Axes
5 |
6 | GRAPHICS_ASSIGNMENT_MODE_AXES: Optional[Axes] = None
7 |
8 |
9 | def reset_all_graphics_assignment_mode():
10 | """
11 | Resets the graphics assignment mode to its initial state.
12 | """
13 | global GRAPHICS_ASSIGNMENT_MODE_AXES
14 | GRAPHICS_ASSIGNMENT_MODE_AXES = None
15 |
16 |
17 | def is_reset_all_graphics_assignment_mode() -> bool:
18 | """
19 | Checks if the graphics assignment mode is in its initial state.
20 | """
21 | return GRAPHICS_ASSIGNMENT_MODE_AXES is None
22 |
23 |
24 | @contextmanager
25 | def graphics_assignment_mode(axes: Axes):
26 | """
27 | In graphics assignment mode. Indicating the axes invoking the assignment.
28 | """
29 |
30 | global GRAPHICS_ASSIGNMENT_MODE_AXES
31 | GRAPHICS_ASSIGNMENT_MODE_AXES = axes
32 | try:
33 | yield
34 | finally:
35 | GRAPHICS_ASSIGNMENT_MODE_AXES = None
36 |
37 |
38 | def get_graphics_assignment_mode_axes() -> Optional[Axes]:
39 | return GRAPHICS_ASSIGNMENT_MODE_AXES
40 |
41 |
42 | def is_within_graphics_assignment_mode() -> bool:
43 | return GRAPHICS_ASSIGNMENT_MODE_AXES is not None
44 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/graphics/graphics_update.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.utilities.basic_types import StrEnum
2 |
3 |
4 | class GraphicsUpdateType(StrEnum):
5 | """
6 | Options for specifying when to refresh a graphics quib.
7 |
8 | See Also
9 | --------
10 | pyquibbler.refresh_graphics, Quib.graphics_update
11 | """
12 |
13 | DRAG = 'drag'
14 | "Refresh immediately as graphics object are dragged (``'drag'``)."
15 |
16 | DROP = 'drop'
17 | "Refresh at end of dragging, upon mouse drop (``'drop'``)."
18 |
19 | CENTRAL = 'central'
20 | "Do not refresh automatically; only refresh upon explicit `refresh_graphics` command (``'central'``)."
21 |
22 | NEVER = 'never'
23 | "Do not refresh (``'never'``)."
24 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/pretty_converters/__init__.py:
--------------------------------------------------------------------------------
1 | from .math_expressions.math_expression import MathExpression
2 | from .math_expressions.simple_expressions import FailedMathExpression, NameMathExpression
3 | from .math_expressions.func_call_expression import FunctionCallMathExpression
4 | from .pretty_convert import get_math_expression_of_func_with_args_and_kwargs
5 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/pretty_converters/math_expressions/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/quib/pretty_converters/math_expressions/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/pretty_converters/math_expressions/call_method_expression.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 |
5 | from pyquibbler.utilities.general_utils import Args, Kwargs
6 | from .func_call_expression import FunctionCallMathExpression
7 | from ..math_precedence import MathPrecedence
8 |
9 | from typing import TYPE_CHECKING
10 | if TYPE_CHECKING:
11 | from pyquibbler.quib.specialized_functions.quiby_methods import CallObjectMethod
12 |
13 |
14 | @dataclass
15 | class CallMethodExpression(FunctionCallMathExpression):
16 |
17 | def get_str(self, with_spaces: bool = True):
18 | obj, *args = self.get_pretty_args()
19 | return f'{obj}.{self.func_name}({", ".join([*args, *self.get_pretty_kwargs()])})'
20 |
21 | @property
22 | def precedence(self) -> MathPrecedence:
23 | return MathPrecedence.SUBSCRIPTION
24 |
25 |
26 | def call_method_converter(func: CallObjectMethod, args: Args, kwargs: Kwargs) -> CallMethodExpression:
27 | return CallMethodExpression(func_name=func.method,
28 | args=args,
29 | kwargs=kwargs)
30 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/pretty_converters/math_expressions/getattr_expression.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 | from typing import Callable, Any
3 |
4 | from pyquibbler.utilities.general_utils import Args
5 | from .math_expression import MathExpression
6 | from ..math_precedence import MathPrecedence
7 |
8 |
9 | @dataclass
10 | class GetAttrExpression(MathExpression):
11 | obj: Any
12 | item: str
13 |
14 | def get_str(self, with_spaces: bool = True):
15 | return f"{self.obj}.{self.item}"
16 |
17 | @property
18 | def precedence(self) -> MathPrecedence:
19 | return MathPrecedence.SUBSCRIPTION
20 |
21 |
22 | def getattr_converter(func: Callable, args: Args) -> GetAttrExpression:
23 | obj, item = args
24 | return GetAttrExpression(obj, item)
25 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/pretty_converters/math_expressions/math_expression.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 | from pyquibbler.env import REPR_RETURNS_SHORT_NAME
4 | from ..math_precedence import MathPrecedence
5 |
6 |
7 | class MathExpression(ABC):
8 | def __str__(self):
9 | with REPR_RETURNS_SHORT_NAME.temporary_set(True):
10 | return self.get_str()
11 |
12 | def get_math_expression(self):
13 | return self
14 |
15 | @abstractmethod
16 | def get_str(self, with_spaces: bool = True):
17 | pass
18 |
19 | @property
20 | @abstractmethod
21 | def precedence(self) -> MathPrecedence:
22 | pass
23 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/pretty_converters/math_precedence.py:
--------------------------------------------------------------------------------
1 | import enum
2 |
3 |
4 | class MathPrecedence(enum.IntEnum):
5 | VAR_NAME = 20
6 | PARENTHESIS = 19
7 | FUNCTION_CALL = 18
8 | SLICING = 17
9 | SUBSCRIPTION = 16
10 | ATTRIBUTE = 15
11 | EXPONENTIATION = 14
12 | BITWISE_NOT = 13
13 | POSNEG = 12
14 | MULDIV = 11
15 | ADDSUB = 10
16 | BITWISE_SHIFT = 9
17 | BITWISE_AND = 8
18 | BITWISE_XOR = 7
19 | BITWISE_OR = 6
20 | COMPARISON = 5
21 | BOOL_NOT = 4
22 | BOOL_AND = 3
23 | BOOL_OR = 2
24 | LAMBDA = 1
25 | VAR_NAME_WITH_SPACES = 0
26 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/specialized_functions/__init__.py:
--------------------------------------------------------------------------------
1 | from .iquib import iquib
2 | from .proxy import proxy
3 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/specialized_functions/getattr.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 | from pyquibbler.exceptions import PyQuibblerException
4 | from pyquibbler.function_overriding.attribute_override import MethodOverride
5 | from pyquibbler.function_overriding.override_all import ATTRIBUTES_TO_ATTRIBUTE_OVERRIDES
6 | from pyquibbler.quib.specialized_functions.quiby_methods import QuibyMethod
7 |
8 |
9 | @dataclass
10 | class PyQuibblerAttributeError(PyQuibblerException, AttributeError):
11 | item: str
12 |
13 | def __str__(self):
14 | return f"Quib has no attribute {self.item}."
15 |
16 |
17 | def create_getattr_quib_or_quiby_method(quib, item):
18 | from pyquibbler.quib.factory import create_quib
19 |
20 | attribute_override = ATTRIBUTES_TO_ATTRIBUTE_OVERRIDES.get(item, None)
21 | if attribute_override is None:
22 | raise PyQuibblerAttributeError(item)
23 |
24 | if isinstance(attribute_override, MethodOverride):
25 | return QuibyMethod(quib, method_override=attribute_override)
26 | else:
27 | return create_quib(func=getattr,
28 | args=(quib, item),
29 | func_definition=attribute_override.func_definition)
30 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/specialized_functions/quiby_methods.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 | from pyquibbler.quib.quib import Quib
4 | from pyquibbler.function_definitions.func_definition import FuncDefinition
5 | from pyquibbler.function_overriding.attribute_override import MethodOverride
6 |
7 |
8 | @dataclass(frozen=True)
9 | class CallObjectMethod:
10 | method: str
11 | func_definition: FuncDefinition
12 |
13 | def __call__(self, *args, **kwargs):
14 | obj, *args = args
15 | return getattr(obj, self.method)(*args, **kwargs)
16 |
17 |
18 | @dataclass
19 | class QuibyMethod:
20 | quib: Quib
21 | method_override: MethodOverride
22 |
23 | def __call__(self, *args, **kwargs):
24 | """
25 | Create a function quib that calls the specified method of self.quib
26 | """
27 | from pyquibbler.quib.factory import create_quib
28 | return create_quib(func=CallObjectMethod(method=self.method_override.attribute,
29 | func_definition=self.method_override.func_definition),
30 | args=(self.quib, *args),
31 | kwargs=kwargs,
32 | )
33 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/types.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 | from dataclasses import dataclass
3 | from typing import Optional
4 |
5 | from pyquibbler.utilities.numpy_original_functions import np_array
6 |
7 |
8 | @dataclass
9 | class FileAndLineNumber:
10 | """
11 | Points to a specific line number within a specified file.
12 | """
13 |
14 | file_path: str
15 | line_no: Optional[int]
16 |
17 | def __repr__(self):
18 | return f'file: {self.file_path}, line={self.line_no}'
19 |
20 | def _repr_html_(self):
21 | return f'{self}'
22 |
23 |
24 | PointArray = np_array
25 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib/utils/__init__.py:
--------------------------------------------------------------------------------
1 | from .miscellaneous import deep_copy_without_quibs_or_graphics, is_there_a_quib_in_args
2 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib_network/__init__.py:
--------------------------------------------------------------------------------
1 | from .types import Direction
2 | from .quib_network import dependency_graph
3 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/quib_network/types.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.utilities.basic_types import StrEnum
2 |
3 |
4 | class Direction(StrEnum):
5 | """
6 | Define upstream/downstream directions in quib dependency graph.
7 |
8 | See Also
9 | --------
10 | dependency_graph
11 | """
12 |
13 | UPSTREAM = 'upstream'
14 | "Towards quibs affecting current quib (``'upstream'``)."
15 |
16 | DOWNSTREAM = 'downstream'
17 | "Towards quibs affected by current quib (``'downstream'``)."
18 |
19 | BOTH = 'both'
20 | "Towards both upstream and downstream directions (``'both'``)."
21 |
22 | ALL = 'all'
23 | "Fully explore the network from the current quib (``'all'``)."
24 |
25 |
26 | def reverse_direction(direction: Direction) -> Direction:
27 | if direction is Direction.UPSTREAM:
28 | return Direction.DOWNSTREAM
29 | if direction is Direction.DOWNSTREAM:
30 | return Direction.UPSTREAM
31 | return direction
32 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/reset_all.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.assignment.override_choice.types import reset_all_override_group, is_reset_all_override_group
2 | from pyquibbler.project.undo_group import reset_all_undo_group, is_reset_all_undo_group
3 | from pyquibbler.quib.get_value_context_manager import reset_all_get_value_context, is_reset_all_get_value_context
4 | from pyquibbler.quib.graphics.graphics_assignment_mode import reset_all_graphics_assignment_mode, \
5 | is_reset_all_graphics_assignment_mode
6 | from pyquibbler.quib.graphics.redraw import reset_all_redraw, is_reset_all_redraw
7 |
8 |
9 | def reset_all():
10 | """
11 | Reset all global variables to their initial state
12 | """
13 | reset_all_graphics_assignment_mode()
14 | reset_all_undo_group()
15 | reset_all_redraw()
16 | reset_all_override_group()
17 | reset_all_get_value_context()
18 |
19 |
20 | def is_reset_all():
21 | return is_reset_all_graphics_assignment_mode() \
22 | and is_reset_all_undo_group() \
23 | and is_reset_all_redraw() \
24 | and is_reset_all_override_group() \
25 | and is_reset_all_get_value_context()
26 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/type_translation/__init__.py:
--------------------------------------------------------------------------------
1 | from .translators import TypeTranslator
2 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/type_translation/run_conditions.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.utilities.multiple_instance_runner import RunCondition
2 |
3 |
4 | class TypeTranslateRunCondition(RunCondition):
5 | NO_ARGUMENTS_TYPES = 1
6 | WITH_ARGUMENTS_TYPES = 2
7 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/type_translation/translate.py:
--------------------------------------------------------------------------------
1 | from typing import Type, List, Optional
2 |
3 | from pyquibbler.utilities.multiple_instance_runner import MultipleInstanceRunner
4 | from pyquibbler.function_definitions.func_definition import FuncDefinition
5 |
6 | from .run_conditions import TypeTranslateRunCondition
7 |
8 |
9 | def translate_type(
10 | run_condition: TypeTranslateRunCondition,
11 | func_definition: FuncDefinition,
12 | data_arguments_types: Optional[List[Type]] = None) -> Optional[Type]:
13 | """
14 | Try getting the type of the quib value without evaluating the function.
15 | Return None if type cannot be calculated.
16 | """
17 | return MultipleInstanceRunner(run_condition=run_condition,
18 | runner_types=func_definition.result_type_or_type_translators,
19 | func_definition=func_definition, data_arguments_types=data_arguments_types).run()
20 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/type_translation/utils.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 | from typing import Type, Mapping
3 |
4 | from pyquibbler.exceptions import PyQuibblerException
5 | from pyquibbler.utilities.missing_value import missing
6 |
7 |
8 | @dataclass
9 | class CannotFindRepresentativeValueForType(PyQuibblerException):
10 | type_: Type
11 |
12 | def __str__(self):
13 | return f"cannot find representative value for type {self._type}"
14 |
15 |
16 | def get_representative_value_of_type(type_: Type):
17 | value = missing
18 | try:
19 | # important to start with scalar typing, because type(np.int64([])) is not np.int64
20 | value = type_(0)
21 | except TypeError:
22 | try:
23 | value = type_([])
24 | except TypeError:
25 | if issubclass(type_, Mapping):
26 | value = type_({})
27 |
28 | if type(value) is not type_:
29 | raise CannotFindRepresentativeValueForType(type_)
30 |
31 | return value
32 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/user_utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/user_utils/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/user_utils/gui_apps.py:
--------------------------------------------------------------------------------
1 | from .quibapp import QuibApp
2 |
3 |
4 | def quibapp():
5 | """
6 | Open the Quibbler App
7 |
8 | See Also
9 | --------
10 | Project
11 | """
12 | return QuibApp.get_or_create()
13 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/utilities/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/pyquibbler/pyquibbler/utilities/__init__.py
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/utilities/basic_types.py:
--------------------------------------------------------------------------------
1 | import contextlib
2 | from typing import Any
3 | from dataclasses import dataclass
4 | from enum import Enum
5 |
6 |
7 | class Singleton(object):
8 | """
9 | A base class for allowing only one instance
10 | """
11 | _instance = None
12 |
13 | def __new__(cls, *args, **kwargs):
14 | if not isinstance(cls._instance, cls):
15 | cls._instance = object.__new__(cls, *args, **kwargs)
16 | return cls._instance
17 |
18 |
19 | @dataclass
20 | class Mutable:
21 | val: Any
22 |
23 | def set(self, val: Any):
24 | self.val = val
25 |
26 | @contextlib.contextmanager
27 | def temporary_set(self, val):
28 | current = self.val
29 | self.set(val)
30 | try:
31 | yield
32 | finally:
33 | self.set(current)
34 |
35 |
36 | @dataclass
37 | class Flag(Mutable):
38 |
39 | def __bool__(self):
40 | return self.val
41 |
42 | def __eq__(self, other):
43 | return self.val == other
44 |
45 | def __ne__(self, other):
46 | return self.val != other
47 |
48 |
49 | class StrEnum(str, Enum):
50 | pass
51 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/utilities/file_path.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 |
3 |
4 | class PathWithHyperLink(type(pathlib.Path())):
5 | def _repr_html_(self):
6 | return f'{self.name}'
7 |
8 |
9 | class NotebookArchiveMirrorPath(PathWithHyperLink):
10 |
11 | name = '[Save in notebook]'
12 |
13 | def _repr_html_(self):
14 | return self.name
15 |
16 | def __repr__(self):
17 | return self.name
18 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/utilities/get_original_func.py:
--------------------------------------------------------------------------------
1 | from typing import Callable
2 |
3 |
4 | def get_original_func(func: Callable):
5 | """
6 | Get the original func- if this function is already overrided, get the original func it's function_definitions.
7 |
8 | So for example, if the OVERLOADED np.array is given as `func`, then the ORIGINAL np.array will be returned
9 | If the ORIGINAL np.array is given as `func`, then `func` will be returned
10 | """
11 | while hasattr(func, '__quibbler_wrapped__'):
12 | func = func.__quibbler_wrapped__
13 | return func
14 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/utilities/missing_value.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.utilities.basic_types import Singleton
2 |
3 |
4 | class Missing(Singleton):
5 | """
6 | Designates a missing value in a function call
7 | """
8 |
9 | def __repr__(self):
10 | return 'missing'
11 |
12 |
13 | missing = Missing()
14 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/utilities/numpy_original_functions.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | from pyquibbler.utilities.get_original_func import get_original_func
4 |
5 | np_logical_and = get_original_func(np.logical_and)
6 | np_logical_or = get_original_func(np.logical_or)
7 | np_cumsum = get_original_func(np.cumsum)
8 | np_sum = get_original_func(np.sum)
9 | np_all = get_original_func(np.all)
10 | np_any = get_original_func(np.any)
11 | np_full = get_original_func(np.full)
12 | np_ndarray = get_original_func(np.ndarray)
13 | np_array = get_original_func(np.array)
14 | np_log10 = get_original_func(np.log10)
15 | np_abs = get_original_func(np.abs)
16 | np_vectorize = get_original_func(np.vectorize)
17 | np_maximum = get_original_func(np.maximum)
18 | np_minimum = get_original_func(np.minimum)
19 | np_round = get_original_func(np.round)
20 | np_zeros = get_original_func(np.zeros)
21 | np_True = np.bool_(True)
22 | np_shape = get_original_func(np.shape)
23 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/utilities/operators_with_reverse.py:
--------------------------------------------------------------------------------
1 | import operator
2 | from typing import Callable
3 |
4 |
5 | def get_reversed_func(func: Callable):
6 | def _reversed(quib, obj):
7 | return func(obj, quib)
8 | _reversed.__name__ = f"{func.__name__}_reversed"
9 | _reversed.__qualname__ = f"{func.__name__}_reversed"
10 | return _reversed
11 |
12 |
13 | BINARY_OPERATOR_NAMES = [
14 | '__add__',
15 | '__sub__',
16 | '__mul__',
17 | '__matmul__',
18 | '__truediv__',
19 | '__floordiv__',
20 | '__mod__',
21 | '__pow__',
22 | '__and__',
23 | '__xor__',
24 | '__or__',
25 | '__lshift__',
26 | '__rshift__',
27 | ]
28 |
29 | REVERSE_OPERATOR_NAMES_TO_FUNCS = {}
30 |
31 | for func_name in BINARY_OPERATOR_NAMES:
32 | reversed_func_name = '__r' + func_name[2:]
33 | func = getattr(operator, func_name)
34 | REVERSE_OPERATOR_NAMES_TO_FUNCS[reversed_func_name] = get_reversed_func(func)
35 |
--------------------------------------------------------------------------------
/pyquibbler/pyquibbler/utilities/warning_messages.py:
--------------------------------------------------------------------------------
1 | import contextlib
2 | import warnings
3 | from typing import Tuple, Optional, Union
4 |
5 |
6 | def _no_header_formatwarning(msg, *args, **kwargs):
7 | return str(msg) + '\n'
8 |
9 |
10 | @contextlib.contextmanager
11 | def _no_header_warning():
12 | original_formatwarning = warnings.formatwarning
13 | warnings.formatwarning = _no_header_formatwarning
14 | yield
15 | warnings.formatwarning = original_formatwarning
16 |
17 |
18 | def no_header_warn(msg: Union[str, Tuple[str, ...]], add_frame: bool = False, once_only: bool = False):
19 | """
20 | Issue a bare warning message.
21 | Do not include in the warning a header with the file path.
22 | """
23 | if isinstance(msg, str):
24 | msg = (msg, )
25 | if add_frame:
26 | msg = create_frame(msg)
27 | msg = '\n'.join(msg)
28 | with _no_header_warning():
29 | if once_only:
30 | warnings.warn(msg)
31 | else:
32 | warnings.showwarning(msg, category=UserWarning, filename=None, lineno=None)
33 |
34 |
35 | def create_frame(message_lines: Tuple[str, ...], width: Optional[int] = None):
36 | if width is None:
37 | max_length = max(len(line) for line in message_lines)
38 | width = max_length + 4
39 |
40 | return (
41 | '-' * width,
42 | *('| ' + line + ' ' * (width - len(line) - 3) + '|' for line in message_lines),
43 | '-' * width,
44 | )
45 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
1 | # When this __init__ file is not present we get a warning when using pytest-cov
2 |
--------------------------------------------------------------------------------
/tests/functional/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/__init__.py
--------------------------------------------------------------------------------
/tests/functional/assignment/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/assignment/__init__.py
--------------------------------------------------------------------------------
/tests/functional/assignment/overriding_choice/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/assignment/overriding_choice/__init__.py
--------------------------------------------------------------------------------
/tests/functional/cache/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/cache/__init__.py
--------------------------------------------------------------------------------
/tests/functional/cache/test_shallow_cache.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 | import pytest
4 |
5 | from pyquibbler.cache.holistic_cache import HolisticCache, PathCannotHaveComponentsException
6 | from pyquibbler.path import PathComponent
7 | from tests.functional.cache.cache_test import CacheTest
8 |
9 |
10 | class TestShallowCache(CacheTest):
11 |
12 | cls = HolisticCache
13 |
14 | @pytest.fixture()
15 | def result(self):
16 | return 1
17 |
18 | def test_shallow_cache_matches_all(self, cache):
19 | assert cache.matches_result(object)
20 |
21 | def test_shallow_cache_does_not_allow_specifying_paths_in_invalidate(self, cache):
22 | with pytest.raises(PathCannotHaveComponentsException, match='.*'):
23 | cache.set_invalid_at_path([PathComponent(7)])
24 |
25 | def test_shallow_cache_does_not_allow_specifying_paths_in_set_valid(self, cache):
26 | with pytest.raises(PathCannotHaveComponentsException, match='.*'):
27 | cache.set_valid_value_at_path([PathComponent(7)], 1)
28 |
--------------------------------------------------------------------------------
/tests/functional/conftest.py:
--------------------------------------------------------------------------------
1 | from unittest.mock import Mock, MagicMock
2 |
3 | from pytest import fixture
4 |
5 |
6 | @fixture
7 | def function_mock_return_val():
8 | return [1, 2, 3, 4, 3, 2, 1]
9 |
10 |
11 | @fixture
12 | def function_mock(function_mock_return_val):
13 | func_mock = MagicMock(return_value=function_mock_return_val)
14 | func_mock.__name__ = 'func_mock'
15 | return func_mock
16 |
--------------------------------------------------------------------------------
/tests/functional/file_syncing/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/file_syncing/__init__.py
--------------------------------------------------------------------------------
/tests/functional/graphics/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/graphics/__init__.py
--------------------------------------------------------------------------------
/tests/functional/inversion/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/inversion/__init__.py
--------------------------------------------------------------------------------
/tests/functional/inversion/inverters/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/inversion/inverters/__init__.py
--------------------------------------------------------------------------------
/tests/functional/inversion/inverters/test_no_shape_elementwise_inverter.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 | from typing import Iterable
4 |
5 | from pyquibbler.path_translation.types import Source
6 | from tests.functional.inversion.inverters.utils import inverse
7 |
8 |
9 | @pytest.mark.parametrize("func,func_arg,indices,value,expected_value", [
10 | (np.log2, Source(np.array([4, 4, 4])), slice(None, None, None), 3, np.array([8, 8, 8])),
11 | (np.log2, Source(np.array([[4, 4], [4, 4]])), (0, slice(0, None, None)), 3, np.array([[8, 8], [4, 4]])),
12 | ], ids=[
13 | "log2: array[:]",
14 | "log2: array[0, 0:]",
15 | ])
16 | def test_inverse_elementwise_no_shape_single_argument(func, func_arg, indices, value, expected_value):
17 | sources_to_results, inversals = inverse(func, indices=indices, value=value, args=(func_arg,), empty_path=indices is None)
18 | assert inversals[0].assignment.path[0].component == indices
19 | value = sources_to_results[func_arg]
20 | if isinstance(expected_value, Iterable):
21 | assert np.array_equal(value, expected_value)
22 | else:
23 | assert value == expected_value
24 |
--------------------------------------------------------------------------------
/tests/functional/inversion/inverters/utils.py:
--------------------------------------------------------------------------------
1 | from typing import Callable, Any, Tuple, Mapping
2 |
3 | from pyquibbler import Assignment
4 | from pyquibbler.inversion.invert import invert
5 | from pyquibbler.path.data_accessing import deep_set
6 | from pyquibbler.utilities.get_original_func import get_original_func
7 | from pyquibbler.path_translation.source_func_call import SourceFuncCall
8 | from pyquibbler.path import PathComponent
9 |
10 |
11 | def inverse(func: Callable, indices: Any, value: Any, args: Tuple[Any, ...] = None, kwargs: Mapping[str, Any] = None,
12 | empty_path: bool = False, assignment: Assignment = None):
13 | func = get_original_func(func)
14 | if indices is not None and empty_path is True:
15 | raise Exception("The indices cannot be set if empty path is True")
16 |
17 | args = args or tuple()
18 | kwargs = kwargs or {}
19 | previous_value = SourceFuncCall.from_(func, args, kwargs).run()
20 | assignment = assignment or Assignment(path=[PathComponent(indices)] if not empty_path else [], value=value)
21 | inversals = invert(
22 | func_call=SourceFuncCall.from_(func, args, kwargs),
23 | previous_result=previous_value,
24 | assignment=assignment
25 | )
26 |
27 | return ({
28 | inversal.source: deep_set(inversal.source.value, inversal.assignment.path, inversal.assignment.value)
29 | for inversal in inversals
30 | },
31 | inversals)
32 |
33 |
--------------------------------------------------------------------------------
/tests/functional/inversion/test_invert.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 | import pytest
4 |
5 | from pyquibbler.inversion.invert import invert
6 | from pyquibbler.path_translation.source_func_call import SourceFuncCall
7 | from pyquibbler.utilities.multiple_instance_runner import NoRunnerWorkedException
8 |
9 |
10 | def test_invert_raises_exception_on_unknown_func():
11 | assignment = mock.Mock()
12 | assignment.is_default = mock.Mock(return_value=False)
13 |
14 | with pytest.raises(NoRunnerWorkedException, match='.*'):
15 | invert(
16 | func_call=SourceFuncCall.from_(func=mock.MagicMock(__name__='unknown'),
17 | func_args=tuple(),
18 | func_kwargs={},
19 | data_source_locations=[],
20 | parameter_source_locations=[]
21 | ),
22 | assignment=assignment,
23 | previous_result=0
24 | )
25 |
--------------------------------------------------------------------------------
/tests/functional/path/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/path/__init__.py
--------------------------------------------------------------------------------
/tests/functional/path/test_hashable.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from pyquibbler.path import PathComponent, get_hashable_path
5 |
6 |
7 | @pytest.mark.parametrize("components_in_path", [
8 | [slice(None, None, None)],
9 | [np.array([1, 2, 3]), np.array([1, 2, 3])],
10 | [(np.array([1, 2, 3]), np.array([1, 2, 3]))],
11 | [np.array([1, 2, 3])],
12 | [([slice(None, None, None)],)],
13 | ])
14 | def test_hash_path(components_in_path):
15 | path = [PathComponent(c) for c in components_in_path]
16 |
17 | # Make sure we don't raise an exception
18 | hash(get_hashable_path(path))
19 |
--------------------------------------------------------------------------------
/tests/functional/quib/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib/__init__.py
--------------------------------------------------------------------------------
/tests/functional/quib/assignment/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib/assignment/__init__.py
--------------------------------------------------------------------------------
/tests/functional/quib/assignment/test_assignments.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from pyquibbler import iquib
5 | from pyquibbler.assignment import AssignmentWithTolerance
6 | from pyquibbler.path import PathComponent
7 |
8 |
9 | def test_assignment_do_not_change_each_other():
10 | a = iquib([1, 2])
11 | a.assign([10, 20, 30])
12 | a[1] = 21
13 | assert a.handler.overrider.get([]).value == [10, 20, 30], "sanity"
14 | a.get_value()
15 |
16 | assert a.handler.overrider.get([]).value == [10, 20, 30]
17 |
18 |
19 | @pytest.mark.parametrize(['x0', 'a', 'b', 'new_y', 'new_dy', 'component', 'expected'], [
20 | (10., 1., 0., 10.123456, 0.005, [], 10.12),
21 | (10., 1., 10., 10.123456, 0.005, [], 0.12),
22 | (10., 0.1, 0., 10.123456, 0.005, [], 101.2),
23 | (10., 10., 0., 10.123456, 0.005, [], 1.012),
24 | (np.array([10., 20.]), 10., 0., 10.123456, 0.005, 0, 1.012),
25 | ])
26 | def test_assignment_with_tolerance(x0, a, b, new_y, new_dy, component, expected):
27 | x = iquib(x0)
28 | y = a * x + b
29 |
30 | assignment = AssignmentWithTolerance.from_value_path_tolerance(
31 | value=new_y,
32 | path=[] if component == [] else [PathComponent(component)],
33 | tolerance=new_dy)
34 |
35 | y.handler.apply_assignment(assignment)
36 | assert x.handler.overrider.get(assignment.path).value == expected
37 |
--------------------------------------------------------------------------------
/tests/functional/quib/conftest.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 | import numpy as np
4 | import pytest
5 |
6 | from pyquibbler.quib.quib import Quib, QuibHandler
7 |
8 |
9 | @pytest.fixture()
10 | def create_mock_quib():
11 | def _create(shape=None, get_value_result=None, children=None):
12 | shape = shape or (3, 1)
13 | get_value_result = get_value_result or [[1, 2, 3]]
14 | mock_quib = mock.Mock(spec=Quib)
15 | mock_quib.get_value_valid_at_path.return_value = get_value_result
16 | mock_quib.get_shape.return_value = shape
17 | mock_quib.get_ndim.return_value = len(shape)
18 | mock_quib.handler = mock.Mock(spec=QuibHandler)
19 | mock_quib.handler.quib_function_call = mock.Mock()
20 | mock_quib.handler.quib_function_call.result_shape = np.shape(get_value_result)
21 | mock_quib.handler.quib_function_call.result_type = type(get_value_result)
22 | mock_quib.handler.get_figures.return_value = []
23 | mock_quib.pass_quibs = False
24 | mock_quib.is_proxy = False
25 | mock_quib.get_descendants.return_value = children or set()
26 | return mock_quib
27 | return _create
28 |
29 |
30 | @pytest.fixture()
31 | def mock_axes():
32 | axes = mock.Mock()
33 | axes.figure.canvas.supports_blit = False
34 | axes._children = []
35 | return axes
36 |
--------------------------------------------------------------------------------
/tests/functional/quib/graphics/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib/graphics/__init__.py
--------------------------------------------------------------------------------
/tests/functional/quib/graphics/event_handling/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib/graphics/event_handling/__init__.py
--------------------------------------------------------------------------------
/tests/functional/quib/quib_widget/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib/quib_widget/__init__.py
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib/test_quib/__init__.py
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/get_value/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib/test_quib/get_value/__init__.py
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/get_value/conftest.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from pyquibbler.quib.factory import create_quib
3 | from pyquibbler.quib.quib import Quib
4 | from pyquibbler.quib.specialized_functions.iquib import identity_function
5 | from pyquibbler import CacheMode
6 | import numpy as np
7 |
8 | @pytest.fixture()
9 | def uncached_array_quib() -> Quib:
10 | return create_quib(func=identity_function, args=(np.arange(6),),
11 | allow_overriding=True,
12 | lazy=False,
13 | cache_mode=CacheMode.OFF,
14 | )
15 |
16 | @pytest.fixture()
17 | def uncached_scalar_quib() -> Quib:
18 | return create_quib(func=identity_function, args=(3,),
19 | allow_overriding=True,
20 | lazy=False,
21 | cache_mode=CacheMode.OFF,
22 | )
23 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/get_value/test_axiswise.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from pyquibbler.path import PathComponent
5 | from tests.functional.quib.test_quib.get_value.test_apply_along_axis import parametrize_data
6 | from tests.functional.quib.test_quib.get_value.utils import check_get_value_valid_at_path
7 |
8 |
9 | @parametrize_data
10 | @pytest.mark.parametrize(['axis', 'indices_to_get_value_at'], [
11 | (-1, 0),
12 | (2, (0, 0)),
13 | ])
14 | def test_axiswise_get_value_valid_at_path(axis, data, indices_to_get_value_at):
15 | path_to_get_value_at = [PathComponent(indices_to_get_value_at)]
16 | check_get_value_valid_at_path(lambda quib: np.sort(quib, axis=axis), data, path_to_get_value_at)
17 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/get_value/test_iquib.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from pytest import mark
3 |
4 | from pyquibbler import iquib
5 | from pyquibbler.path import PathComponent
6 |
7 |
8 | @mark.regression
9 | def test_get_partial_value_of_a_list_iquib_with_boolean_indexing():
10 | value = [[1, 2], [3, 4]]
11 | a = iquib(value)
12 |
13 | index = np.array([[0, 1], [0, 0]], dtype=bool)
14 | partial_value = a.get_value_valid_at_path([PathComponent(index)])
15 |
16 | assert partial_value[0][1] == value[0][1]
17 |
18 |
19 | @mark.regression
20 | def test_array_of_iquib_list():
21 | value = [[1, 2], [3, 4]]
22 | a = iquib(value)
23 |
24 | index = np.array([[0, 1], [0, 0]], dtype=bool)
25 | b = np.array(a)
26 | c = b[index]
27 |
28 | assert c.get_value() == np.array(value)[index]
29 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/get_value/test_list_operatos.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib/test_quib/get_value/test_list_operatos.py
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/get_value/test_minor_sources.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from pyquibbler import iquib
5 |
6 |
7 | @pytest.mark.regression
8 | def test_array_with_quib_inner_source():
9 | a = iquib([1])
10 | b = np.array([a])
11 |
12 | assert b.get_value() == np.array([[1]])
13 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/get_value/test_proxy.py:
--------------------------------------------------------------------------------
1 | from pyquibbler.path.path_component import PathComponent
2 | from pyquibbler.quib.specialized_functions.proxy import create_proxy
3 | from tests.functional.quib.test_quib.get_value.utils import collecting_quib
4 |
5 |
6 | def test_proxy_get_value():
7 | val = [1, 2, 3]
8 | path_collector_quib = collecting_quib(val)
9 | proxy = create_proxy(path_collector_quib)
10 |
11 | with path_collector_quib.collect_valid_paths() as valid_paths:
12 | res = proxy.get_value_valid_at_path([PathComponent(0)])
13 |
14 | assert valid_paths == [[PathComponent(0)]]
15 | assert res == val
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/invalidation/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib/test_quib/invalidation/__init__.py
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/invalidation/test_accumulation.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from tests.functional.quib.test_quib.get_value.test_apply_along_axis import parametrize_indices_to_invalidate, \
5 | parametrize_data
6 | from tests.functional.quib.test_quib.invalidation.utils import check_invalidation
7 |
8 |
9 | @parametrize_indices_to_invalidate
10 | @parametrize_data
11 | @pytest.mark.parametrize('axis', [-1, 0, 1, 2, None])
12 | def test_accumulation_axiswise_invalidation(indices_to_invalidate, axis, data):
13 | check_invalidation(lambda quib: np.cumsum(quib, axis=axis), data, indices_to_invalidate)
14 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/invalidation/test_apply_along_axis.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from tests.functional.quib.test_quib.get_value.test_apply_along_axis import parametrize_indices_to_invalidate, \
5 | parametrize_data, parametrize_path_to_invalidate
6 | from tests.functional.quib.test_quib.invalidation.utils import check_invalidation
7 |
8 |
9 | @parametrize_indices_to_invalidate
10 | @parametrize_data
11 | @pytest.mark.parametrize('axis', [0, 1, 2, -1, -2])
12 | @pytest.mark.parametrize('func_out_dims', [0, 1, 2])
13 | def test_apply_along_axis_invalidation_(indices_to_invalidate, axis, func_out_dims, data):
14 | func1d = lambda slice: np.sum(slice).reshape((1,) * func_out_dims)
15 | check_invalidation(lambda quib: np.apply_along_axis(func1d, axis, quib), data, indices_to_invalidate)
16 |
17 |
18 | @parametrize_path_to_invalidate
19 | @parametrize_data
20 | def test_apply_along_axis_invalidation_list(path_to_invalidate, data, axis=0, func_out_dims=0):
21 | data = data.tolist()
22 | func1d = lambda slice: np.sum(slice).reshape((1,) * func_out_dims)
23 | check_invalidation(lambda quib: np.apply_along_axis(func1d, axis, quib), data, path_to_invalidate)
24 |
25 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/invalidation/test_list_operators.py:
--------------------------------------------------------------------------------
1 | from pyquibbler import iquib, CacheStatus
2 |
3 |
4 | def test_list_addition():
5 | a = iquib([10, 20, 30])
6 | b = (a + [40, 50]).setp(cache_mode='on')
7 | b0 = b[0]
8 | b1 = b[1]
9 | b2 = b[2]
10 |
11 | b0.get_value()
12 | b1.get_value()
13 | b2.get_value()
14 |
15 | assert b.get_value() == [10, 20, 30, 40, 50]
16 | a[1] = 21
17 | assert b.get_value() == [10, 21, 30, 40, 50]
18 |
19 | assert b0.cache_status == CacheStatus.ALL_VALID
20 | assert b1.cache_status == CacheStatus.ALL_INVALID
21 | assert b2.cache_status == CacheStatus.ALL_VALID
22 |
23 |
24 | def test_list_multiplication():
25 | a = iquib([10, 20, 30])
26 | n = iquib(3)
27 | b = (n * a).setp(cache_mode='on')
28 |
29 | assert b.get_value() == [10, 20, 30, 10, 20, 30, 10, 20, 30]
30 |
31 | b0 = b[0]
32 | b1 = b[1]
33 | b4 = b[4]
34 |
35 | b0.get_value()
36 | b1.get_value()
37 | b4.get_value()
38 |
39 | a[1] = 21
40 | assert b.get_value() == [10, 21, 30, 10, 21, 30, 10, 21, 30]
41 |
42 | assert b0.cache_status == CacheStatus.ALL_VALID
43 | assert b1.cache_status == CacheStatus.ALL_INVALID
44 | assert b4.cache_status == CacheStatus.ALL_INVALID
45 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/invalidation/test_proxy.py:
--------------------------------------------------------------------------------
1 | from pyquibbler import iquib
2 | from pyquibbler.cache.cache import CacheStatus
3 | from pyquibbler.quib.specialized_functions.proxy import create_proxy
4 |
5 |
6 | def test_proxy_never_invalidates():
7 | arg = iquib([100])
8 | proxy = create_proxy(arg)
9 | child = proxy[0]
10 | child.get_value()
11 |
12 | arg.handler.invalidate_and_aggregate_redraw_at_path([])
13 |
14 | assert child.cache_status == CacheStatus.ALL_VALID
15 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/invalidation/test_reduction.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from pyquibbler import iquib
5 | from pyquibbler.cache import CacheStatus
6 | from tests.functional.quib.test_quib.get_value.test_apply_along_axis import parametrize_indices_to_invalidate, \
7 | parametrize_data, parametrize_keepdims, parametrize_where
8 | from tests.functional.quib.test_quib.invalidation.utils import check_invalidation
9 |
10 |
11 | @parametrize_indices_to_invalidate
12 | @parametrize_data
13 | @pytest.mark.parametrize('axis', [-1, (-1, 1), 0, 1, 2, (0, 2), (0, 1), None])
14 | @parametrize_keepdims
15 | @parametrize_where
16 | def test_reduction_axiswise_invalidation(indices_to_invalidate, axis, keepdims, where, data):
17 | kwargs = dict(axis=axis)
18 | if keepdims is not None:
19 | kwargs['keepdims'] = keepdims
20 | if where is not None:
21 | kwargs['where'] = where
22 | check_invalidation(lambda quib: np.sum(quib, **kwargs), data, indices_to_invalidate)
23 |
24 |
25 | @pytest.mark.regression
26 | def test_sum_invalidation():
27 | z = iquib(np.array([3, 1, 2]))
28 | sum_z = np.sum(z).setp(cache_mode='on')
29 | sum_z.get_value()
30 | assert sum_z.cache_status == CacheStatus.ALL_VALID, "Sanity"
31 |
32 | z[1] = 0
33 |
34 | assert sum_z.cache_status == CacheStatus.ALL_INVALID
35 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/pretty_repr/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib/test_quib/pretty_repr/__init__.py
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/pretty_repr/test_overrider.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from pyquibbler.quib.specialized_functions.iquib import iquib
5 |
6 |
7 | @pytest.mark.parametrize("assignments", [
8 | ["a[1] = 3"],
9 | ["a[:, 0] = 1"],
10 | ["a[0] = 1", "a[0, 1] = 2"]
11 | ])
12 | @pytest.mark.get_variable_names(True)
13 | def test_overrider_pretty_repr_array_assignments(assignments):
14 | data = np.array([[1, 2, 3]])
15 | a = iquib(data)
16 | for assignment in assignments:
17 | exec(assignment)
18 | expected = "a = iquib(array([[1, 2, 3]]))" + f"\n" + f"\n".join(assignments)
19 | assert repr(a) == expected
20 |
21 | @pytest.mark.parametrize("assignments", [
22 | ["a['name'] = 'Wow'"],
23 | ["a['short_name'] = 'quib'"],
24 | ["a['numbers'] = [1, 2, 3]", "a['numbers'][1] = 20"],
25 | ])
26 | @pytest.mark.get_variable_names(True)
27 | def test_overrider_pretty_repr_dict_assignments(assignments):
28 | data = {'name': 'Quibbler'}
29 | a = iquib(data)
30 | for assignment in assignments:
31 | exec(assignment)
32 | expected = "a = iquib({'name': 'Quibbler'})" + f"\n" + f"\n".join(assignments)
33 | assert repr(a) == expected
34 |
35 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/pretty_repr/test_vectorize.py:
--------------------------------------------------------------------------------
1 | import functools
2 |
3 | import numpy as np
4 | import pytest
5 |
6 | from pyquibbler import iquib
7 | from pyquibbler.env import PRETTY_REPR
8 |
9 |
10 | def test_qvectorize_pretty_repr():
11 | @np.vectorize
12 | def my_func():
13 | pass
14 |
15 | with PRETTY_REPR.temporary_set(True):
16 | assert repr(my_func) == "np.vectorize(my_func)"
17 |
18 |
19 | @pytest.fixture
20 | def signature():
21 | return '(w,h,c),(x)->(w2,h2,c)'
22 |
23 |
24 | @pytest.fixture
25 | def vectorized_func_with_signature(signature):
26 | @functools.partial(np.vectorize, signature=signature)
27 | def my_func():
28 | pass
29 |
30 | return my_func
31 |
32 |
33 | def test_qvectorize_pretty_repr_with_signature(vectorized_func_with_signature, signature):
34 | with PRETTY_REPR.temporary_set(True):
35 | assert repr(vectorized_func_with_signature) == f"np.vectorize(my_func, {signature})"
36 |
37 |
38 | @pytest.mark.get_variable_names(True)
39 | def test_vectorize_pretty_repr(vectorized_func_with_signature, signature):
40 | a = iquib("pasten")
41 | b = iquib(np.array([42, 42, 42]))
42 | quib = vectorized_func_with_signature(a, b)
43 |
44 | with PRETTY_REPR.temporary_set(True):
45 | assert quib.pretty_repr == f"quib = np.vectorize(my_func, {signature})(a, b)"
46 |
47 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/test_array_operator_quib.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from pyquibbler import iquib, Quib
5 | from pyquibbler.quib.exceptions import QuibsShouldPrecedeException
6 |
7 |
8 | def test_add_array_and_quib():
9 | w = iquib(10)
10 | a = np.array([1, 2, 3])
11 | wa = w + a
12 | assert isinstance(wa, Quib), "sanity"
13 | with pytest.raises(QuibsShouldPrecedeException, match='.*'):
14 | aw = a + w
15 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/test_assign_default.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | import pytest
4 |
5 | from pyquibbler import iquib, q, default
6 | from pyquibbler.quib.quib import Quib
7 |
8 |
9 | def test_default_repr():
10 | assert repr(default) == 'default'
11 |
12 |
13 | def test_quib_assign_default(create_quib_with_return_value):
14 | a = create_quib_with_return_value(np.array([1, 2, 3]), allow_overriding=False)
15 | b = (a + 10).setp(allow_overriding=True)
16 |
17 | b.assign(0, 1)
18 | assert np.array_equal(b.get_value(), [11, 0, 13]), "sanity"
19 | b.assign(default)
20 | assert np.array_equal(b.get_value(), [11, 12, 13])
21 |
22 |
23 | @pytest.mark.parametrize(['item', 'value', 'expected_before_removal', 'item_removal', 'expected_after_removal'], [
24 | (1, 0, [11, 0, 13], 0, [11, 0, 13]),
25 | (1, 0, [11, 0, 13], 1, [11, 12, 13]),
26 | (1, 0, [11, 0, 13], slice(0, 2), [11, 12, 13]),
27 | (2, 0, [11, 12, 0], slice(0, 2), [11, 12, 0]),
28 | ])
29 | def test_quib_setitem_default(create_quib_with_return_value, item, value, expected_before_removal,
30 | item_removal, expected_after_removal):
31 | a = create_quib_with_return_value(np.array([1, 2, 3]), allow_overriding=False)
32 | b = (a + 10).setp(allow_overriding=True)
33 |
34 | b[item] = value
35 | assert np.array_equal(b.get_value(), expected_before_removal)
36 |
37 | b[item_removal] = default
38 | assert np.array_equal(b.get_value(), expected_after_removal)
39 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/test_cache_behavior.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 | import pytest
4 |
5 | from pyquibbler.function_definitions import add_definition_for_function
6 | from pyquibbler.function_definitions.func_definition import FuncDefinition
7 | from pyquibbler.utilities.input_validation_utils import InvalidArgumentTypeException, UnknownEnumException
8 | from pyquibbler.quib.func_calling.cache_mode import CacheMode
9 | from pyquibbler.quib.factory import create_quib
10 |
11 |
12 | def test_quib_set_cache_behaviour_forces_correct_type(quib):
13 | with pytest.raises(InvalidArgumentTypeException, match='.*'):
14 | quib.cache_mode = 1
15 |
16 |
17 | def test_quib_setp(quib):
18 | quib.setp(cache_mode='off')
19 |
20 | assert quib.cache_mode == CacheMode.OFF
21 |
22 |
23 | def test_quib_setp_with_invalid_cache_mode(quib):
24 | with pytest.raises(UnknownEnumException, match='.*'):
25 | quib.setp(cache_mode='ondfdd')
26 |
27 |
28 | @pytest.fixture()
29 | def random_quib():
30 | func = mock.Mock()
31 | add_definition_for_function(func=func, func_definition=FuncDefinition(is_random=True))
32 | return create_quib(func=func)
33 |
34 |
35 | def test_can_set_quib_cache_mode_to_on_when_random(random_quib):
36 | random_quib.cache_mode = CacheMode.ON
37 |
38 |
39 | def test_quib_cache_mode_on_by_default_when_is_random(random_quib):
40 | assert random_quib.cache_mode == CacheMode.ON
41 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/test_display_props.py:
--------------------------------------------------------------------------------
1 | from pyquibbler import iquib
2 |
3 |
4 | def test_display_properties_of_iquib():
5 | a = iquib(0)
6 | a.display_properties().get_html_repr()
7 | a.display_properties().get_text_repr()
8 |
9 |
10 | def test_display_properties_of_fquib():
11 | a = iquib(0)
12 | b = a + 1
13 | a.display_properties().get_html_repr()
14 | a.display_properties().get_text_repr()
15 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/test_functions_returning_array_view.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | import numpy as np
4 | from pyquibbler import iquib, quiby, CacheStatus
5 |
6 |
7 | @pytest.mark.regression
8 | def test_assignment_into_array_view():
9 | a = iquib(np.array([0, 0]))
10 | b = np.ravel(a).setp(cache_mode='on')
11 | b.get_value()
12 |
13 | a[0] = 7
14 | assert a.args[0][0] == 0, "sanity"
15 |
16 | b.get_value()
17 | assert a.args[0][0] == 0
18 |
19 |
20 | @pytest.mark.regression
21 | def test_view_should_be_able_to_cache():
22 | @quiby
23 | def get_a_view():
24 | # this simulates functions like np.genfromtxt which returns a view
25 | # of an internal array they create
26 | # when this bug exists we get very slow dragging in `quibdemo_fit_stock`
27 | return np.ravel(np.array([1, 2, 3]))
28 |
29 | view_quib = get_a_view()
30 | view_quib.cache_mode = 'on'
31 | view_quib.get_value()
32 |
33 | assert view_quib.cache_status == CacheStatus.ALL_VALID
34 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/test_getattr.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from pyquibbler import iquib
5 | from pytest import fixture
6 |
7 | from pyquibbler.quib.specialized_functions.getattr import PyQuibblerAttributeError
8 |
9 |
10 | @fixture
11 | def array_value():
12 | return np.array([[1, 2, 3]])
13 |
14 |
15 | @fixture
16 | def quib(array_value):
17 | a = iquib(array_value, assigned_name='a')
18 | return a
19 |
20 |
21 | @fixture
22 | def quib_T(quib):
23 | return quib.T
24 |
25 |
26 | def test_getattr_T_get_value(quib, quib_T):
27 | assert np.array_equal(quib.get_value().T, quib_T.get_value())
28 |
29 |
30 | def test_getattr_T_inverse(quib, quib_T):
31 | quib_T[2, 0] = 10
32 | assert np.array_equal(quib.get_value(), [[1, 2, 10]])
33 |
34 |
35 | def test_getattr_T_invalidate(quib, quib_T):
36 | quib_T.get_value()
37 | quib[0, 1] = 10
38 | assert np.array_equal(quib_T.handler.quib_function_call.cache._invalid_mask, [[False], [True], [False]])
39 |
40 |
41 | def test_getattr_T_repr(quib, quib_T):
42 | assert repr(quib_T) == 'a.T'
43 |
44 |
45 | def test_getattr_raises_on_wrong_attr(quib):
46 | with pytest.raises(PyQuibblerAttributeError, match='wrong_attr'):
47 | quib.wrong_attr
48 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/test_list_operator_inveral.py:
--------------------------------------------------------------------------------
1 | from pyquibbler import iquib
2 |
3 |
4 | def test_list_addition_inversal():
5 | a = iquib([10, 20, 30])
6 | b = iquib([40, 50])
7 | ab = a + b
8 |
9 | assert ab.get_value() == [10, 20, 30, 40, 50]
10 | ab[1] = 21
11 |
12 | assert a.get_value() == [10, 21, 30]
13 | assert ab.get_value() == [10, 21, 30, 40, 50]
14 |
15 |
16 | def test_list_multiplication_inversal():
17 | a = iquib([10, 20, 30])
18 | n = iquib(4)
19 | c = n * a
20 |
21 | assert c.get_value() == 4 * [10, 20, 30]
22 | c[4] = 100
23 |
24 | assert a.get_value() == [10, 100, 30]
25 | assert c.get_value() == 4 * [10, 100, 30]
26 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_quib/test_quib_creation.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from matplotlib import pyplot as plt
3 |
4 | from pyquibbler import iquib, Quib
5 | from pyquibbler.env import ALLOW_ARRAY_WITH_DTYPE_OBJECT
6 |
7 |
8 | def test_allow_array_with_dtype_object_off():
9 | a = iquib(1)
10 | with ALLOW_ARRAY_WITH_DTYPE_OBJECT.temporary_set(False):
11 | assert isinstance(np.array([a], dtype=object), np.ndarray)
12 |
13 |
14 | def test_allow_array_with_dtype_object_on():
15 | a = iquib(1)
16 | with ALLOW_ARRAY_WITH_DTYPE_OBJECT.temporary_set(True):
17 | assert isinstance(np.array([a], dtype=object), Quib)
18 |
19 |
20 | def test_plot_quib_converts_quib_containing_args_to_quib_arrays():
21 | a = iquib(1)
22 | b = plt.plot([0, a, 2])
23 | arg = b.args[1]
24 | assert isinstance(arg, Quib) and np.array_equal(arg.get_value(), [0, 1, 2])
25 |
--------------------------------------------------------------------------------
/tests/functional/quib/test_uninitiated.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyquibbler import iquib, quiby, q, is_quiby, Quib
4 | from pyquibbler.function_overriding.is_initiated import IS_QUIBBLER_INITIATED
5 |
6 |
7 | def test_iquib_does_not_create_quib_when_uninitiated():
8 | with IS_QUIBBLER_INITIATED.temporary_set(False):
9 | with pytest.warns(UserWarning):
10 | quib = iquib(3)
11 | assert not isinstance(quib, Quib) and quib == 3
12 | quib = iquib(3)
13 | assert isinstance(quib, Quib) and quib.get_value() == 3, "sanity"
14 |
15 |
16 | def test_quiby_does_not_create_quiby_func_when_uninitiated():
17 | with IS_QUIBBLER_INITIATED.temporary_set(False):
18 | with pytest.warns(UserWarning):
19 | quiby_str = quiby(str)
20 | with pytest.warns(UserWarning):
21 | assert not is_quiby(quiby_str)
22 | quiby_str = quiby(str)
23 | assert is_quiby(quiby_str), "sanity"
24 |
25 |
26 | def test_q_does_not_create_quib_when_uninitiated():
27 | with IS_QUIBBLER_INITIATED.temporary_set(False):
28 | with pytest.warns(UserWarning):
29 | quib = q(str, 3)
30 | assert not isinstance(quib, Quib) and quib == '3'
31 | quib = q(str, 3)
32 | assert isinstance(quib, Quib) and quib.get_value() == '3'
33 |
--------------------------------------------------------------------------------
/tests/functional/quib_network/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/quib_network/__init__.py
--------------------------------------------------------------------------------
/tests/functional/quib_network/test_quib_network_without_ipywidgets.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyquibbler.optional_packages.exceptions import MissingPackagesForFunctionException
4 |
5 |
6 | # def test_dependency_graph_exception_with_no_ipywidget():
7 | # with pytest.raises(MissingPackagesForFunctionException, match='.*'):
8 | # from pyquibbler.quib_network.quib_network import dependency_graph
9 |
--------------------------------------------------------------------------------
/tests/functional/test_project_wraps.py:
--------------------------------------------------------------------------------
1 |
2 | import pyquibbler as qb
3 |
4 |
5 | def test_get_project(project):
6 | assert qb.get_project() is project
7 |
8 |
9 | def test_get_set_project_directory():
10 | qb.set_project_directory(None)
11 | assert qb.get_project_directory() is None
12 |
13 |
--------------------------------------------------------------------------------
/tests/functional/test_utils.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 | import pytest
4 | import numpy as np
5 |
6 | from pyquibbler.utilities.decorators import ensure_only_run_once_globally
7 | from pyquibbler.utilities.general_utils import get_shared_shape
8 |
9 |
10 | def test_ensure_run_once_globally_runs_once():
11 | global_func = mock.Mock()
12 |
13 | wrapped_func = ensure_only_run_once_globally(global_func)
14 | res = wrapped_func()
15 | wrapped_func()
16 |
17 | global_func.assert_called_once()
18 | assert res == global_func.return_value
19 |
20 |
21 | @pytest.mark.parametrize('shapes, expected', [
22 | [[(2, 3), (2, 3)], (2, 3)],
23 | [[(2, 3), (2, 4)], (2,)],
24 | [[(2, 3), ], (2, 3)],
25 | [[(1, 3), (2, 3)], tuple()],
26 | [[], tuple()],
27 | ])
28 | def test_get_shared_shape(shapes, expected):
29 | assert get_shared_shape([np.zeros(shape) for shape in shapes]) == expected
30 |
--------------------------------------------------------------------------------
/tests/functional/third_party_overriding/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/functional/third_party_overriding/__init__.py
--------------------------------------------------------------------------------
/tests/functional/third_party_overriding/conftest.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 | import pytest
4 |
5 | from pyquibbler import Quib
6 | from pyquibbler.quib.factory import create_quib
7 |
8 |
9 | @pytest.fixture()
10 | def quib() -> Quib:
11 | return create_quib(func=mock.Mock())
12 |
13 |
14 | @pytest.fixture
15 | def mock_module():
16 | mdl = mock.Mock()
17 | mdl.__name__ = 'MockModule'
18 | return mdl
19 |
20 | @pytest.fixture
21 | def func_name_to_override():
22 | return "hello_my_good_good_friend"
23 |
24 |
25 | @pytest.fixture
26 | def func_mock_on_module(mock_module, func_name_to_override):
27 | return getattr(mock_module, func_name_to_override)
28 |
29 |
30 | @pytest.fixture()
31 | def overridden_func(mock_module, func_name_to_override):
32 | return lambda *a: getattr(mock_module, func_name_to_override)(*a)
33 |
--------------------------------------------------------------------------------
/tests/functional/third_party_overriding/test_graphics_definition.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyquibbler.env import GRAPHICS_LAZY
4 | from pyquibbler.function_overriding.third_party_overriding.matplotlib.helpers import graphics_override
5 |
6 |
7 | @pytest.fixture(autouse=True)
8 | def graphics_definition(mock_module, func_name_to_override, func_mock_on_module):
9 | definition = graphics_override(func_name=func_name_to_override, module_or_cls=mock_module)
10 | definition.override()
11 | return definition
12 |
13 |
14 | def test_graphics_func_does_run_by_default(overridden_func, func_mock_on_module, quib):
15 | overridden_func(quib, )
16 |
17 | assert func_mock_on_module.call_count == 1
18 |
19 |
20 | def test_graphics_func_does_not_run_when_lazy_flag_set_to_true(overridden_func, func_mock_on_module, quib):
21 | with GRAPHICS_LAZY.temporary_set(True):
22 | overridden_func(quib, )
23 |
24 | assert func_mock_on_module.call_count == 0
25 |
--------------------------------------------------------------------------------
/tests/functional/third_party_overriding/test_not_implemented.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pytest
3 |
4 | from pyquibbler import iquib
5 | from pyquibbler.function_overriding.function_override import NotImplementedFunc
6 |
7 |
8 | def test_function_defined_as_unimplemented_does_runs_on_non_quibs(axes):
9 | axes.axis([0, 7, 0, 5])
10 | assert np.array_equal(axes.get_xlim(), [0, 7])
11 | assert np.array_equal(axes.get_ylim(), [0, 5])
12 |
13 |
14 | def test_function_defined_as_unimplemented_raises_exception_on_quibs(axes):
15 | x = iquib(7)
16 | with pytest.raises(NotImplementedFunc, match='.*'):
17 | axes.grid(x)
18 |
--------------------------------------------------------------------------------
/tests/functional/third_party_overriding/test_numpy_special.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from numpy import ogrid, mgrid
3 | from numpy.lib._index_tricks_impl import nd_grid
4 |
5 | from pyquibbler import iquib
6 |
7 |
8 | def test_orgrid_getitem_without_quibs():
9 | grid = mgrid[0:3]
10 | assert np.array_equal(grid, [0, 1, 2])
11 |
12 |
13 | def my_getitem(self, key):
14 | return key
15 |
16 |
17 | def test_orgrid_getitem_with_quibs():
18 | n = iquib(3)
19 | grid = mgrid[0:n]
20 | assert np.array_equal(grid.get_value(), [0, 1, 2])
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/tests/functional/third_party_overriding/test_patches.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | import numpy as np
4 | from matplotlib.patches import Rectangle
5 | from pyquibbler import iquib
6 |
7 |
8 | def check_rectangle_location(rectangle: Rectangle, args):
9 | xy, w, h = args
10 | return np.array_equal(rectangle.get_xy(), xy) \
11 | and rectangle.get_width() == w \
12 | and rectangle.get_height() == h
13 |
14 |
15 | @pytest.fixture()
16 | def get_only_patch_from_axes(axes):
17 |
18 | def get_():
19 | assert len(axes.patches) == 1
20 | return axes.patches[0]
21 |
22 | return get_
23 |
24 |
25 | def test_axes_add_patch_on_non_quib(axes, get_only_patch_from_axes):
26 | p = Rectangle((1, 2), 3, 4)
27 | axes.add_patch(p)
28 | assert p is get_only_patch_from_axes()
29 |
30 |
31 | def test_axes_add_patch_on_quib(axes, get_only_patch_from_axes):
32 | w = iquib(3)
33 | p = Rectangle((1, 2), w, 4)
34 | axes.add_patch(p)
35 | assert p.get_value() is get_only_patch_from_axes()
36 |
37 |
38 | def test_patch_update(axes, get_only_patch_from_axes):
39 | w = iquib(3)
40 | p = Rectangle((1, 2), w, 4)
41 | axes.add_patch(p)
42 | assert check_rectangle_location(p.get_value(), ((1, 2), 3, 4)), "sanity"
43 |
44 | w.assign(10)
45 | assert p.get_value() is get_only_patch_from_axes()
46 | assert check_rectangle_location(p.get_value(), ((1, 2), 10, 4))
47 |
--------------------------------------------------------------------------------
/tests/functional/third_party_overriding/test_q_rectangle_selector.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | from pyquibbler.graphics.widgets import QRectangleSelector
4 |
5 |
6 | def test_move_only_one_rectangle_selector(axes, create_axes_mouse_press_move_release_events):
7 | w1 = QRectangleSelector(axes, extents=[0.4, 0.6, 0.4, 0.6])
8 | w2 = QRectangleSelector(axes, extents=[0.4, 0.6, 0.4, 0.6])
9 |
10 | create_axes_mouse_press_move_release_events([(0.5, 0.5), (0.6, 0.6), (0.7, 0.7)])
11 | assert np.array_equal(np.round(w1.extents, 2), [0.6, 0.8, 0.6, 0.8])
12 | assert np.array_equal(np.round(w2.extents, 2), [0.4, 0.6, 0.4, 0.6]) # this fails in normal RectangleSelector
13 |
14 | create_axes_mouse_press_move_release_events([(0.5, 0.5), (0.6, 0.6), (0.7, 0.7)])
15 | assert np.array_equal(np.round(w1.extents, 2), [0.6, 0.8, 0.6, 0.8])
16 | assert np.array_equal(np.round(w2.extents, 2), [0.6, 0.8, 0.6, 0.8])
17 |
--------------------------------------------------------------------------------
/tests/functional/utils.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 | from unittest.mock import Mock
3 | from dataclasses import dataclass, field
4 | from typing import List
5 |
6 | from pyquibbler.quib.quib import Quib
7 | from pyquibbler.path import PathComponent, Path
8 |
9 |
10 | def get_mock_with_repr(repr_value: str):
11 | mock = Mock()
12 | mock.__repr__ = Mock(return_value=repr_value)
13 | return mock
14 |
15 |
16 | slicer = type('Slicer', (), dict(__getitem__=lambda self, item: item))()
17 |
18 |
19 | @dataclass
20 | class PathBuilder:
21 | quib: Quib
22 | path: Path = field(default_factory=list)
23 |
24 | def __getitem__(self, item):
25 | self.quib.get_type() # legacy from when PathComponent had type
26 | return PathBuilder(self.quib[item], [*self.path, PathComponent(item)])
27 |
28 |
29 | def get_func_mock(func):
30 | return mock.create_autospec(func, side_effect=func)
31 |
--------------------------------------------------------------------------------
/tests/integration/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/__init__.py
--------------------------------------------------------------------------------
/tests/integration/benchmarks/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/benchmarks/__init__.py
--------------------------------------------------------------------------------
/tests/integration/demos/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/demos/__init__.py
--------------------------------------------------------------------------------
/tests/integration/demos/baseline_images/test_covid_demo/covid_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/demos/baseline_images/test_covid_demo/covid_demo.png
--------------------------------------------------------------------------------
/tests/integration/demos/baseline_images/test_gear_demo/gear_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/demos/baseline_images/test_gear_demo/gear_demo.png
--------------------------------------------------------------------------------
/tests/integration/quib/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/__init__.py
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/graphics/__init__.py
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/test_general.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import pytest
3 |
4 | from pyquibbler import initialize_quibbler, iquib, Quib, quiby
5 | from pyquibbler.graphics.global_collecting import AxesCreatedDuringQuibEvaluationException
6 |
7 |
8 | @pytest.mark.regression
9 | def test_graphics_function_quib_doesnt_fail_on_removal_of_artists(axes):
10 | input_quib = iquib([1, 2, 3])
11 | plt.plot(input_quib)
12 | plt.cla()
13 |
14 | input_quib[0] = 10
15 |
16 |
17 | @pytest.mark.regression
18 | def test_graphics_quiby_function_doesnt_fail_when_creating_axes():
19 | def plot_draggable(y: Quib):
20 | plt.plot(y)
21 |
22 | plt.close("all")
23 | data = iquib([1, 2])
24 | with pytest.raises(AxesCreatedDuringQuibEvaluationException, match='.*'):
25 | quiby(plot_draggable, is_graphics=True)(data)
26 |
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/widgets/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/graphics/widgets/__init__.py
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/widgets/baseline_images/test_checkbuttons/multiple_sets.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/graphics/widgets/baseline_images/test_checkbuttons/multiple_sets.png
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/widgets/baseline_images/test_checkbuttons/unset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/graphics/widgets/baseline_images/test_checkbuttons/unset.png
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/widgets/baseline_images/test_radio_buttons/set_active_multiple_times.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/graphics/widgets/baseline_images/test_radio_buttons/set_active_multiple_times.png
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/widgets/baseline_images/test_rectangle_selector/move.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/graphics/widgets/baseline_images/test_rectangle_selector/move.png
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/widgets/baseline_images/test_rectangle_selector/move_list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/graphics/widgets/baseline_images/test_rectangle_selector/move_list.png
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/widgets/baseline_images/test_slider/keeps_same_widget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/graphics/widgets/baseline_images/test_slider/keeps_same_widget.png
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/widgets/baseline_images/test_slider/multiple_times.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/graphics/widgets/baseline_images/test_slider/multiple_times.png
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/widgets/baseline_images/test_slider/press_and_release_changes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/integration/quib/graphics/widgets/baseline_images/test_slider/press_and_release_changes.png
--------------------------------------------------------------------------------
/tests/integration/quib/graphics/widgets/conftest.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from matplotlib.widgets import AxesWidget
3 |
4 | from pyquibbler.debug_utils.track_instances import track_instances_of_class
5 |
6 |
7 | @pytest.fixture()
8 | def get_only_live_widget(live_widgets):
9 | def _get():
10 | assert len(live_widgets) == 1
11 | return list(live_widgets)[0]
12 |
13 | return _get
14 |
15 |
16 | @pytest.fixture()
17 | def live_widgets():
18 | with track_instances_of_class(AxesWidget, False) as tracker:
19 | yield tracker
20 |
--------------------------------------------------------------------------------
/tests/lab_extension/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Technion-Kishony-lab/quibbler/fb371d899b4aa1e56fa8c2074962177607ff5af6/tests/lab_extension/__init__.py
--------------------------------------------------------------------------------
/tests/lab_extension/notebooks/notebook_with_error.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "id": "5dc0e2e4",
7 | "metadata": {},
8 | "outputs": [],
9 | "source": [
10 | "# notebook with error\n",
11 | "assert False"
12 | ]
13 | }
14 | ],
15 | "metadata": {
16 | "kernelspec": {
17 | "display_name": "Python 3 (ipykernel)",
18 | "language": "python",
19 | "name": "python3"
20 | },
21 | "language_info": {
22 | "codemirror_mode": {
23 | "name": "ipython",
24 | "version": 3
25 | },
26 | "file_extension": ".py",
27 | "mimetype": "text/x-python",
28 | "name": "python",
29 | "nbconvert_exporter": "python",
30 | "pygments_lexer": "ipython3",
31 | "version": "3.11.9"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 5
36 | }
37 |
--------------------------------------------------------------------------------
/tests/lab_extension/notebooks/test_saving.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "id": "5dc0e2e4",
7 | "metadata": {},
8 | "outputs": [],
9 | "source": [
10 | "from pyquibbler import iquib, initialize_quibbler\n",
11 | "initialize_quibbler()"
12 | ]
13 | },
14 | {
15 | "metadata": {},
16 | "cell_type": "code",
17 | "outputs": [],
18 | "execution_count": null,
19 | "source": [
20 | "# Verify kernel restarts\n",
21 | "try:\n",
22 | " ID += 1\n",
23 | "except NameError:\n",
24 | " ID = 0\n",
25 | "assert ID == 0"
26 | ],
27 | "id": "ce3b0011760ef619"
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": null,
32 | "id": "3c3674c5",
33 | "metadata": {
34 | "pycharm": {
35 | "name": "#%%\n"
36 | }
37 | },
38 | "outputs": [],
39 | "source": [
40 | "name = iquib('michael')\n",
41 | "nums = iquib([1, 2., 3])"
42 | ]
43 | }
44 | ],
45 | "metadata": {
46 | "kernelspec": {
47 | "display_name": "Python 3 (ipykernel)",
48 | "language": "python",
49 | "name": "python3"
50 | },
51 | "language_info": {
52 | "codemirror_mode": {
53 | "name": "ipython",
54 | "version": 3
55 | },
56 | "file_extension": ".py",
57 | "mimetype": "text/x-python",
58 | "name": "python",
59 | "nbconvert_exporter": "python",
60 | "pygments_lexer": "ipython3",
61 | "version": "3.11.9"
62 | }
63 | },
64 | "nbformat": 4,
65 | "nbformat_minor": 5
66 | }
67 |
--------------------------------------------------------------------------------