memory-graph 0.3.54__tar.gz → 0.3.56__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.54/memory_graph.egg-info → memory_graph-0.3.56}/PKG-INFO +39 -9
- {memory_graph-0.3.54 → memory_graph-0.3.56}/README.md +38 -8
- memory_graph-0.3.56/images/add_one.png +0 -0
- memory_graph-0.3.56/images/avltree_key_value.png +0 -0
- memory_graph-0.3.56/images/avltree_leaf.png +0 -0
- memory_graph-0.3.56/images/avltree_linear.png +0 -0
- memory_graph-0.3.56/images/avltree_table.png +0 -0
- memory_graph-0.3.56/images/bin_search.png +0 -0
- memory_graph-0.3.56/images/bin_search_linear.png +0 -0
- memory_graph-0.3.56/images/bin_tree.png +0 -0
- memory_graph-0.3.56/images/binary.gif +0 -0
- memory_graph-0.3.56/images/copy_immutable.png +0 -0
- memory_graph-0.3.56/images/copy_method.png +0 -0
- memory_graph-0.3.56/images/copy_mix.png +0 -0
- memory_graph-0.3.56/images/copy_mutable.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/create_images.sh +1 -0
- memory_graph-0.3.56/images/debugging.gif +0 -0
- memory_graph-0.3.56/images/embedded1.png +0 -0
- memory_graph-0.3.56/images/embedded2.png +0 -0
- memory_graph-0.3.56/images/extension_numpy.png +0 -0
- memory_graph-0.3.56/images/extension_pandas.png +0 -0
- memory_graph-0.3.56/images/factorial.gif +0 -0
- memory_graph-0.3.56/images/hash_set.png +0 -0
- memory_graph-0.3.56/images/hidden_edges.png +0 -0
- memory_graph-0.3.56/images/immutable1.png +0 -0
- memory_graph-0.3.56/images/immutable2.png +0 -0
- memory_graph-0.3.56/images/introspect_depth.png +0 -0
- memory_graph-0.3.56/images/linked_list.png +0 -0
- memory_graph-0.3.56/images/many_types.png +0 -0
- memory_graph-0.3.56/images/mutable1.png +0 -0
- memory_graph-0.3.56/images/mutable2.png +0 -0
- memory_graph-0.3.56/images/power_set.gif +0 -0
- memory_graph-0.3.56/images/rebinding1.png +0 -0
- memory_graph-0.3.56/images/rebinding2.png +0 -0
- memory_graph-0.3.56/images/wrap_int.png +0 -0
- memory_graph-0.3.56/images/wrap_int.py +16 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/__init__.py +1 -1
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/memory_to_nodes.py +3 -3
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/utils.py +1 -1
- {memory_graph-0.3.54 → memory_graph-0.3.56/memory_graph.egg-info}/PKG-INFO +39 -9
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph.egg-info/SOURCES.txt +2 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/pyproject.toml +1 -1
- memory_graph-0.3.54/images/add_one.png +0 -0
- memory_graph-0.3.54/images/avltree_key_value.png +0 -0
- memory_graph-0.3.54/images/avltree_leaf.png +0 -0
- memory_graph-0.3.54/images/avltree_linear.png +0 -0
- memory_graph-0.3.54/images/avltree_table.png +0 -0
- memory_graph-0.3.54/images/bin_search.png +0 -0
- memory_graph-0.3.54/images/bin_search_linear.png +0 -0
- memory_graph-0.3.54/images/bin_tree.png +0 -0
- memory_graph-0.3.54/images/binary.gif +0 -0
- memory_graph-0.3.54/images/copy_immutable.png +0 -0
- memory_graph-0.3.54/images/copy_method.png +0 -0
- memory_graph-0.3.54/images/copy_mix.png +0 -0
- memory_graph-0.3.54/images/copy_mutable.png +0 -0
- memory_graph-0.3.54/images/debugging.gif +0 -0
- memory_graph-0.3.54/images/embedded1.png +0 -0
- memory_graph-0.3.54/images/embedded2.png +0 -0
- memory_graph-0.3.54/images/extension_numpy.png +0 -0
- memory_graph-0.3.54/images/extension_pandas.png +0 -0
- memory_graph-0.3.54/images/factorial.gif +0 -0
- memory_graph-0.3.54/images/hash_set.png +0 -0
- memory_graph-0.3.54/images/hidden_edges.png +0 -0
- memory_graph-0.3.54/images/immutable1.png +0 -0
- memory_graph-0.3.54/images/immutable2.png +0 -0
- memory_graph-0.3.54/images/introspect_depth.png +0 -0
- memory_graph-0.3.54/images/linked_list.png +0 -0
- memory_graph-0.3.54/images/many_types.png +0 -0
- memory_graph-0.3.54/images/mutable1.png +0 -0
- memory_graph-0.3.54/images/mutable2.png +0 -0
- memory_graph-0.3.54/images/power_set.gif +0 -0
- memory_graph-0.3.54/images/rebinding1.png +0 -0
- memory_graph-0.3.54/images/rebinding2.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/LICENSE.txt +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/MANIFEST.in +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/add_one.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/avltree.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/avltree_dir.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/avltree_fail.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/bin_search.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/bin_tree.gif +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/bin_tree.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/binary.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/colab_example.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/copy_immutable.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/copy_method.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/copy_mix.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/copy_mutable.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/create_gif.sh +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/debug_vscode.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/debugging.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/extension_numpy.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/extension_pandas.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/extension_torch.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/extension_torch.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/factorial.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/hash_set.gif +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/hash_set.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/hidden_edges.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/immutable.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/introspect_depth.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/ipython.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/jupyter_example.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/linked_list.gif +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/linked_list.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/many_types.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/marimo_example.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/memory_graph_web_debugger.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/mutable.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/name_rebinding.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/not_node_types.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/power_set.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/uva.png +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/images/vscode_copying.gif +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/call_stack.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/config.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/config_default.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/config_helpers.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/extension_numpy.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/extension_pandas.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/extension_torch.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/html_table.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/list_view.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/node_base.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/node_key_value.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/node_leaf.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/node_linear.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/node_table.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/sequence.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/slicer.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/slices.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/slices_iterator.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/slices_table_iterator.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/test.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/test_max_graph_depth.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/test_memory_graph.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/test_memory_to_nodes.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/test_sequence.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/test_slicer.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/test_slices.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph/test_slices_iterator.py +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph.egg-info/dependency_links.txt +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph.egg-info/requires.txt +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/memory_graph.egg-info/top_level.txt +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/setup.cfg +0 -0
- {memory_graph-0.3.54 → memory_graph-0.3.56}/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.56
|
|
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
|
|
@@ -58,6 +58,10 @@ Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph
|
|
|
58
58
|
- **visualize the structure of your data** to easily understand and debug any data structure
|
|
59
59
|
- understand function calls, variable scope, and the **complete program state** through call stack visualization
|
|
60
60
|
|
|
61
|
+
An example Binary Tree data structure:
|
|
62
|
+

