memory-graph 0.3.8__tar.gz → 0.3.10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. {memory_graph-0.3.8/memory_graph.egg-info → memory_graph-0.3.10}/PKG-INFO +51 -17
  2. {memory_graph-0.3.8 → memory_graph-0.3.10}/README.md +50 -16
  3. memory_graph-0.3.10/images/add_one.png +0 -0
  4. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/add_one.py +4 -0
  5. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/avltree.py +4 -0
  6. memory_graph-0.3.10/images/bin_tree.png +0 -0
  7. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/bin_tree.py +4 -0
  8. memory_graph-0.3.10/images/copies.png +0 -0
  9. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/copies.py +4 -0
  10. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/copy_method.py +4 -0
  11. memory_graph-0.3.10/images/debugging.gif +0 -0
  12. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/debugging.py +4 -0
  13. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/extension_numpy.py +4 -0
  14. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/extension_pandas.py +4 -0
  15. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/factorial.py +4 -0
  16. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/hash_set.py +4 -0
  17. memory_graph-0.3.10/images/highlight.png +0 -0
  18. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/highlight.py +4 -0
  19. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/immutable.py +4 -0
  20. memory_graph-0.3.10/images/ipython.png +0 -0
  21. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/linked_list.py +4 -0
  22. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/many_types.py +4 -0
  23. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/mutable.py +4 -0
  24. memory_graph-0.3.10/images/power_set.gif +0 -0
  25. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/power_set.py +4 -0
  26. memory_graph-0.3.10/images/pyodide.png +0 -0
  27. {memory_graph-0.3.8 → memory_graph-0.3.10}/install.txt +2 -2
  28. memory_graph-0.3.10/memory_graph/__init__.py +249 -0
  29. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/config.py +5 -0
  30. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/config_default.py +8 -1
  31. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/config_helpers.py +4 -0
  32. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/extension_numpy.py +4 -0
  33. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/extension_pandas.py +4 -0
  34. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/html_table.py +4 -0
  35. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/list_view.py +4 -0
  36. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/memory_to_nodes.py +5 -2
  37. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/node_base.py +4 -0
  38. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/node_key_value.py +4 -0
  39. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/node_linear.py +4 -0
  40. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/node_table.py +4 -0
  41. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/sequence.py +4 -0
  42. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/slicer.py +4 -0
  43. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/slices.py +4 -0
  44. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/slices_iterator.py +4 -0
  45. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/slices_table_iterator.py +4 -0
  46. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/test.py +4 -0
  47. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/test_memory_graph.py +4 -0
  48. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/test_memory_to_nodes.py +4 -0
  49. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/test_sequence.py +4 -0
  50. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/test_slicer.py +4 -0
  51. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/test_slices.py +4 -0
  52. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/test_slices_iterator.py +4 -0
  53. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph/utils.py +4 -0
  54. {memory_graph-0.3.8 → memory_graph-0.3.10/memory_graph.egg-info}/PKG-INFO +51 -17
  55. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph.egg-info/SOURCES.txt +4 -2
  56. {memory_graph-0.3.8 → memory_graph-0.3.10}/setup.py +5 -1
  57. memory_graph-0.3.10/src/auto_memory_graph.py +18 -0
  58. memory_graph-0.3.10/src/pyodide.html +179 -0
  59. memory_graph-0.3.8/child_to_parent/main.py +0 -334
  60. memory_graph-0.3.8/images/add_one.png +0 -0
  61. memory_graph-0.3.8/images/bin_tree.png +0 -0
  62. memory_graph-0.3.8/images/copies.png +0 -0
  63. memory_graph-0.3.8/images/debugging.gif +0 -0
  64. memory_graph-0.3.8/images/highlight.png +0 -0
  65. memory_graph-0.3.8/images/power_set.gif +0 -0
  66. memory_graph-0.3.8/memory_graph/__init__.py +0 -161
  67. memory_graph-0.3.8/memory_graph/t.py +0 -15
  68. {memory_graph-0.3.8 → memory_graph-0.3.10}/LICENSE.txt +0 -0
  69. {memory_graph-0.3.8 → memory_graph-0.3.10}/MANIFEST.in +0 -0
  70. {memory_graph-0.3.8 → memory_graph-0.3.10}/TODO.txt +0 -0
  71. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/avltree_base.png +0 -0
  72. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/avltree_dir.png +0 -0
  73. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/avltree_fail.png +0 -0
  74. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/avltree_key_value.png +0 -0
  75. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/avltree_linear.png +0 -0
  76. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/avltree_table.png +0 -0
  77. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/copy_method.png +0 -0
  78. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/create_gif.sh +0 -0
  79. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/create_images.sh +0 -0
  80. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/extension_numpy.png +0 -0
  81. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/extension_pandas.png +0 -0
  82. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/factorial.gif +0 -0
  83. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/hash_set.png +0 -0
  84. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/immutable1.png +0 -0
  85. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/immutable2.png +0 -0
  86. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/jupyter_example.ipynb +0 -0
  87. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/jupyter_example.png +0 -0
  88. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/linked_list.png +0 -0
  89. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/many_types.png +0 -0
  90. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/mutable1.png +0 -0
  91. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/mutable2.png +0 -0
  92. {memory_graph-0.3.8 → memory_graph-0.3.10}/images/uva.png +0 -0
  93. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph.egg-info/dependency_links.txt +0 -0
  94. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph.egg-info/requires.txt +0 -0
  95. {memory_graph-0.3.8 → memory_graph-0.3.10}/memory_graph.egg-info/top_level.txt +0 -0
  96. {memory_graph-0.3.8 → memory_graph-0.3.10}/setup.cfg +0 -0
  97. {memory_graph-0.3.8 → memory_graph-0.3.10}/uml/memory_graph.uxf +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: memory_graph
