memory-graph 0.3.45__tar.gz → 0.3.47__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {memory_graph-0.3.45/memory_graph.egg-info → memory_graph-0.3.47}/PKG-INFO +50 -40
- {memory_graph-0.3.45 → memory_graph-0.3.47}/README.md +49 -39
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/add_one.gv +18 -18
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_key_value.gv +12 -12
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_leaf.gv +5 -5
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_linear.gv +12 -12
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_table.gv +12 -12
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_search.gv +34 -34
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_search.py +1 -1
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_search_linear.gv +29 -29
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_tree.gv +35 -35
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary.py +2 -1
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary0.gv +6 -6
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary0.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary1.gv +8 -8
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary1.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary10.gv +16 -16
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary10.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary11.gv +14 -14
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary11.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary12.gv +12 -12
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary12.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary13.gv +10 -10
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary13.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary14.gv +8 -8
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary14.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary2.gv +10 -10
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary2.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary3.gv +12 -12
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary3.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary4.gv +14 -14
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary4.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary5.gv +16 -16
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary5.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary6.gv +18 -18
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary6.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary7.gv +20 -20
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary7.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary8.gv +20 -20
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary8.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary9.gv +18 -18
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary9.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copies.gv +20 -20
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_immutable.gv +11 -11
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_method.gv +16 -16
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_mix.gv +16 -16
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging0.gv +8 -8
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging0.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging1.gv +11 -11
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging1.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging2.gv +13 -13
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging2.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging3.gv +15 -15
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging3.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging4.gv +17 -17
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging4.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging5.gv +17 -17
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging5.png +0 -0
- memory_graph-0.3.47/images/embedded1.gv +26 -0
- memory_graph-0.3.47/images/embedded2.gv +46 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/extension_numpy.gv +15 -15
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/extension_pandas.gv +8 -8
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial0.gv +3 -3
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial0.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial1.gv +6 -6
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial1.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial2.gv +8 -8
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial2.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial3.gv +10 -10
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial3.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial4.gv +12 -12
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial4.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial5.gv +14 -14
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial5.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial6.gv +12 -12
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial6.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial7.gv +10 -10
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial7.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial8.gv +8 -8
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial8.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial9.gv +6 -6
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial9.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/hash_set.gv +29 -29
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/immutable1.gv +4 -4
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/immutable2.gv +6 -6
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/introspect_depth.gv +56 -56
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/linked_list.gv +20 -20
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/many_types.gv +12 -12
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/mutable1.gv +4 -4
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/mutable2.gv +4 -4
- memory_graph-0.3.47/images/not_node_types.py +9 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/not_node_types1.gv +6 -6
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/not_node_types2.gv +14 -14
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set0.gv +11 -11
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set0.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set1.gv +17 -17
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set1.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set10.gv +36 -36
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set10.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set11.gv +31 -31
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set11.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set12.gv +31 -31
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set12.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set13.gv +36 -36
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set13.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set14.gv +41 -41
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set14.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set15.gv +43 -43
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set15.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set16.gv +40 -40
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set16.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set17.gv +40 -40
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set17.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set18.gv +45 -45
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set18.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set19.gv +47 -47
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set19.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set2.gv +22 -22
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set2.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set20.gv +44 -44
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set20.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set21.gv +39 -39
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set21.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set22.gv +34 -34
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set22.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set23.gv +28 -28
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set23.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set3.gv +27 -27
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set3.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set4.gv +32 -32
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set4.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set5.gv +34 -34
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set5.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set6.gv +32 -32
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set6.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set7.gv +32 -32
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set7.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set8.gv +37 -37
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set8.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set9.gv +39 -39
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set9.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/rebinding1.gv +4 -4
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/rebinding2.gv +6 -6
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/__init__.py +6 -5
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/config.py +7 -2
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/config_default.py +8 -5
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/extension_numpy.py +1 -1
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/extension_pytorch.py +1 -1
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/html_table.py +2 -2
- memory_graph-0.3.47/memory_graph/memory_to_nodes.py +253 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/node_base.py +1 -1
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/node_key_value.py +9 -2
- memory_graph-0.3.47/memory_graph/t.py +8 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/test.py +3 -3
- {memory_graph-0.3.45 → memory_graph-0.3.47/memory_graph.egg-info}/PKG-INFO +50 -40
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph.egg-info/SOURCES.txt +5 -2
- {memory_graph-0.3.45 → memory_graph-0.3.47}/pyproject.toml +1 -1
- memory_graph-0.3.45/images/not_node_types.py +0 -9
- memory_graph-0.3.45/memory_graph/memory_to_nodes.py +0 -200
- {memory_graph-0.3.45 → memory_graph-0.3.47}/LICENSE.txt +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/MANIFEST.in +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/-0 +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/.gif +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/.idea/.gitignore +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/.idea/images.iml +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/.idea/inspectionProfiles/profiles_settings.xml +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/.idea/misc.xml +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/.idea/modules.xml +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/.idea/vcs.xml +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/.idea/workspace.xml +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/add_one.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/add_one.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_dir.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_dir.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_fail.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_fail.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_key_value.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_leaf.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_linear.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/avltree_table.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_search.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_search.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_search_linear.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_search_linear.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_tree.gif +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_tree.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_tree.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_tree2.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/bin_tree2.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/binary.gif +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/call_stack.txt +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/colab_example.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copies.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copies_immutable.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copies_immutable.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copies_mix.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copies_mix.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_immutable.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_immutable.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_immutable.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_method.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_method.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_mix.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_mix.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_mix.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_mutable.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/copy_mutable.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/create_gif.sh +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/create_images.sh +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debug.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debug.pdf +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debug_vscode.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging.gif +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging01.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging02.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging03.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging04.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging05.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/debugging06.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/depth.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/depth.png +0 -0
- /memory_graph-0.3.45/images/not_node_types1.png → /memory_graph-0.3.47/images/embedded1.png +0 -0
- /memory_graph-0.3.45/images/not_node_types2.png → /memory_graph-0.3.47/images/embedded2.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/extension_numpy.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/extension_numpy.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/extension_pandas.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/extension_pandas.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/extension_torch.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/extension_torch.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/extension_torch.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/extension_torch.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial.gif +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial01.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial02.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial03.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial04.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial05.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial06.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/factorial07.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/hash_set.gif +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/hash_set.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/hash_set.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/hidden_edges.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/hidden_edges.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/hidden_edges.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/hidden_edges.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/highlight.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/immutable.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/immutable1.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/immutable2.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/introspect_depth.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/introspect_depth.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/introspect_depth.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/ipython.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/jupyter_example.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/linked_list.gif +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/linked_list.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/linked_list.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/log.txt +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/many_types.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/many_types.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/memory_graph.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/memory_graph.gv.pdf +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/memory_graph.pdf +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/mutable.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/mutable1.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/mutable2.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/my_graph.gv +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/my_graph.pdf +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/name_rebinding.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/not_node_types.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set.gif +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set19.png~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/power_set8.png~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/pyodide.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/rebinding1.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/rebinding2.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/stack.txt +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/test.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/test.py~ +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/uva.png +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/vsc.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/images/vscode_copying.gif +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/call_stack.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/config_helpers.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/extension_pandas.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/extension_torch.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/list_view.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/node_leaf.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/node_linear.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/node_table.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/pytorch_test.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/sequence.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/slicer.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/slices.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/slices_iterator.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/slices_table_iterator.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/test_max_graph_depth.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/test_memory_graph.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/test_memory_to_nodes.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/test_sequence.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/test_slicer.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/test_slices.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/test_slices_iterator.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph/utils.py +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph.egg-info/dependency_links.txt +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph.egg-info/requires.txt +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/memory_graph.egg-info/top_level.txt +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/setup.cfg +0 -0
- {memory_graph-0.3.45 → memory_graph-0.3.47}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memory_graph
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.47
|
|
4
4
|
Summary: Teaching tool and debugging aid in context of references, mutable data types, and shallow and deep copy.
|
|
5
5
|
Author-email: Bas Terwijn <bterwijn@gmail.com>
|
|
6
6
|
License: BSD 2-Clause License
|
|
@@ -105,7 +105,7 @@ b.append(1) # changing 'b' changes 'a'
|
|
|
105
105
|
print('a:', a)
|
|
106
106
|
print('b:', b)
|
|
107
107
|
|
|
108
|
-
# check if 'a' and 'b' share
|
|
108
|
+
# check if 'a' and 'b' share values
|
|
109
109
|
print('ids:', id(a), id(b))
|
|
110
110
|
print('identical?:', a is b)
|
|
111
111
|
|
|
@@ -117,18 +117,18 @@ mg.show( locals() )
|
|
|
117
117
|
|
|
118
118
|