|
|
63
|
+
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_tree.py×tep=0.2&play).
|
|
64
|
+
|
|
61
65
|
# Videos #
|
|
62
66
|
| [](https://www.youtube.com/watch?v=23_bHcr7hqo) | [](https://www.youtube.com/watch?v=pvIJgHCaXhU) |
|
|
63
67
|
|:--:|:--:|
|
|
@@ -132,7 +136,7 @@ identical?: True
|
|
|
132
136
|
```
|
|
133
137
|
A better way to understand what values are shared is to draw a graph using [memory_graph](https://pypi.org/project/memory-graph/).
|
|
134
138
|
|
|
135
|
-
#
|
|
139
|
+
# Topics #
|
|
136
140
|
|
|
137
141
|
[Python Data Model](#python-data-model)
|
|
138
142
|
|
|
@@ -173,8 +177,8 @@ Bas Terwijn
|
|
|
173
177
|
Inspired by [Python Tutor](https://pythontutor.com/).
|
|
174
178
|
|
|
175
179
|
## Social Media #
|
|
176
|
-
* LinkedIn
|
|
177
|
-
* Reddit
|
|
180
|
+
* [LinkedIn](https://www.linkedin.com/groups/13244150/)
|
|
181
|
+
* [Reddit](https://www.reddit.com/r/Python_memory_graph/)
|
|
178
182
|
|
|
179
183
|
## Supported by ##
|
|
180
184
|
<img src="https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/uva.png" alt="University of Amsterdam" width="600">
|
|
@@ -358,9 +362,33 @@ In the printed output only `a` is changed as a result of the function call:
|
|
|
358
362
|
```
|
|
359
363
|
a:[4, 3, 2, 1] b:(4, 3, 2) c:[4, 3, 2]
|
|
360
364
|
```
|
|
361
|
-
|
|
362
365
|
This is because `b` is of immutable type 'tuple' so its value gets copied automatically when it is changed. And because the function is called with a copy of `c`, its original value is not changed by the function. The value of variable `a` is the only value of mutable type that is shared between the root stack frame **'0: \<module>'** and the **'1: add_one'** stack frame of the function so only that variable is affected as a result of the function call. The other changes remain confined to the local variables of the ```add_one()``` function.
|
|
363
366
|
|
|
367
|
+
## Function Call That Changes 'int' Value ##
|
|
368
|
+
Even though `int` is an immutable type, so an `int` value can not be changed by directly passing it to a function, we can still change it by wrapping it in a mutable container.
|
|
369
|
+
|
|
370
|
+
```python
|
|
371
|
+
import memory_graph as mg
|
|
372
|
+
|
|
373
|
+
def add_one(a, b):
|
|
374
|
+
a += 1 # change remains confined to 'a' in the add_one function
|
|
375
|
+
b[0] += 1 # change also effects 'b' outside of the add_one function
|
|
376
|
+
mg.show(mg.stack())
|
|
377
|
+
|
|
378
|
+
a = 10
|
|
379
|
+
b = [10] # wrap in a value of mutable type list
|
|
380
|
+
add_one(a, b)
|
|
381
|
+
|
|
382
|
+
print(f"a:{a} b:{b[0]}")
|
|
383
|
+
```
|
|
384
|
+

|
|
385
|
+
```
|
|
386
|
+
a:10 b:11
|
|
387
|
+
```
|
|
388
|
+
Calling `add_one()` does not effect the `int` value of `a` but does effect the `int` value of `b` because it's wrapped in a mutable container.
|
|
389
|
+
|
|
390
|
+
## Exercises ##
|
|
391
|
+
|
|
364
392
|
Now is a good time to practice the Python Data Model. Here are [some exercises](https://github.com/bterwijn/memory_graph_videos/blob/main/exercises/exercises.md) on references, mutability, copies, and function calls.
|
|
365
393
|
|
|
366
394
|
## Block ##
|
|
@@ -398,8 +426,8 @@ and the result is: 1 x 2 x 3 x 4 = 24
|
|
|
398
426
|
|
|
399
427
|
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/factorial.py×tep=1.0&play).
|
|
400
428
|
|
|
401
|
-
## Binary
|
|
402
|
-
A more interesting recursive example is function `binary()` that converts a decimal
|
|
429
|
+
## Binary Conversion ##
|
|
430
|
+
A more interesting recursive example is function `binary()` that converts a integer from decimal to binary representation.
|
|
403
431
|
```python
|
|
404
432
|
import memory_graph as mg
|
|
405
433
|
mg.config.type_to_horizontal[list] = True # horizontal lists
|
|
@@ -417,7 +445,7 @@ print( binary(100) )
|
|
|
417
445
|
```
|
|
418
446
|

|
|
419
447
|
```
|
|
420
|
-
|
|
448
|
+
[1, 1, 0, 0, 1, 0, 0]
|
|
421
449
|
```
|
|
422
450
|
|
|
423
451
|
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/binary_convert.py×tep=1.0&play).
|
|
@@ -452,6 +480,8 @@ print( power_set(['a', 'b', 'c']) )
|
|
|
452
480
|
[['a', 'b', 'c'], ['a', 'b'], ['a', 'c'], ['a'], ['b', 'c'], ['b'], ['c'], []]
|
|
453
481
|
```
|
|
454
482
|
|
|
483
|
+
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/power_set.py×tep=1.0&play).
|
|
484
|
+
|
|
455
485
|
# Debugging #
|
|
456
486
|
|
|
457
487
|
For the best debugging experience with memory_graph set for example expression:
|
|
@@ -1101,7 +1131,7 @@ $ bash create_gif.sh animated
|
|
|
1101
1131
|
```
|
|
1102
1132
|
|
|
1103
1133
|
# Troubleshooting #
|
|
1104
|
-
- Adobe Acrobat Reader [doesn't refresh a PDF file](https://community.adobe.com/t5/acrobat-reader-discussions/reload-refresh-pdfs/td-p/9632292) when it changes on disk and blocks updates which results in an `Could not open '
|
|
1134
|
+
- Adobe Acrobat Reader [doesn't refresh a PDF file](https://community.adobe.com/t5/acrobat-reader-discussions/reload-refresh-pdfs/td-p/9632292) when it changes on disk and blocks updates which results in an `Could not open 'memory_graph.pdf' for writing : Permission denied` error. One solution is to install a PDF reader that does refresh ([SumatraPDF](https://www.sumatrapdfreader.org/), [Okular](https://okular.kde.org/), ...) and set it as your default PDF reader. Another solution is to `render()` the graph to a different output format.
|
|
1105
1135
|
|
|
1106
1136
|
- 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.
|
|
1107
1137
|
|
|
@@ -13,6 +13,10 @@ Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph
|
|
|
13
13
|
- **visualize the structure of your data** to easily understand and debug any data structure
|
|
14
14
|
- understand function calls, variable scope, and the **complete program state** through call stack visualization
|
|
15
15
|
|
|
16
|
+
An example Binary Tree data structure:
|
|
17
|
+

|
|
18
|
+
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_tree.py×tep=0.2&play).
|
|
19
|
+
|
|
16
20
|
# Videos #
|
|
17
21
|
| [](https://www.youtube.com/watch?v=23_bHcr7hqo) | [](https://www.youtube.com/watch?v=pvIJgHCaXhU) |
|
|
18
22
|
|:--:|:--:|
|
|
@@ -87,7 +91,7 @@ identical?: True
|
|
|
87
91
|
```
|
|
88
92
|
A better way to understand what values are shared is to draw a graph using [memory_graph](https://pypi.org/project/memory-graph/).
|
|
89
93
|
|
|
90
|
-
#
|
|
94
|
+
# Topics #
|
|
91
95
|
|
|
92
96
|
[Python Data Model](#python-data-model)
|
|
93
97
|
|
|
@@ -128,8 +132,8 @@ Bas Terwijn
|
|
|
128
132
|
Inspired by [Python Tutor](https://pythontutor.com/).
|
|
129
133
|
|
|
130
134
|
## Social Media #
|
|
131
|
-
* LinkedIn
|
|
132
|
-
* Reddit
|
|
135
|
+
* [LinkedIn](https://www.linkedin.com/groups/13244150/)
|
|
136
|
+
* [Reddit](https://www.reddit.com/r/Python_memory_graph/)
|
|
133
137
|
|
|
134
138
|
## Supported by ##
|
|
135
139
|
<img src="https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/uva.png" alt="University of Amsterdam" width="600">
|
|
@@ -313,9 +317,33 @@ In the printed output only `a` is changed as a result of the function call:
|
|
|
313
317
|
```
|
|
314
318
|
a:[4, 3, 2, 1] b:(4, 3, 2) c:[4, 3, 2]
|
|
315
319
|
```
|
|
316
|
-
|
|
317
320
|
This is because `b` is of immutable type 'tuple' so its value gets copied automatically when it is changed. And because the function is called with a copy of `c`, its original value is not changed by the function. The value of variable `a` is the only value of mutable type that is shared between the root stack frame **'0: \<module>'** and the **'1: add_one'** stack frame of the function so only that variable is affected as a result of the function call. The other changes remain confined to the local variables of the ```add_one()``` function.
|
|
318
321
|
|
|
322
|
+
## Function Call That Changes 'int' Value ##
|
|
323
|
+
Even though `int` is an immutable type, so an `int` value can not be changed by directly passing it to a function, we can still change it by wrapping it in a mutable container.
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
import memory_graph as mg
|
|
327
|
+
|
|
328
|
+
def add_one(a, b):
|
|
329
|
+
a += 1 # change remains confined to 'a' in the add_one function
|
|
330
|
+
b[0] += 1 # change also effects 'b' outside of the add_one function
|
|
331
|
+
mg.show(mg.stack())
|
|
332
|
+
|
|
333
|
+
a = 10
|
|
334
|
+
b = [10] # wrap in a value of mutable type list
|
|
335
|
+
add_one(a, b)
|
|
336
|
+
|
|
337
|
+
print(f"a:{a} b:{b[0]}")
|
|
338
|
+
```
|
|
339
|
+

|
|
340
|
+
```
|
|
341
|
+
a:10 b:11
|
|
342
|
+
```
|
|
343
|
+
Calling `add_one()` does not effect the `int` value of `a` but does effect the `int` value of `b` because it's wrapped in a mutable container.
|
|
344
|
+
|
|
345
|
+
## Exercises ##
|
|
346
|
+
|
|
319
347
|
Now is a good time to practice the Python Data Model. Here are [some exercises](https://github.com/bterwijn/memory_graph_videos/blob/main/exercises/exercises.md) on references, mutability, copies, and function calls.
|
|
320
348
|
|
|
321
349
|
## Block ##
|
|
@@ -353,8 +381,8 @@ and the result is: 1 x 2 x 3 x 4 = 24
|
|
|
353
381
|
|
|
354
382
|
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/factorial.py×tep=1.0&play).
|
|
355
383
|
|
|
356
|
-
## Binary
|
|
357
|
-
A more interesting recursive example is function `binary()` that converts a decimal
|
|
384
|
+
## Binary Conversion ##
|
|
385
|
+
A more interesting recursive example is function `binary()` that converts a integer from decimal to binary representation.
|
|
358
386
|
```python
|
|
359
387
|
import memory_graph as mg
|
|
360
388
|
mg.config.type_to_horizontal[list] = True # horizontal lists
|
|
@@ -372,7 +400,7 @@ print( binary(100) )
|
|
|
372
400
|
```
|
|
373
401
|

|
|
374
402
|
```
|
|
375
|
-
|
|
403
|
+
[1, 1, 0, 0, 1, 0, 0]
|
|
376
404
|
```
|
|
377
405
|
|
|
378
406
|
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/binary_convert.py×tep=1.0&play).
|
|
@@ -407,6 +435,8 @@ print( power_set(['a', 'b', 'c']) )
|
|
|
407
435
|
[['a', 'b', 'c'], ['a', 'b'], ['a', 'c'], ['a'], ['b', 'c'], ['b'], ['c'], []]
|
|
408
436
|
```
|
|
409
437
|
|
|
438
|
+
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/power_set.py×tep=1.0&play).
|
|
439
|
+
|
|
410
440
|
# Debugging #
|
|
411
441
|
|
|
412
442
|
For the best debugging experience with memory_graph set for example expression:
|
|
@@ -1056,7 +1086,7 @@ $ bash create_gif.sh animated
|
|
|
1056
1086
|
```
|
|
1057
1087
|
|
|
1058
1088
|
# Troubleshooting #
|
|
1059
|
-
- Adobe Acrobat Reader [doesn't refresh a PDF file](https://community.adobe.com/t5/acrobat-reader-discussions/reload-refresh-pdfs/td-p/9632292) when it changes on disk and blocks updates which results in an `Could not open '
|
|
1089
|
+
- Adobe Acrobat Reader [doesn't refresh a PDF file](https://community.adobe.com/t5/acrobat-reader-discussions/reload-refresh-pdfs/td-p/9632292) when it changes on disk and blocks updates which results in an `Could not open 'memory_graph.pdf' for writing : Permission denied` error. One solution is to install a PDF reader that does refresh ([SumatraPDF](https://www.sumatrapdfreader.org/), [Okular](https://okular.kde.org/), ...) and set it as your default PDF reader. Another solution is to `render()` the graph to a different output format.
|
|
1060
1090
|
|
|
1061
1091
|
- 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.
|
|
1062
1092
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# This file is part of memory_graph.
|
|
2
|
+
# Copyright (c) 2023, Bas Terwijn.
|
|
3
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
4
|
+
|
|
5
|
+
import memory_graph as mg
|
|
6
|
+
|
|
7
|
+
def add_one(a, b):
|
|
8
|
+
a += 1
|
|
9
|
+
b[0] += 1
|
|
10
|
+
mg.render( mg.stack(), "wrap_int.png")
|
|
11
|
+
|
|
12
|
+
a = 10
|
|
13
|
+
b = [10]
|
|
14
|
+
|
|
15
|
+
add_one(a, b)
|
|
16
|
+
print(f"a:{a} b:{b[0]}")
|
|
@@ -257,9 +257,9 @@ def memory_to_nodes(data):
|
|
|
257
257
|
id_to_slices = add_missing_edges(nodes, id_to_slices, config.max_missing_edges)
|
|
258
258
|
#print('id_to_slices:',id_to_slices)
|
|
259
259
|
embed_keys_in_key_value_nodes(nodes, nodes_key_value, id_to_slices)
|
|
260
|
-
graphviz_graph_attr = {}
|
|
261
|
-
graphviz_node_attr = {'shape':'plaintext'}
|
|
262
|
-
graphviz_edge_attr = {}
|
|
260
|
+
graphviz_graph_attr = {'fontname': 'Courier', 'fontsize': '14'}
|
|
261
|
+
graphviz_node_attr = {'fontname': 'Courier', 'fontsize': '14', 'shape': 'plaintext'}
|
|
262
|
+
graphviz_edge_attr = {'fontname': 'Courier', 'fontsize': '14'}
|
|
263
263
|
graphviz_graph=graphviz.Digraph('memory_graph',
|
|
264
264
|
graph_attr=graphviz_graph_attr,
|
|
265
265
|
node_attr=graphviz_node_attr,
|
|
@@ -20,7 +20,7 @@ def is_function(obj):
|
|
|
20
20
|
|
|
21
21
|
def filter_dict(dictionary):
|
|
22
22
|
""" Filters out the unwanted dict attributes. """
|
|
23
|
-
if '__name__' in dictionary: #
|
|
23
|
+
if '__name__' in dictionary: # filter stack frames in global scope
|
|
24
24
|
return [
|
|
25
25
|
(k,v) for k, v in dictionary.items() if
|
|
26
26
|
not (type(k) is str and k.startswith('__')) and
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memory_graph
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.56
|
|
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
|
|
@@ -58,6 +58,10 @@ Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph
|
|
|
58
58
|
- **visualize the structure of your data** to easily understand and debug any data structure
|
|
59
59
|
- understand function calls, variable scope, and the **complete program state** through call stack visualization
|
|
60
60
|
|
|
61
|
+
An example Binary Tree data structure:
|
|
62
|
+

|
|
63
|
+
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_tree.py×tep=0.2&play).
|
|
64
|
+
|
|
61
65
|
# Videos #
|
|
62
66
|
| [](https://www.youtube.com/watch?v=23_bHcr7hqo) | [](https://www.youtube.com/watch?v=pvIJgHCaXhU) |
|
|
63
67
|
|:--:|:--:|
|
|
@@ -132,7 +136,7 @@ identical?: True
|
|
|
132
136
|
```
|
|
133
137
|
A better way to understand what values are shared is to draw a graph using [memory_graph](https://pypi.org/project/memory-graph/).
|
|
134
138
|
|
|
135
|
-
#
|
|
139
|
+
# Topics #
|
|
136
140
|
|
|
137
141
|
[Python Data Model](#python-data-model)
|
|
138
142
|
|
|
@@ -173,8 +177,8 @@ Bas Terwijn
|
|
|
173
177
|
Inspired by [Python Tutor](https://pythontutor.com/).
|
|
174
178
|
|
|
175
179
|
## Social Media #
|
|
176
|
-
* LinkedIn
|
|
177
|
-
* Reddit
|
|
180
|
+
* [LinkedIn](https://www.linkedin.com/groups/13244150/)
|
|
181
|
+
* [Reddit](https://www.reddit.com/r/Python_memory_graph/)
|
|
178
182
|
|
|
179
183
|
## Supported by ##
|
|
180
184
|
<img src="https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/uva.png" alt="University of Amsterdam" width="600">
|
|
@@ -358,9 +362,33 @@ In the printed output only `a` is changed as a result of the function call:
|
|
|
358
362
|
```
|
|
359
363
|
a:[4, 3, 2, 1] b:(4, 3, 2) c:[4, 3, 2]
|
|
360
364
|
```
|
|
361
|
-
|
|
362
365
|
This is because `b` is of immutable type 'tuple' so its value gets copied automatically when it is changed. And because the function is called with a copy of `c`, its original value is not changed by the function. The value of variable `a` is the only value of mutable type that is shared between the root stack frame **'0: \<module>'** and the **'1: add_one'** stack frame of the function so only that variable is affected as a result of the function call. The other changes remain confined to the local variables of the ```add_one()``` function.
|
|
363
366
|
|
|
367
|
+
## Function Call That Changes 'int' Value ##
|
|
368
|
+
Even though `int` is an immutable type, so an `int` value can not be changed by directly passing it to a function, we can still change it by wrapping it in a mutable container.
|
|
369
|
+
|
|
370
|
+
```python
|
|
371
|
+
import memory_graph as mg
|
|
372
|
+
|
|
373
|
+
def add_one(a, b):
|
|
374
|
+
a += 1 # change remains confined to 'a' in the add_one function
|
|
375
|
+
b[0] += 1 # change also effects 'b' outside of the add_one function
|
|
376
|
+
mg.show(mg.stack())
|
|
377
|
+
|
|
378
|
+
a = 10
|
|
379
|
+
b = [10] # wrap in a value of mutable type list
|
|
380
|
+
add_one(a, b)
|
|
381
|
+
|
|
382
|
+
print(f"a:{a} b:{b[0]}")
|
|
383
|
+
```
|
|
384
|
+

|
|
385
|
+
```
|
|
386
|
+
a:10 b:11
|
|
387
|
+
```
|
|
388
|
+
Calling `add_one()` does not effect the `int` value of `a` but does effect the `int` value of `b` because it's wrapped in a mutable container.
|
|
389
|
+
|
|
390
|
+
## Exercises ##
|
|
391
|
+
|
|
364
392
|
Now is a good time to practice the Python Data Model. Here are [some exercises](https://github.com/bterwijn/memory_graph_videos/blob/main/exercises/exercises.md) on references, mutability, copies, and function calls.
|
|
365
393
|
|
|
366
394
|
## Block ##
|
|
@@ -398,8 +426,8 @@ and the result is: 1 x 2 x 3 x 4 = 24
|
|
|
398
426
|
|
|
399
427
|
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/factorial.py×tep=1.0&play).
|
|
400
428
|
|
|
401
|
-
## Binary
|
|
402
|
-
A more interesting recursive example is function `binary()` that converts a decimal
|
|
429
|
+
## Binary Conversion ##
|
|
430
|
+
A more interesting recursive example is function `binary()` that converts a integer from decimal to binary representation.
|
|
403
431
|
```python
|
|
404
432
|
import memory_graph as mg
|
|
405
433
|
mg.config.type_to_horizontal[list] = True # horizontal lists
|
|
@@ -417,7 +445,7 @@ print( binary(100) )
|
|
|
417
445
|
```
|
|
418
446
|

|
|
419
447
|
```
|
|
420
|
-
|
|
448
|
+
[1, 1, 0, 0, 1, 0, 0]
|
|
421
449
|
```
|
|
422
450
|
|
|
423
451
|
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/binary_convert.py×tep=1.0&play).
|
|
@@ -452,6 +480,8 @@ print( power_set(['a', 'b', 'c']) )
|
|
|
452
480
|
[['a', 'b', 'c'], ['a', 'b'], ['a', 'c'], ['a'], ['b', 'c'], ['b'], ['c'], []]
|
|
453
481
|
```
|
|
454
482
|
|
|
483
|
+
Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/power_set.py×tep=1.0&play).
|
|
484
|
+
|
|
455
485
|
# Debugging #
|
|
456
486
|
|
|
457
487
|
For the best debugging experience with memory_graph set for example expression:
|
|
@@ -1101,7 +1131,7 @@ $ bash create_gif.sh animated
|
|
|
1101
1131
|
```
|
|
1102
1132
|
|
|
1103
1133
|
# Troubleshooting #
|
|
1104
|
-
- Adobe Acrobat Reader [doesn't refresh a PDF file](https://community.adobe.com/t5/acrobat-reader-discussions/reload-refresh-pdfs/td-p/9632292) when it changes on disk and blocks updates which results in an `Could not open '
|
|
1134
|
+
- Adobe Acrobat Reader [doesn't refresh a PDF file](https://community.adobe.com/t5/acrobat-reader-discussions/reload-refresh-pdfs/td-p/9632292) when it changes on disk and blocks updates which results in an `Could not open 'memory_graph.pdf' for writing : Permission denied` error. One solution is to install a PDF reader that does refresh ([SumatraPDF](https://www.sumatrapdfreader.org/), [Okular](https://okular.kde.org/), ...) and set it as your default PDF reader. Another solution is to `render()` the graph to a different output format.
|
|
1105
1135
|
|
|
1106
1136
|
- 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.
|
|
1107
1137
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "memory_graph"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.56"
|
|
8
8
|
description = "Teaching tool and debugging aid in context of references, mutable data types, and shallow and deep copy."
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Bas Terwijn", email = "bterwijn@gmail.com"}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|