3
- Version: 0.3.8
3
+ Version: 0.3.10
4
4
  Summary: Draws a graph of your data to analyze its structure.
5
5
  Home-page: https://github.com/bterwijn/memory_graph
6
6
  Author: Bas Terwijn
@@ -91,6 +91,7 @@ mg.render(data, "my_graph.pdf")
91
91
  mg.render(data, "my_graph.svg")
92
92
  mg.render(data, "my_graph.png")
93
93
  mg.render(data, "my_graph.gv") # Graphviz DOT file
94
+ mg.render(data) # renders to 'mg.render_filename' with default value: 'memory_graph.pdf'
94
95
  ```
95
96
 
96
97
  # Chapters #
@@ -111,6 +112,10 @@ mg.render(data, "my_graph.gv") # Graphviz DOT file
111
112
 
112
113
  [Jupyter Notebook](#jupyter-notebook)
113
114
 
115
+ [ipython](#ipython)
116
+
117
+ [In the Browser](#in-the-browser)
118
+
114
119
  [Troubleshooting](#troubleshooting)
115
120
 
116
121
 
@@ -151,7 +156,7 @@ mg.render(locals(), 'immutable2.png')
151
156
 
152
157
 
153
158
  ### Mutable Type ###
154
- With mutable types the result is different. In the code below variable `a` and `b` both reference the same `list` value [4, 3, 2]. A `list` is a mutable type and therefore when we change variable `a` its value **can** be mutated in place and thus `a` and `b` both reference the same new value afterwards. Thus changing `a` also changes `b` and vice versa. Sometimes we want this but other times we don't and then we will have to make a copy so that `b` is independent from `a`.
159
+ With mutable types the result is different. In the code below variable `a` and `b` both reference the same `list` value [4, 3, 2]. A `list` is a mutable type and therefore when we change variable `a` its value **can** be mutated in place and thus `a` and `b` both reference the same new value afterwards. Thus changing `a` also changes `b` and vice versa. Sometimes we want this but other times we don't and then we will have to make a copy so that `a` and `b` are independent.
155
160
 
156
161
  ```python
157
162
  import memory_graph as mg
@@ -166,7 +171,7 @@ mg.render(locals(), 'mutable2.png')
166
171
  |:-----------------------------------------------------------:|:-------------------------------------------------------------:|
167
172
  | mutable1.png | mutable2.png |
168
173
 
169
- One practical reason why Python makes the distinction between mutable and immutable types is that a value of a mutable type could be large, making it inefficient to copy each time we change it. Immutable values generally don't need to change as much or are smaller, which makes copying less of a concern.
174
+ One practical reason why Python makes the distinction between mutable and immutable types is that a value of a mutable type can be large, making it inefficient to copy each time we change it. Immutable values generally don't need to change as much, or are small which makes copying less of a concern.
170
175
 