|
|
119
119
|
|
|
120
|
-
a graph showing `a` and `b` share
|
|
120
|
+
a graph showing `a` and `b` share values
|
|
121
121
|
|
|
122
122
|
</td></tr></table>
|
|
123
123
|
|
|
124
|
-
The fact that `a` and `b` share
|
|
124
|
+
The fact that `a` and `b` share values can not be verified by printing the lists. It can be verified by comparing the identity of both variables using the `id()` function or by using the `is` comparison operator as shown in the program output below, but this quickly becomes impractical for larger programs.
|
|
125
125
|
```{verbatim}
|
|
126
126
|
a: 4, 3, 2, 1
|
|
127
127
|
b: 4, 3, 2, 1
|
|
128
128
|
ids: 126432214913216 126432214913216
|
|
129
129
|
identical?: True
|
|
130
130
|
```
|
|
131
|
-
A better way to understand what
|
|
131
|
+
A better way to understand what values are shared is to draw a graph using [memory_graph](https://pypi.org/project/memory-graph/).
|
|
132
132
|
|
|
133
133
|
# Chapters #
|
|
134
134
|
|
|
@@ -160,6 +160,9 @@ A better way to understand what data is shared is to draw a graph using [memory_
|
|
|
160
160
|
|
|
161
161
|
[Troubleshooting](#troubleshooting)
|
|
162
162
|
|
|
163
|
+
[Social Media](#social-media)
|
|
164
|
+
|
|
165
|
+
[Other Packages](#other-packages)
|
|
163
166
|
|
|
164
167
|
## Author ##
|
|
165
168
|
Bas Terwijn
|
|
@@ -235,14 +238,14 @@ mg.show(locals())
|
|
|
235
238
|
```
|
|
236
239
|
|
|
237
240
|
* `c1` is an **assignment**, nothing is copied, all the values are shared
|
|
238
|
-
* `c2` is a **shallow copy**, only the
|
|
241
|
+
* `c2` is a **shallow copy**, only the first value is copied, all the underlying values are shared
|
|
239
242
|
* `c3` is a **deep copy**, all the values are copied, nothing is shared
|
|
240
243
|
|
|
241
244
|

|
|
242
245
|
|
|
243
246
|
|
|
244
247
|
## Custom Copy ##
|
|
245
|
-
We can write our own custom copy function or method in case the three standard "copy" options don't do what we want. For example, in the code below the
|
|
248
|
+
We can write our own custom copy function or method in case the three standard "copy" options don't do what we want. For example, in the code below the `custom_copy()` method of My_Class copies the `digits` but shares the `letters` between two objects.
|
|
246
249
|
|
|
247
250
|
```python
|
|
248
251
|
import memory_graph as mg
|
|
@@ -267,6 +270,24 @@ mg.show(locals())
|
|
|
267
270
|
```
|
|
268
271
|

|
|
269
272
|
|
|
273
|
+
## Name Rebinding ##
|
|
274
|
+
When `a` and `b` share a mutable value, then changing the value of `b` changes the value of `a` and vice versa. However, reassigning `b` does not change `a`. When you reassign `b`, you only rebind the name `b` to another value without effecting any other variables.
|
|
275
|
+
|
|
276
|
+
```python
|
|
277
|
+
import memory_graph as mg
|
|
278
|
+
|
|
279
|
+
a = [4, 3, 2]
|
|
280
|
+
b = a
|
|
281
|
+
mg.render(locals(), 'rebinding1.png')
|
|
282
|
+
|
|
283
|
+
b += [1] # changes the value of 'b' and 'a'
|
|
284
|
+
b = [100, 200] # rebinds 'b' to another value, 'a' is uneffected
|
|
285
|
+
mg.render(locals(), 'rebinding2.png')
|
|
286
|
+
```
|
|
287
|
+
|  |  |
|
|
288
|
+
|:-----------------------------------------------------------:|:-------------------------------------------------------------:|
|
|
289
|
+
| rebinding1.png | rebinding2.png |
|
|
290
|
+
|
|
270
291
|
## Copying Values of Immutable Type ##
|
|
271
292
|
Because a value of immutable type will be copied automatically when it is changed, there is no need to copy it beforehand. Therefore, a shallow or deep copy of a value of immutable type will result in just an assignment to save on the time needed to make the copy and the space (=memory) needed to store the values.
|
|
272
293
|
|
|
@@ -302,24 +323,6 @@ mg.show(locals())
|
|
|
302
323
|
```
|
|
303
324
|

|
|
304
325
|
|
|
305
|
-
## Name Rebinding ##
|
|
306
|
-
When `a` and `b` share a mutable value, then changing the value of `b` changes the value of `a` and vice versa. However, reassigning `b` does not change `a`. When you reassign `b`, you only rebind the name `b` to a new value without effecting any other variables.
|
|
307
|
-
|
|
308
|
-
```python
|
|
309
|
-
import memory_graph as mg
|
|
310
|
-
|
|
311
|
-
a = [4, 3, 2]
|
|
312
|
-
b = a
|
|
313
|
-
mg.render(locals(), 'rebinding1.png')
|
|
314
|
-
|
|
315
|
-
b += [1] # changes the value of 'b' and 'a'
|
|
316
|
-
b = [100, 200] # rebinds 'b' to a new value, 'a' is uneffected
|
|
317
|
-
mg.render(locals(), 'rebinding2.png')
|
|
318
|
-
```
|
|
319
|
-
|  |  |
|
|
320
|
-
|:-----------------------------------------------------------:|:-------------------------------------------------------------:|
|
|
321
|
-
| rebinding1.png | rebinding2.png |
|
|
322
|
-
|
|
323
326
|
# Call Stack #
|
|
324
327
|
The `mg.stack()` function retrieves the entire call stack, including the local variables for each function on the stack. This enables us to understand function calls, variable scope, and the **complete program state** through call stack visualization. By examining the graph, we can determine whether any local variables from different functions share data. For instance, consider the function `add_one()` which adds the value `1` to each of its parameters `a`, `b`, and `c`.
|
|
325
328
|
|
|
@@ -335,8 +338,8 @@ def add_one(a, b, c):
|
|
|
335
338
|
a = [4, 3, 2]
|
|
336
339
|
b = (4, 3, 2)
|
|
337
340
|
c = [4, 3, 2]
|
|
338
|
-
|
|
339
341
|
add_one(a, b, c.copy())
|
|
342
|
+
|
|
340
343
|
print(f"a:{a} b:{b} c:{c}")
|
|
341
344
|
```
|
|
342
345
|

|
|
@@ -647,11 +650,14 @@ Different aspects of memory_graph can be configured. The default configuration c
|
|
|
647
650
|
- ***mg.config.max_string_length*** : int
|
|
648
651
|
- The maximum length of strings shown in the graph. Longer strings will be truncated.
|
|
649
652
|
|
|
650
|
-
- ***mg.config.
|
|
651
|
-
- Holds all types for which no separate node is drawn but that
|
|
653
|
+
- ***mg.config.embedded_types*** : set[type]
|
|
654
|
+
- Holds all types for which no separate node is drawn but that are embedded in their parent Node.
|
|
652
655
|
|
|
653
|
-
- ***mg.config.
|
|
654
|
-
-
|
|
656
|
+
- ***mg.config.embedded_key_types*** : set[type]
|
|
657
|
+
- Holds all types that are embedded as key in a Node_Key_Value node, even when not in 'embedded_types'.
|
|
658
|
+
|
|
659
|
+
- ***mg.config.embedding_types*** : set[type]
|
|
660
|
+
- Holds all dictionary types that embed their key-value tuple children.
|
|
655
661
|
|
|
656
662
|
- ***mg.config.type_to_node*** : dict[type, fun(data) -> Node]
|
|
657
663
|
- Determines how a data type is converted to a Node subclass for visualization in the graph.
|
|
@@ -681,26 +687,26 @@ Different aspects of memory_graph can be configured. The default configuration c
|
|
|
681
687
|
## Simplified Graph ##
|
|
682
688
|
Memory_graph simplifies the visualization (and the viewer's mental model) by **not** showing separate nodes for immutable types like `bool`, `int`, `float`, `complex`, and `str` by default. This simplification can sometimes be slightly misleading. As in the example below, after a shallow copy, lists `a` and `b` technically share their `int` values, but the graph makes it appear as though `a` and `b` each have their own copies. However, since `int` is immutable, this simplification will never lead to unexpected changes (changing `a` won’t affect `b`) so will never result in bugs.
|
|
683
689
|
|
|
684
|
-
The simplification strikes a balance: it is slightly misleading but keeps the graph clean and easy to understand and focuses on the mutable types where unexpected changes can occur. This is why it is the default behavior. If you do want to show separate nodes for `int` values, such as for educational purposes, you can simply remove `int` from the `mg.config.
|
|
690
|
+
The simplification strikes a balance: it is slightly misleading but keeps the graph clean and easy to understand and focuses on the mutable types where unexpected changes can occur. This is why it is the default behavior. If you do want to show separate nodes for `int` values, such as for educational purposes, you can simply remove `int` from the `mg.config.embedded_types` set:
|
|
685
691
|
```python
|
|
686
692
|
import memory_graph as mg
|
|
687
693
|
|
|
688
694
|
a = [100, 200, 300]
|
|
689
695
|
b = a.copy()
|
|
690
|
-
mg.render(locals(), '
|
|
696
|
+
mg.render(locals(), 'embedded1.png')
|
|
691
697
|
|
|
692
|
-
mg.config.
|
|
698
|
+
mg.config.embedded_types.remove(int) # now show separate nodes for int values
|
|
693
699
|
|
|
694
|
-
mg.render(locals(), '
|
|
700
|
+
mg.render(locals(), 'embedded2.png')
|
|
695
701
|
```
|
|
696
|
-
|  |  |
|
|
697
703
|
|:-----------------------------------------------------------:|:-------------------------------------------------------------:|
|
|
698
|
-
|
|
|
704
|
+
| embedded1.png — simplified | embedded2.png — technically correct |
|
|
699
705
|
|
|
700
|
-
Additionally, the simplification hides away the [reuse of small int values \[-5, 256\]](https://docs.python.org/3/c-api/long.html#c.PyLong_FromLong) in the current CPython implementation, an optimization that might otherwise confuse beginner Python programmers. For instance, after executing `a[1]+=1; b[1]+=1` the `201` value is, maybe surprisingly, still shared between `a` and `b`, whereas executing `a[2]+=1; b[2]+=1` does not result in sharing the `301` value.
|
|
706
|
+
Additionally, the simplification hides away the [reuse of small int values \[-5, 256\]](https://docs.python.org/3/c-api/long.html#c.PyLong_FromLong) in the current CPython implementation, an optimization that might otherwise confuse beginner Python programmers. For instance, after executing `a[1]+=1; b[1]+=1` the `201` value is, maybe surprisingly, still shared between `a` and `b`, whereas executing `a[2]+=1; b[2]+=1` does not result in sharing the `301` value. Similarly CPython uses [String Interning](https://python-reference.readthedocs.io/en/latest/docs/functions/intern.html) to reuse small strings.
|
|
701
707
|
|
|
702
708
|
# Introspection #
|
|
703
|
-
|
|
709
|
+
Sometimes the introspection fails or is not as desired. For example the `bintrees.avltree.Node` object doesn't show any attributes in the graph below.
|
|
704
710
|
|
|
705
711
|
```python
|
|
706
712
|
import memory_graph as mg
|
|
@@ -873,7 +879,7 @@ data.sort()
|
|
|
873
879
|
# search 'value'
|
|
874
880
|
value = data[random.randrange(n)]
|
|
875
881
|
index = bin_search(List_View(data, 0, len(data)), value)
|
|
876
|
-
print(
|
|
882
|
+
print('index:', index, 'data[index]:', data[index])
|
|
877
883
|
```
|
|
878
884
|

|
|
879
885
|
|
|
@@ -1067,5 +1073,9 @@ $ bash create_gif.sh animated
|
|
|
1067
1073
|
|
|
1068
1074
|
- When graph edges overlap it can be hard to distinguish them. Using an interactive graphviz viewer, such as [xdot](https://github.com/jrfonseca/xdot.py), on a '*.gv' DOT output file will help.
|
|
1069
1075
|
|
|
1070
|
-
|
|
1076
|
+
# Social Media #
|
|
1077
|
+
* LinkedIn: https://www.linkedin.com/groups/13244150/
|
|
1078
|
+
* Reddit: https://www.reddit.com/r/Python_memory_graph/
|
|
1079
|
+
|
|
1080
|
+
# Other Packages #
|
|
1071
1081
|
The [memory_graph](https://pypi.org/project/memory-graph/) package visualizes your data. If instead you want to visualize function calls, check out the [invocation_tree](https://pypi.org/project/invocation-tree/) package.
|
|
@@ -60,7 +60,7 @@ b.append(1) # changing 'b' changes 'a'
|
|
|
60
60
|
print('a:', a)
|
|
61
61
|
print('b:', b)
|
|
62
62
|
|
|
63
|
-
# check if 'a' and 'b' share
|
|
63
|
+
# check if 'a' and 'b' share values
|
|
64
64
|
print('ids:', id(a), id(b))
|
|
65
65
|
print('identical?:', a is b)
|
|
66
66
|
|
|
@@ -72,18 +72,18 @@ mg.show( locals() )
|
|
|
72
72
|
|
|
73
73
|

|
|
74
74
|
|
|
75
|
-
a graph showing `a` and `b` share
|
|
75
|
+
a graph showing `a` and `b` share values
|
|
76
76
|
|
|
77
77
|
</td></tr></table>
|
|
78
78
|
|
|
79
|
-
The fact that `a` and `b` share
|
|
79
|
+
The fact that `a` and `b` share values can not be verified by printing the lists. It can be verified by comparing the identity of both variables using the `id()` function or by using the `is` comparison operator as shown in the program output below, but this quickly becomes impractical for larger programs.
|
|
80
80
|
```{verbatim}
|
|
81
81
|
a: 4, 3, 2, 1
|
|
82
82
|
b: 4, 3, 2, 1
|
|
83
83
|
ids: 126432214913216 126432214913216
|
|
84
84
|
identical?: True
|
|
85
85
|
```
|
|
86
|
-
A better way to understand what
|
|
86
|
+
A better way to understand what values are shared is to draw a graph using [memory_graph](https://pypi.org/project/memory-graph/).
|
|
87
87
|
|
|
88
88
|
# Chapters #
|
|
89
89
|
|
|
@@ -115,6 +115,9 @@ A better way to understand what data is shared is to draw a graph using [memory_
|
|
|
115
115
|
|
|
116
116
|
[Troubleshooting](#troubleshooting)
|
|
117
117
|
|
|
118
|
+
[Social Media](#social-media)
|
|
119
|
+
|
|
120
|
+
[Other Packages](#other-packages)
|
|
118
121
|
|
|
119
122
|
## Author ##
|
|
120
123
|
Bas Terwijn
|
|
@@ -190,14 +193,14 @@ mg.show(locals())
|
|
|
190
193
|
```
|
|
191
194
|
|
|
192
195
|
* `c1` is an **assignment**, nothing is copied, all the values are shared
|
|
193
|
-
* `c2` is a **shallow copy**, only the
|
|
196
|
+
* `c2` is a **shallow copy**, only the first value is copied, all the underlying values are shared
|
|
194
197
|
* `c3` is a **deep copy**, all the values are copied, nothing is shared
|
|
195
198
|
|
|
196
199
|

|
|
197
200
|
|
|
198
201
|
|
|
199
202
|
## Custom Copy ##
|
|
200
|
-
We can write our own custom copy function or method in case the three standard "copy" options don't do what we want. For example, in the code below the
|
|
203
|
+
We can write our own custom copy function or method in case the three standard "copy" options don't do what we want. For example, in the code below the `custom_copy()` method of My_Class copies the `digits` but shares the `letters` between two objects.
|
|
201
204
|
|
|
202
205
|
```python
|
|
203
206
|
import memory_graph as mg
|
|
@@ -222,6 +225,24 @@ mg.show(locals())
|
|
|
222
225
|
```
|
|
223
226
|

|
|
224
227
|
|
|
228
|
+
## Name Rebinding ##
|
|
229
|
+
When `a` and `b` share a mutable value, then changing the value of `b` changes the value of `a` and vice versa. However, reassigning `b` does not change `a`. When you reassign `b`, you only rebind the name `b` to another value without effecting any other variables.
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
import memory_graph as mg
|
|
233
|
+
|
|
234
|
+
a = [4, 3, 2]
|
|
235
|
+
b = a
|
|
236
|
+
mg.render(locals(), 'rebinding1.png')
|
|
237
|
+
|
|
238
|
+
b += [1] # changes the value of 'b' and 'a'
|
|
239
|
+
b = [100, 200] # rebinds 'b' to another value, 'a' is uneffected
|
|
240
|
+
mg.render(locals(), 'rebinding2.png')
|
|
241
|
+
```
|
|
242
|
+
|  |  |
|
|
243
|
+
|:-----------------------------------------------------------:|:-------------------------------------------------------------:|
|
|
244
|
+
| rebinding1.png | rebinding2.png |
|
|
245
|
+
|
|
225
246
|
## Copying Values of Immutable Type ##
|
|
226
247
|
Because a value of immutable type will be copied automatically when it is changed, there is no need to copy it beforehand. Therefore, a shallow or deep copy of a value of immutable type will result in just an assignment to save on the time needed to make the copy and the space (=memory) needed to store the values.
|
|
227
248
|
|
|
@@ -257,24 +278,6 @@ mg.show(locals())
|
|
|
257
278
|
```
|
|
258
279
|

|
|
259
280
|
|
|
260
|
-
## Name Rebinding ##
|
|
261
|
-
When `a` and `b` share a mutable value, then changing the value of `b` changes the value of `a` and vice versa. However, reassigning `b` does not change `a`. When you reassign `b`, you only rebind the name `b` to a new value without effecting any other variables.
|
|
262
|
-
|
|
263
|
-
```python
|
|
264
|
-
import memory_graph as mg
|
|
265
|
-
|
|
266
|
-
a = [4, 3, 2]
|
|
267
|
-
b = a
|
|
268
|
-
mg.render(locals(), 'rebinding1.png')
|
|
269
|
-
|
|
270
|
-
b += [1] # changes the value of 'b' and 'a'
|
|
271
|
-
b = [100, 200] # rebinds 'b' to a new value, 'a' is uneffected
|
|
272
|
-
mg.render(locals(), 'rebinding2.png')
|
|
273
|
-
```
|
|
274
|
-
|  |  |
|
|
275
|
-
|:-----------------------------------------------------------:|:-------------------------------------------------------------:|
|
|
276
|
-
| rebinding1.png | rebinding2.png |
|
|
277
|
-
|
|
278
281
|
# Call Stack #
|
|
279
282
|
The `mg.stack()` function retrieves the entire call stack, including the local variables for each function on the stack. This enables us to understand function calls, variable scope, and the **complete program state** through call stack visualization. By examining the graph, we can determine whether any local variables from different functions share data. For instance, consider the function `add_one()` which adds the value `1` to each of its parameters `a`, `b`, and `c`.
|
|
280
283
|
|
|
@@ -290,8 +293,8 @@ def add_one(a, b, c):
|
|
|
290
293
|
a = [4, 3, 2]
|
|
291
294
|
b = (4, 3, 2)
|
|
292
295
|
c = [4, 3, 2]
|
|
293
|
-
|
|
294
296
|
add_one(a, b, c.copy())
|
|
297
|
+
|
|
295
298
|
print(f"a:{a} b:{b} c:{c}")
|
|
296
299
|
```
|
|
297
300
|

|
|
@@ -602,11 +605,14 @@ Different aspects of memory_graph can be configured. The default configuration c
|
|
|
602
605
|
- ***mg.config.max_string_length*** : int
|
|
603
606
|
- The maximum length of strings shown in the graph. Longer strings will be truncated.
|
|
604
607
|
|
|
605
|
-
- ***mg.config.
|
|
606
|
-
- Holds all types for which no separate node is drawn but that
|
|
608
|
+
- ***mg.config.embedded_types*** : set[type]
|
|
609
|
+
- Holds all types for which no separate node is drawn but that are embedded in their parent Node.
|
|
607
610
|
|
|
608
|
-
- ***mg.config.
|
|
609
|
-
-
|
|
611
|
+
- ***mg.config.embedded_key_types*** : set[type]
|
|
612
|
+
- Holds all types that are embedded as key in a Node_Key_Value node, even when not in 'embedded_types'.
|
|
613
|
+
|
|
614
|
+
- ***mg.config.embedding_types*** : set[type]
|
|
615
|
+
- Holds all dictionary types that embed their key-value tuple children.
|
|
610
616
|
|
|
611
617
|
- ***mg.config.type_to_node*** : dict[type, fun(data) -> Node]
|
|
612
618
|
- Determines how a data type is converted to a Node subclass for visualization in the graph.
|
|
@@ -636,26 +642,26 @@ Different aspects of memory_graph can be configured. The default configuration c
|
|
|
636
642
|
## Simplified Graph ##
|
|
637
643
|
Memory_graph simplifies the visualization (and the viewer's mental model) by **not** showing separate nodes for immutable types like `bool`, `int`, `float`, `complex`, and `str` by default. This simplification can sometimes be slightly misleading. As in the example below, after a shallow copy, lists `a` and `b` technically share their `int` values, but the graph makes it appear as though `a` and `b` each have their own copies. However, since `int` is immutable, this simplification will never lead to unexpected changes (changing `a` won’t affect `b`) so will never result in bugs.
|
|
638
644
|
|
|
639
|
-
The simplification strikes a balance: it is slightly misleading but keeps the graph clean and easy to understand and focuses on the mutable types where unexpected changes can occur. This is why it is the default behavior. If you do want to show separate nodes for `int` values, such as for educational purposes, you can simply remove `int` from the `mg.config.
|
|
645
|
+
The simplification strikes a balance: it is slightly misleading but keeps the graph clean and easy to understand and focuses on the mutable types where unexpected changes can occur. This is why it is the default behavior. If you do want to show separate nodes for `int` values, such as for educational purposes, you can simply remove `int` from the `mg.config.embedded_types` set:
|
|
640
646
|
```python
|
|
641
647
|
import memory_graph as mg
|
|
642
648
|
|
|
643
649
|
a = [100, 200, 300]
|
|
644
650
|
b = a.copy()
|
|
645
|
-
mg.render(locals(), '
|
|
651
|
+
mg.render(locals(), 'embedded1.png')
|
|
646
652
|
|
|
647
|
-
mg.config.
|
|
653
|
+
mg.config.embedded_types.remove(int) # now show separate nodes for int values
|
|
648
654
|
|
|
649
|
-
mg.render(locals(), '
|
|
655
|
+
mg.render(locals(), 'embedded2.png')
|
|
650
656
|
```
|
|
651
|
-
|  |  |
|
|
652
658
|
|:-----------------------------------------------------------:|:-------------------------------------------------------------:|
|
|
653
|
-
|
|
|
659
|
+
| embedded1.png — simplified | embedded2.png — technically correct |
|
|
654
660
|
|
|
655
|
-
Additionally, the simplification hides away the [reuse of small int values \[-5, 256\]](https://docs.python.org/3/c-api/long.html#c.PyLong_FromLong) in the current CPython implementation, an optimization that might otherwise confuse beginner Python programmers. For instance, after executing `a[1]+=1; b[1]+=1` the `201` value is, maybe surprisingly, still shared between `a` and `b`, whereas executing `a[2]+=1; b[2]+=1` does not result in sharing the `301` value.
|
|
661
|
+
Additionally, the simplification hides away the [reuse of small int values \[-5, 256\]](https://docs.python.org/3/c-api/long.html#c.PyLong_FromLong) in the current CPython implementation, an optimization that might otherwise confuse beginner Python programmers. For instance, after executing `a[1]+=1; b[1]+=1` the `201` value is, maybe surprisingly, still shared between `a` and `b`, whereas executing `a[2]+=1; b[2]+=1` does not result in sharing the `301` value. Similarly CPython uses [String Interning](https://python-reference.readthedocs.io/en/latest/docs/functions/intern.html) to reuse small strings.
|
|
656
662
|
|
|
657
663
|
# Introspection #
|
|
658
|
-
|
|
664
|
+
Sometimes the introspection fails or is not as desired. For example the `bintrees.avltree.Node` object doesn't show any attributes in the graph below.
|
|
659
665
|
|
|
660
666
|
```python
|
|
661
667
|
import memory_graph as mg
|
|
@@ -828,7 +834,7 @@ data.sort()
|
|
|
828
834
|
# search 'value'
|
|
829
835
|
value = data[random.randrange(n)]
|
|
830
836
|
index = bin_search(List_View(data, 0, len(data)), value)
|
|
831
|
-
print(
|
|
837
|
+
print('index:', index, 'data[index]:', data[index])
|
|
832
838
|
```
|
|
833
839
|

|
|
834
840
|
|
|
@@ -1022,5 +1028,9 @@ $ bash create_gif.sh animated
|
|
|
1022
1028
|
|
|
1023
1029
|
- When graph edges overlap it can be hard to distinguish them. Using an interactive graphviz viewer, such as [xdot](https://github.com/jrfonseca/xdot.py), on a '*.gv' DOT output file will help.
|
|
1024
1030
|
|
|
1025
|
-
|
|
1031
|
+
# Social Media #
|
|
1032
|
+
* LinkedIn: https://www.linkedin.com/groups/13244150/
|
|
1033
|
+
* Reddit: https://www.reddit.com/r/Python_memory_graph/
|
|
1034
|
+
|
|
1035
|
+
# Other Packages #
|
|
1026
1036
|
The [memory_graph](https://pypi.org/project/memory-graph/) package visualizes your data. If instead you want to visualize function calls, check out the [invocation_tree](https://pypi.org/project/invocation-tree/) package.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
digraph memory_graph {
|
|
2
2
|
node [shape=plaintext]
|
|
3
|
-
|
|
3
|
+
node134158269386304 [label=<
|
|
4
4
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="lightcoral" PORT="table">
|
|
5
5
|
<TR><TD BORDER="0"><font color="#505050">0</font></TD><TD BORDER="1"> 4 </TD></TR>
|
|
6
6
|
<TR><TD BORDER="0"><font color="#505050">1</font></TD><TD BORDER="1"> 3 </TD></TR>
|
|
@@ -8,30 +8,30 @@ digraph memory_graph {
|
|
|
8
8
|
<TR><TD BORDER="0"><font color="#505050">3</font></TD><TD BORDER="1"> 1 </TD></TR>
|
|
9
9
|
</TABLE>
|
|
10
10
|
> xlabel=list]
|
|
11
|
-
|
|
11
|
+
node134158258758592 [label=<
|
|
12
12
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="orange" PORT="table">
|
|
13
13
|
<TR><TD BORDER="0"><font color="#505050">0</font></TD><TD BORDER="1"> 4 </TD></TR>
|
|
14
14
|
<TR><TD BORDER="0"><font color="#505050">1</font></TD><TD BORDER="1"> 3 </TD></TR>
|
|
15
15
|
<TR><TD BORDER="0"><font color="#505050">2</font></TD><TD BORDER="1"> 2 </TD></TR>
|
|
16
16
|
</TABLE>
|
|
17
17
|
> xlabel=tuple]
|
|
18
|
-
|
|
18
|
+
node134158258021504 [label=<
|
|
19
19
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="lightcoral" PORT="table">
|
|
20
20
|
<TR><TD BORDER="0"><font color="#505050">0</font></TD><TD BORDER="1"> 4 </TD></TR>
|
|
21
21
|
<TR><TD BORDER="0"><font color="#505050">1</font></TD><TD BORDER="1"> 3 </TD></TR>
|
|
22
22
|
<TR><TD BORDER="0"><font color="#505050">2</font></TD><TD BORDER="1"> 2 </TD></TR>
|
|
23
23
|
</TABLE>
|
|
24
24
|
> xlabel=list]
|
|
25
|
-
|
|
25
|
+
node134158258580928 [label=<
|
|
26
26
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="#60a5ff" PORT="table">
|
|
27
27
|
<TR><TD BORDER="1" STYLE="ROUNDED"> a </TD><TD BORDER="1" STYLE="ROUNDED"> b </TD><TD BORDER="1" STYLE="ROUNDED"> c </TD></TR>
|
|
28
28
|
<TR><TD BORDER="1" PORT="ref0"> </TD><TD BORDER="1" PORT="ref1"> </TD><TD BORDER="1" PORT="ref2"> </TD></TR>
|
|
29
29
|
</TABLE>
|
|
30
30
|
> xlabel=dict]
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
node134158258580928:ref0 -> node134158269386304:table [style=solid]
|
|
32
|
+
node134158258580928:ref1 -> node134158258758592:table [style=solid]
|
|
33
|
+
node134158258580928:ref2 -> node134158258021504:table [style=solid]
|
|
34
|
+
node134158258723536 [label=<
|
|
35
35
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="orange" PORT="table">
|
|
36
36
|
<TR><TD BORDER="0"><font color="#505050">0</font></TD><TD BORDER="1"> 4 </TD></TR>
|
|
37
37
|
<TR><TD BORDER="0"><font color="#505050">1</font></TD><TD BORDER="1"> 3 </TD></TR>
|
|
@@ -39,7 +39,7 @@ digraph memory_graph {
|
|
|
39
39
|
<TR><TD BORDER="0"><font color="#505050">3</font></TD><TD BORDER="1"> 1 </TD></TR>
|
|
40
40
|
</TABLE>
|
|
41
41
|
> xlabel=tuple]
|
|
42
|
-
|
|
42
|
+
node134158258758976 [label=<
|
|
43
43
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="lightcoral" PORT="table">
|
|
44
44
|
<TR><TD BORDER="0"><font color="#505050">0</font></TD><TD BORDER="1"> 4 </TD></TR>
|
|
45
45
|
<TR><TD BORDER="0"><font color="#505050">1</font></TD><TD BORDER="1"> 3 </TD></TR>
|
|
@@ -47,23 +47,23 @@ digraph memory_graph {
|
|
|
47
47
|
<TR><TD BORDER="0"><font color="#505050">3</font></TD><TD BORDER="1"> 1 </TD></TR>
|
|
48
48
|
</TABLE>
|
|
49
49
|
> xlabel=list]
|
|
50
|
-
|
|
50
|
+
node134158254184256 [label=<
|
|
51
51
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="#60a5ff" PORT="table">
|
|
52
52
|
<TR><TD BORDER="1" STYLE="ROUNDED"> a </TD><TD BORDER="1" STYLE="ROUNDED"> b </TD><TD BORDER="1" STYLE="ROUNDED"> c </TD></TR>
|
|
53
53
|
<TR><TD BORDER="1" PORT="ref0"> </TD><TD BORDER="1" PORT="ref1"> </TD><TD BORDER="1" PORT="ref2"> </TD></TR>
|
|
54
54
|
</TABLE>
|
|
55
55
|
> xlabel=dict]
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
node134158254184256:ref0 -> node134158269386304:table [style=solid]
|
|
57
|
+
node134158254184256:ref1 -> node134158258723536:table [style=solid]
|
|
58
|
+
node134158254184256:ref2 -> node134158258758976:table [style=solid]
|
|
59
|
+
node134158254254080 [label=<
|
|
60
60
|
<TABLE BORDER="3" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="khaki" PORT="table">
|
|
61
61
|
<TR><TD BORDER="1" STYLE="ROUNDED"> 0: <module> </TD><TD BORDER="1" STYLE="ROUNDED"> 1: add_one </TD></TR>
|
|
62
62
|
<TR><TD BORDER="1" PORT="ref0"> </TD><TD BORDER="1" PORT="ref1"> </TD></TR>
|
|
63
63
|
</TABLE>
|
|
64
64
|
> xlabel=call_stack]
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
subgraph { rank=same;
|
|
68
|
-
subgraph { rank=same;
|
|
65
|
+
node134158254254080:ref0 -> node134158258580928:table [style=solid]
|
|
66
|
+
node134158254254080:ref1 -> node134158254184256:table [style=solid]
|
|
67
|
+
subgraph { rank=same; node134158258580928 -> node134158254184256[weight=10, style=invis]; }
|
|
68
|
+
subgraph { rank=same; node134158269386304 -> node134158258758592 -> node134158258021504 -> node134158258723536 -> node134158258758976[weight=10, style=invis]; }
|
|
69
69
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
digraph memory_graph {
|
|
2
2
|
node [shape=plaintext]
|
|
3
|
-
|
|
3
|
+
node129652369896160 [label=<
|
|
4
4
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="sandybrown" PORT="table">
|
|
5
5
|
<TR><TD BORDER="1" STYLE="ROUNDED"> left </TD><TD BORDER="1"> None </TD></TR>
|
|
6
6
|
<TR><TD BORDER="1" STYLE="ROUNDED"> key </TD><TD BORDER="1"> 5 </TD></TR>
|
|
@@ -8,7 +8,7 @@ digraph memory_graph {
|
|
|
8
8
|
<TR><TD BORDER="1" STYLE="ROUNDED"> right </TD><TD BORDER="1"> None </TD></TR>
|
|
9
9
|
</TABLE>
|
|
10
10
|
> xlabel="Node"]
|
|
11
|
-
|
|
11
|
+
node129652370126816 [label=<
|
|
12
12
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="sandybrown" PORT="table">
|
|
13
13
|
<TR><TD BORDER="1" STYLE="ROUNDED"> left </TD><TD BORDER="1"> None </TD></TR>
|
|
14
14
|
<TR><TD BORDER="1" STYLE="ROUNDED"> key </TD><TD BORDER="1"> 15 </TD></TR>
|
|
@@ -16,34 +16,34 @@ digraph memory_graph {
|
|
|
16
16
|
<TR><TD BORDER="1" STYLE="ROUNDED"> right </TD><TD BORDER="1"> None </TD></TR>
|
|
17
17
|
</TABLE>
|
|
18
18
|
> xlabel="Node"]
|
|
19
|
-
|
|
19
|
+
node129652370126896 [label=<
|
|
20
20
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="sandybrown" PORT="table">
|
|
21
21
|
<TR><TD BORDER="1" STYLE="ROUNDED"> left </TD><TD BORDER="1" STYLE="ROUNDED"> key </TD><TD BORDER="1" STYLE="ROUNDED"> value </TD><TD BORDER="1" STYLE="ROUNDED"> right </TD></TR>
|
|
22
22
|
<TR><TD BORDER="1" PORT="ref0"> </TD><TD BORDER="1"> 20 </TD><TD BORDER="1"> twenty </TD><TD BORDER="1"> None </TD></TR>
|
|
23
23
|
</TABLE>
|
|
24
24
|
> xlabel="Node"]
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
node129652370126896:ref0 -> node129652370126816:table [style=solid]
|
|
26
|
+
node129652385165168 [label=<
|
|
27
27
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="sandybrown" PORT="table">
|
|
28
28
|
<TR><TD BORDER="1" STYLE="ROUNDED"> left </TD><TD BORDER="1" STYLE="ROUNDED"> key </TD><TD BORDER="1" STYLE="ROUNDED"> value </TD><TD BORDER="1" STYLE="ROUNDED"> right </TD></TR>
|
|
29
29
|
<TR><TD BORDER="1" PORT="ref0"> </TD><TD BORDER="1"> 10 </TD><TD BORDER="1"> ten </TD><TD BORDER="1" PORT="ref1"> </TD></TR>
|
|
30
30
|
</TABLE>
|
|
31
31
|
> xlabel="Node"]
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
node129652385165168:ref0 -> node129652369896160:table [style=solid]
|
|
33
|
+
node129652385165168:ref1 -> node129652370126896:table [style=solid]
|
|
34
|
+
node129652371410960 [label=<
|
|
35
35
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="seagreen1" PORT="table">
|
|
36
36
|
<TR><TD BORDER="1" STYLE="ROUNDED"> _root </TD><TD BORDER="1" STYLE="ROUNDED"> _count </TD></TR>
|
|
37
37
|
<TR><TD BORDER="1" PORT="ref0"> </TD><TD BORDER="1"> 4 </TD></TR>
|
|
38
38
|
</TABLE>
|
|
39
39
|
> xlabel=AVLTree]
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
node129652371410960:ref0 -> node129652385165168:table [style=solid]
|
|
41
|
+
node129652374079360 [label=<
|
|
42
42
|
<TABLE BORDER="3" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="#60a5ff" PORT="table">
|
|
43
43
|
<TR><TD BORDER="1" STYLE="ROUNDED"> tree </TD></TR>
|
|
44
44
|
<TR><TD BORDER="1" PORT="ref0"> </TD></TR>
|
|
45
45
|
</TABLE>
|
|
46
46
|
> xlabel=dict]
|
|
47
|
-
|
|
48
|
-
subgraph { rank=same;
|
|
47
|
+
node129652374079360:ref0 -> node129652371410960:table [style=solid]
|
|
48
|
+
subgraph { rank=same; node129652369896160 -> node129652370126896[weight=10, style=invis]; }
|
|
49
49
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
digraph memory_graph {
|
|
2
2
|
node [shape=plaintext]
|
|
3
|
-
|
|
3
|
+
node129652385165168 [label=<
|
|
4
4
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="sandybrown" PORT="table">
|
|
5
5
|
<TR><TD BORDER="1"> key:10 value:ten </TD></TR>
|
|
6
6
|
</TABLE>
|
|
7
7
|
> xlabel="Node"]
|
|
8
|
-
|
|
8
|
+
node129652371410960 [label=<
|
|
9
9
|
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="seagreen1" PORT="table">
|
|
10
10
|
<TR><TD BORDER="1" STYLE="ROUNDED"> _root </TD><TD BORDER="1" STYLE="ROUNDED"> _count </TD></TR>
|
|
11
11
|
<TR><TD BORDER="1" PORT="ref0"> </TD><TD BORDER="1"> 4 </TD></TR>
|
|
12
12
|
</TABLE>
|
|
13
13
|
> xlabel=AVLTree]
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
node129652371410960:ref0 -> node129652385165168:table [style=solid]
|
|
15
|
+
node129652374079360 [label=<
|
|
16
16
|
<TABLE BORDER="3" CELLBORDER="1" CELLSPACING="5" CELLPADDING="0" BGCOLOR="#60a5ff" PORT="table">
|
|
17
17
|
<TR><TD BORDER="1" STYLE="ROUNDED"> tree </TD></TR>
|
|
18
18
|
<TR><TD BORDER="1" PORT="ref0"> </TD></TR>
|
|
19
19
|
</TABLE>
|
|
20
20
|
> xlabel=dict]
|
|
21
|
-
|
|
21
|
+
node129652374079360:ref0 -> node129652371410960:table [style=solid]
|
|
22
22
|
}
|