171
176
  ### Copying ###
172
177
  Python offers three different "copy" options that we will demonstrate using a nested list:
@@ -219,7 +224,7 @@ mg.show(locals())
219
224
 
220
225
 
221
226
  ## Call Stack ##
222
- The `mg.get_call_stack()` function retrieves the entire call stack, including the local variables for each function on the stack. This enables us to visualize the local variables across all active functions simultaneously. Then by examining the graph, we can determine whether any local variables from different functions on the call stack share data. For instance, consider the function `add_one()` which adds the value `1` to each of its parameters, `a`, `b`, and `c`.
227
+ The `mg.get_call_stack()` function retrieves the entire call stack, including the local variables for each function on the stack. This enables us to visualize the local variables across all active functions simultaneously. Then by examining the graph, we can determine whether any local variables from different functions on the call stack share data. For instance, consider the function `add_one()` which adds the value `1` to each of its parameters `a`, `b`, and `c`.
223
228
 
224
229
  ```python
225
230
  import memory_graph as mg
@@ -250,10 +255,18 @@ This is because `b` is of immutable type 'tuple' so its value gets copied automa
250
255
  It is often helpful to temporarily block program execution to inspect the graph. For this, you can use the `mg.block()` function:
251
256
 
252
257
  ```python
253
- mg.block(fun, arg1, arg2, ..., loc=True)
258
+ mg.block(fun, arg1, arg2, ...)
254
259
  ```
255
260
 
256
- This function first executes `fun(arg1, arg2, ...)`, then prints the current source location in the program, and blocks execution until the <Enter> key is pressed. To skip printing the source location, set `loc=False`.
261
+ This function:
262
+ * first executes `fun(arg1, arg2, ...)`
263
+ * then prints the current source location in the program
264
+ * then blocks execution until the <Enter> key is pressed
265
+ * finally returns the value of the `fun()` call
266
+
267
+ to change it's behavior:
268
+ * Set `mg.block_prints_location = False` to skip printing the source location.
269
+ * Set `mg.press_enter_message = None` to skip printing "Press <Enter> to continue...".
257
270
 
258
271
  ### Recursion ###
259
272
  The call stack is also helpful to visualize how recursion works. Here we use `mg.block()` to show each step of how recursively ```factorial(3)``` is computed:
@@ -336,12 +349,20 @@ mg.get_call_stack_after_up_to(after_function, up_to_function="<module>")
336
349
 
337
350
  ### Debugging without Debugger Tool ###
338
351
 
339
- To simplify debugging without a debugger tool, we offer these blocking alias functions that you can insert into your code at a specific point to visualize a graph:
352
+ To simplify debugging without a debugger tool, we offer these alias functions that you can insert into your code at the point where you want to visualize a graph:
340
353
 
341
354
  | alias | purpose | function call |
342
355
  |:---|:---|:---|
343
- | `mg.l()` | graph **l**ocal variables and block | `mg.block(mg.show, locals())` |
344
- | `mg.s()` | graph the call **s**tack and block | `mg.block(mg.show, mg.get_call_stack())` |
356
+ | `mg.sl()` | **s**how **l**ocal variables | `mg.show(locals())` |
357
+ | `mg.ss()` | **s**how the call **s**tack | `mg.show(mg.get_call_stack())` |
358
+ | `mg.bsl()` | **b**lock after **s**howing **l**ocal variables | `mg.block(mg.show, locals())` |
359
+ | `mg.bss()` | **b**lock after **s**howing the call **s**tack | `mg.block(mg.show, mg.get_call_stack())` |
360
+ | `mg.rl()` | **r**ender **l**ocal variables | `mg.render(locals())` |
361
+ | `mg.rs()` | **r**ender the call **s**tack | `mg.render(mg.get_call_stack())` |
362
+ | `mg.brl()` | **b**lock after **r**endering **l**ocal variables | `mg.block(mg.render, locals())` |
363
+ | `mg.brs()` | **b**lock after **r**endering the call **s**tack | `mg.block(mg.render, mg.get_call_stack())` |
364
+ | `mg.l()` | same as `mg.bsl()` | |
365
+ | `mg.s()` | same as `mg.bss()` | |
345
366
 
346
367
  For example, executing this program:
347
368
 
@@ -353,7 +374,7 @@ squares_collector = []
353
374
  for i in range(1, 6):
354
375
  squares.append(i**2)
355
376
  squares_collector.append(squares.copy())
356
- mg.l() # graph local variables
377
+ mg.l() # block after showing local variables
357
378
  ```
358
379
  and pressing &lt;Enter&gt; a number of times, results in:
359
380
 
@@ -568,7 +589,7 @@ mg.show(locals())
568
589
  ![extension_pandas.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_pandas.png)
569
590
 
570
591
  ## Introspection ##
571
- This section is likely to change. 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:
592
+ This section is likely to change. 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.
572
593
 
573
594
  ```python
574
595
  import memory_graph as mg
@@ -587,7 +608,7 @@ mg.show(locals())
587
608
 
588
609
 
589
610
  ### dir() ###
590
- A usefull start is to give it some color, show the list of all its attributes using `dir()`, and setting an empty Slicer to see the attribute list in full.
611
+ A useful start is to give it some color, show the list of all its attributes using `dir()`, and setting an empty Slicer to see the attribute list in full.
591
612
 
592
613
  ```python
593
614
  import memory_graph as mg
@@ -609,9 +630,9 @@ mg.show(locals())
609
630
  ```
610
631
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_dir.png)
611
632
 
612
- Next figure out what are the attributes you want to graph and choose a Node type, there are four options.
633
+ Next figure out what are the attributes you want to graph and choose a Node type, there are four options:
613
634
 
614
- ### 1 Node_Base ###
635
+ ### 1) Node_Base ###
615
636
  Node_base is a leaf node (with no children) and shows just a single value.
616
637
  ```python
617
638
  import memory_graph as mg
@@ -631,7 +652,7 @@ mg.show(locals())
631
652
  ```
632
653
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_base.png)
633
654
 
634
- ### 2 Node_Linear ###
655
+ ### 2) Node_Linear ###
635
656
  Node_Linear shows all the values in a line like a list.
636
657
  ```python
637
658
  import memory_graph as mg
@@ -655,7 +676,7 @@ mg.show(locals())
655
676
  ```
656
677
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_linear.png)
657
678
 
658
- ### 3 Node_Key_Value ###
679
+ ### 3) Node_Key_Value ###
659
680
  Node_Key_Value shows key-value pairs like a dictionary. Note the required `items()` call at the end.
660
681
  ```python
661
682
  import memory_graph as mg
@@ -679,7 +700,7 @@ mg.show(locals())
679
700
  ```
680
701
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_key_value.png)
681
702
 
682
- ### 4 Node_Table ###
703
+ ### 4) Node_Table ###
683
704
  Node_Table shows all the values as a table.
684
705
  ```python
685
706
  import memory_graph as mg
@@ -716,6 +737,19 @@ mg.block(display, mg.create_graph(mg.locals_jupyter()) ) # the same but blocked
716
737
  See for example [jupyter_example.ipynb](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/jupyter_example.ipynb).
717
738
  ![jupyter_example.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/jupyter_example.png)
718
739
 
740
+ ## ipython ##
741
+ In ipython `locals()` has additional variables that cause problems in the graph, use `mg.locals_ipython()` to get the local variables with these problematic variables filtered out. Use `mg.get_call_stack_ipython()` to get the whole call stack with these variables filtered out.
742
+
743
+ Additionally install file [auto_memory_graph.py](https://raw.githubusercontent.com/bterwijn/memory_graph/main/sc/auto_memory_graph.py) in the ipython startup directory:
744
+ * Linux/Mac: ~/.ipython/profile_default/startup/
745
+ * Windows: %USERPROFILE%\.ipython\profile_default\startup\
746
+
747
+ Then after starting 'ipython' call function `mg_switch()` to turn on/off the automatic visualization of local variables after each command.
748
+ ![ipyton.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/ipython.png)
749
+
750
+ ## In the Browser ##
751
+ We can run memory_graph in the browser: <a href="https://bterwijn.github.io/memory_graph/src/pyodide.html" target="_blank">Pyodide Example</a>
752
+ ![pyodide.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/pyodide.png)
719
753
 
720
754
  ## Troubleshooting ##
721
755
 
@@ -72,6 +72,7 @@ mg.render(data, "my_graph.pdf")
72
72
  mg.render(data, "my_graph.svg")
73
73
  mg.render(data, "my_graph.png")
74
74
  mg.render(data, "my_graph.gv") # Graphviz DOT file
75
+ mg.render(data) # renders to 'mg.render_filename' with default value: 'memory_graph.pdf'
75
76
  ```
76
77
 
77
78
  # Chapters #
@@ -92,6 +93,10 @@ mg.render(data, "my_graph.gv") # Graphviz DOT file
92
93
 
93
94
  [Jupyter Notebook](#jupyter-notebook)
94
95
 
96
+ [ipython](#ipython)
97
+
98
+ [In the Browser](#in-the-browser)
99
+
95
100
  [Troubleshooting](#troubleshooting)
96
101
 
97
102
 
@@ -132,7 +137,7 @@ mg.render(locals(), 'immutable2.png')
132
137
 
133
138
 
134
139
  ### Mutable Type ###
135
- With mutable types the result is different. In the code below variable `a` and `b` both reference the same `list` value [4, 3, 2]. A `list` is a mutable type and therefore when we change variable `a` its value **can** be mutated in place and thus `a` and `b` both reference the same new value afterwards. Thus changing `a` also changes `b` and vice versa. Sometimes we want this but other times we don't and then we will have to make a copy so that `b` is independent from `a`.
140
+ With mutable types the result is different. In the code below variable `a` and `b` both reference the same `list` value [4, 3, 2]. A `list` is a mutable type and therefore when we change variable `a` its value **can** be mutated in place and thus `a` and `b` both reference the same new value afterwards. Thus changing `a` also changes `b` and vice versa. Sometimes we want this but other times we don't and then we will have to make a copy so that `a` and `b` are independent.
136
141
 
137
142
  ```python
138
143
  import memory_graph as mg
@@ -147,7 +152,7 @@ mg.render(locals(), 'mutable2.png')
147
152
  |:-----------------------------------------------------------:|:-------------------------------------------------------------:|
148
153
  | mutable1.png | mutable2.png |
149
154
 
150
- One practical reason why Python makes the distinction between mutable and immutable types is that a value of a mutable type could be large, making it inefficient to copy each time we change it. Immutable values generally don't need to change as much or are smaller, which makes copying less of a concern.
155
+ One practical reason why Python makes the distinction between mutable and immutable types is that a value of a mutable type can be large, making it inefficient to copy each time we change it. Immutable values generally don't need to change as much, or are small which makes copying less of a concern.
151
156
 
152
157
  ### Copying ###
153
158
  Python offers three different "copy" options that we will demonstrate using a nested list:
@@ -200,7 +205,7 @@ mg.show(locals())
200
205
 
201
206
 
202
207
  ## Call Stack ##
203
- The `mg.get_call_stack()` function retrieves the entire call stack, including the local variables for each function on the stack. This enables us to visualize the local variables across all active functions simultaneously. Then by examining the graph, we can determine whether any local variables from different functions on the call stack share data. For instance, consider the function `add_one()` which adds the value `1` to each of its parameters, `a`, `b`, and `c`.
208
+ The `mg.get_call_stack()` function retrieves the entire call stack, including the local variables for each function on the stack. This enables us to visualize the local variables across all active functions simultaneously. Then by examining the graph, we can determine whether any local variables from different functions on the call stack share data. For instance, consider the function `add_one()` which adds the value `1` to each of its parameters `a`, `b`, and `c`.
204
209
 
205
210
  ```python
206
211
  import memory_graph as mg
@@ -231,10 +236,18 @@ This is because `b` is of immutable type 'tuple' so its value gets copied automa
231
236
  It is often helpful to temporarily block program execution to inspect the graph. For this, you can use the `mg.block()` function:
232
237
 
233
238
  ```python
234
- mg.block(fun, arg1, arg2, ..., loc=True)
239
+ mg.block(fun, arg1, arg2, ...)
235
240
  ```
236
241
 
237
- This function first executes `fun(arg1, arg2, ...)`, then prints the current source location in the program, and blocks execution until the &lt;Enter&gt; key is pressed. To skip printing the source location, set `loc=False`.
242
+ This function:
243
+ * first executes `fun(arg1, arg2, ...)`
244
+ * then prints the current source location in the program
245
+ * then blocks execution until the &lt;Enter&gt; key is pressed
246
+ * finally returns the value of the `fun()` call
247
+
248
+ to change it's behavior:
249
+ * Set `mg.block_prints_location = False` to skip printing the source location.
250
+ * Set `mg.press_enter_message = None` to skip printing "Press &lt;Enter&gt; to continue...".
238
251
 
239
252
  ### Recursion ###
240
253
  The call stack is also helpful to visualize how recursion works. Here we use `mg.block()` to show each step of how recursively ```factorial(3)``` is computed:
@@ -317,12 +330,20 @@ mg.get_call_stack_after_up_to(after_function, up_to_function="<module>")
317
330
 
318
331
  ### Debugging without Debugger Tool ###
319
332
 
320
- To simplify debugging without a debugger tool, we offer these blocking alias functions that you can insert into your code at a specific point to visualize a graph:
333
+ To simplify debugging without a debugger tool, we offer these alias functions that you can insert into your code at the point where you want to visualize a graph:
321
334
 
322
335
  | alias | purpose | function call |
323
336
  |:---|:---|:---|
324
- | `mg.l()` | graph **l**ocal variables and block | `mg.block(mg.show, locals())` |
325
- | `mg.s()` | graph the call **s**tack and block | `mg.block(mg.show, mg.get_call_stack())` |
337
+ | `mg.sl()` | **s**how **l**ocal variables | `mg.show(locals())` |
338
+ | `mg.ss()` | **s**how the call **s**tack | `mg.show(mg.get_call_stack())` |
339
+ | `mg.bsl()` | **b**lock after **s**howing **l**ocal variables | `mg.block(mg.show, locals())` |
340
+ | `mg.bss()` | **b**lock after **s**howing the call **s**tack | `mg.block(mg.show, mg.get_call_stack())` |
341
+ | `mg.rl()` | **r**ender **l**ocal variables | `mg.render(locals())` |
342
+ | `mg.rs()` | **r**ender the call **s**tack | `mg.render(mg.get_call_stack())` |
343
+ | `mg.brl()` | **b**lock after **r**endering **l**ocal variables | `mg.block(mg.render, locals())` |
344
+ | `mg.brs()` | **b**lock after **r**endering the call **s**tack | `mg.block(mg.render, mg.get_call_stack())` |
345
+ | `mg.l()` | same as `mg.bsl()` | |
346
+ | `mg.s()` | same as `mg.bss()` | |
326
347
 
327
348
  For example, executing this program:
328
349
 
@@ -334,7 +355,7 @@ squares_collector = []
334
355
  for i in range(1, 6):
335
356
  squares.append(i**2)
336
357
  squares_collector.append(squares.copy())
337
- mg.l() # graph local variables
358
+ mg.l() # block after showing local variables
338
359
  ```
339
360
  and pressing &lt;Enter&gt; a number of times, results in:
340
361
 
@@ -549,7 +570,7 @@ mg.show(locals())
549
570
  ![extension_pandas.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_pandas.png)
550
571
 
551
572
  ## Introspection ##
552
- This section is likely to change. 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:
573
+ This section is likely to change. 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.
553
574
 
554
575
  ```python
555
576
  import memory_graph as mg
@@ -568,7 +589,7 @@ mg.show(locals())
568
589
 
569
590
 
570
591
  ### dir() ###
571
- A usefull start is to give it some color, show the list of all its attributes using `dir()`, and setting an empty Slicer to see the attribute list in full.
592
+ A useful start is to give it some color, show the list of all its attributes using `dir()`, and setting an empty Slicer to see the attribute list in full.
572
593
 
573
594
  ```python
574
595
  import memory_graph as mg
@@ -590,9 +611,9 @@ mg.show(locals())
590
611
  ```
591
612
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_dir.png)
592
613
 
593
- Next figure out what are the attributes you want to graph and choose a Node type, there are four options.
614
+ Next figure out what are the attributes you want to graph and choose a Node type, there are four options:
594
615
 
595
- ### 1 Node_Base ###
616
+ ### 1) Node_Base ###
596
617
  Node_base is a leaf node (with no children) and shows just a single value.
597
618
  ```python
598
619
  import memory_graph as mg
@@ -612,7 +633,7 @@ mg.show(locals())
612
633
  ```
613
634
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_base.png)
614
635
 
615
- ### 2 Node_Linear ###
636
+ ### 2) Node_Linear ###
616
637
  Node_Linear shows all the values in a line like a list.
617
638
  ```python
618
639
  import memory_graph as mg
@@ -636,7 +657,7 @@ mg.show(locals())
636
657
  ```
637
658
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_linear.png)
638
659
 
639
- ### 3 Node_Key_Value ###
660
+ ### 3) Node_Key_Value ###
640
661
  Node_Key_Value shows key-value pairs like a dictionary. Note the required `items()` call at the end.
641
662
  ```python
642
663
  import memory_graph as mg
@@ -660,7 +681,7 @@ mg.show(locals())
660
681
  ```
661
682
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_key_value.png)
662
683
 
663
- ### 4 Node_Table ###
684
+ ### 4) Node_Table ###
664
685
  Node_Table shows all the values as a table.
665
686
  ```python
666
687
  import memory_graph as mg
@@ -697,6 +718,19 @@ mg.block(display, mg.create_graph(mg.locals_jupyter()) ) # the same but blocked
697
718
  See for example [jupyter_example.ipynb](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/jupyter_example.ipynb).
698
719
  ![jupyter_example.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/jupyter_example.png)
699
720
 
721
+ ## ipython ##
722
+ In ipython `locals()` has additional variables that cause problems in the graph, use `mg.locals_ipython()` to get the local variables with these problematic variables filtered out. Use `mg.get_call_stack_ipython()` to get the whole call stack with these variables filtered out.
723
+
724
+ Additionally install file [auto_memory_graph.py](https://raw.githubusercontent.com/bterwijn/memory_graph/main/sc/auto_memory_graph.py) in the ipython startup directory:
725
+ * Linux/Mac: ~/.ipython/profile_default/startup/
726
+ * Windows: %USERPROFILE%\.ipython\profile_default\startup\
727
+
728
+ Then after starting 'ipython' call function `mg_switch()` to turn on/off the automatic visualization of local variables after each command.
729
+ ![ipyton.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/ipython.png)
730
+
731
+ ## In the Browser ##
732
+ We can run memory_graph in the browser: <a href="https://bterwijn.github.io/memory_graph/src/pyodide.html" target="_blank">Pyodide Example</a>
733
+ ![pyodide.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/pyodide.png)
700
734
 
701
735
  ## Troubleshooting ##
702
736
 
Binary file
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
 
3
7
  def add_one(a, b, c):
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
  import bintrees
3
7
 
Binary file
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
  import random
3
7
  random.seed(0) # use same random numbers each run
Binary file
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
  import copy
3
7
 
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
  import copy
3
7
 
Binary file
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
 
3
7
  image=0
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
  import numpy as np
3
7
  import memory_graph.extension_numpy
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
  import pandas as pd
3
7
  import memory_graph.extension_pandas
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
 
3
7
  image=0
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
  import random
3
7
  random.seed(0) # use same random numbers each run
Binary file
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
  from memory_graph.slicer import Slicer
3
7
 
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
 
3
7
  a = (4, 3, 2)
Binary file
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
  import random
3
7
  random.seed(0) # use same random numbers each run
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
 
3
7
  class MyClass:
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
 
3
7
  a = [4, 3, 2]
Binary file
@@ -1,3 +1,7 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
1
5
  import memory_graph as mg
2
6
 
3
7
  image = 1
Binary file
@@ -14,10 +14,10 @@ pip install --upgrade .
14
14
 
15
15
 
16
16
  # ===== prepare packages for upload
17
- # - increase version number in setup.py and memory_graph/__init__.py before each upload
17
+ # - increase version number in: setup.py memory_graph/__init__.py
18
18
  # - update images:
19
19
  cd images; bash create_images.sh; cd ..
20
- # - git commit -am "version X.X.X"
20
+ # - git commit -am "version X.X.X" && git push
21
21
  rm -f ./dist/*
22
22
  python setup.py check
23
23
  python setup.py sdist