memory-graph 0.3.78__tar.gz → 0.3.79__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 (41) hide show
  1. {memory_graph-0.3.78 → memory_graph-0.3.79}/PKG-INFO +78 -19
  2. {memory_graph-0.3.78 → memory_graph-0.3.79}/README.md +77 -18
  3. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/__init__.py +2 -1
  4. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/config.py +5 -0
  5. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/config_default.py +92 -29
  6. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/html_table.py +6 -6
  7. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/memory_to_nodes.py +5 -5
  8. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph.egg-info/PKG-INFO +78 -19
  9. {memory_graph-0.3.78 → memory_graph-0.3.79}/pyproject.toml +1 -1
  10. {memory_graph-0.3.78 → memory_graph-0.3.79}/LICENSE.txt +0 -0
  11. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/call_stack.py +0 -0
  12. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/config_helpers.py +0 -0
  13. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/extension_numpy.py +0 -0
  14. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/extension_pandas.py +0 -0
  15. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/extension_torch.py +0 -0
  16. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/list_view.py +0 -0
  17. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/node_base.py +0 -0
  18. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/node_key_value.py +0 -0
  19. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/node_leaf.py +0 -0
  20. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/node_linear.py +0 -0
  21. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/node_table.py +0 -0
  22. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/sequence.py +0 -0
  23. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/slicer.py +0 -0
  24. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/slices.py +0 -0
  25. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/slices_iterator.py +0 -0
  26. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/slices_table_iterator.py +0 -0
  27. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/test.py +0 -0
  28. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/test_max_graph_depth.py +0 -0
  29. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/test_memory_graph.py +0 -0
  30. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/test_memory_to_nodes.py +0 -0
  31. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/test_sequence.py +0 -0
  32. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/test_slicer.py +0 -0
  33. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/test_slices.py +0 -0
  34. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/test_slices_iterator.py +0 -0
  35. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph/utils.py +0 -0
  36. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph.egg-info/SOURCES.txt +0 -0
  37. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph.egg-info/dependency_links.txt +0 -0
  38. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph.egg-info/requires.txt +0 -0
  39. {memory_graph-0.3.78 → memory_graph-0.3.79}/memory_graph.egg-info/top_level.txt +0 -0
  40. {memory_graph-0.3.78 → memory_graph-0.3.79}/setup.cfg +0 -0
  41. {memory_graph-0.3.78 → memory_graph-0.3.79}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memory_graph
3
- Version: 0.3.78
3
+ Version: 0.3.79
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-Expression: BSD-2-Clause
@@ -27,7 +27,7 @@ Additionally [Graphviz](https://graphviz.org/download/) needs to be installed.
27
27
 
28
28
  # Highlights #
29
29
  ![vscode_copying.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/vscode_copying.gif)
30
- Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph.com/#breakpoints=8&continues=1&timestep=1.0&play) 👈 now, no installation required!
30
+ Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph.com/#breakpoints=8&continues=1&play) 👈 now, no installation required!
31
31
 
32
32
  - learn the right **mental model** to think about Python data (references, mutability, shallow vs deep copy)
33
33
  - **visualize the structure of your data** to more easily understand and debug any data structure
@@ -35,7 +35,7 @@ Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph
35
35
 
36
36
  An example Binary Tree data structure:
37
37
  ![bin_tree_vs.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/bin_tree_vs.gif)
38
- 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&timestep=0.2&play).
38
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_tree.py&timestep=0.2&play).
39
39
 
40
40
  # Videos #
41
41
  | [![Quick Intro](https://img.youtube.com/vi/23_bHcr7hqo/0.jpg)](https://www.youtube.com/watch?v=23_bHcr7hqo) | [![Mutability](https://img.youtube.com/vi/pvIJgHCaXhU/0.jpg)](https://www.youtube.com/watch?v=pvIJgHCaXhU) |
@@ -163,7 +163,7 @@ Bas Terwijn
163
163
  ## Inspiration ##
164
164
  Inspired by [Python Tutor](https://pythontutor.com/).
165
165
 
166
- The main differences are that by running memory_graph locally we support Python Tutor’s [unsupported features](https://github.com/pythontutor-dev/pythontutor/blob/master/unsupported-features.md#unsupported-features) so that it scales to full programs in many environments and IDEs instead of just code snippets in a webbrowser, and by mirroring the data’s hierarchy we improve graph readability for larger graphs.
166
+ The main differences are that by running memory_graph locally we support Python Tutor’s [unsupported features](https://github.com/pythontutor-dev/pythontutor/blob/master/unsupported-features.md#unsupported-features) so that it scales to full multi-file programs in many environments and IDEs instead of just code snippets in a webbrowser, and by mirroring the data’s hierarchy we improve graph readability for larger graphs.
167
167
 
168
168
  ## Social Media #
169
169
  * [LinkedIn](https://www.linkedin.com/groups/13244150/)
@@ -242,7 +242,7 @@ mg.show(locals())
242
242
 
243
243
  ![copy_mutbale.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/copy_mutable.png)
244
244
 
245
- 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/copies.py&play).
245
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/copies.py&play).
246
246
 
247
247
  ## Custom Copy ##
248
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.
@@ -270,7 +270,7 @@ mg.show(locals())
270
270
  ```
271
271
  ![copy_method.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/copy_method.png)
272
272
 
273
- 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/custom_copy.py&breakpoints=15&continues=1&play).
273
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/custom_copy.py&breakpoints=15&continues=1&play).
274
274
 
275
275
  ## Name Rebinding ##
276
276
  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 affecting any other variable.
@@ -300,7 +300,7 @@ mg.render(locals(), 'rebinding3.png')
300
300
  |:--------------:|:--------------:|:--------------:|
301
301
  | rebinding1.png | rebinding2.png | rebinding3.png |
302
302
 
303
- 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/rebind.py&play).
303
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/rebind.py&play).
304
304
 
305
305
  ## Copying Values of Immutable Type ##
306
306
  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.
@@ -358,7 +358,7 @@ print(f"a:{a} b:{b} c:{c}")
358
358
  ```
359
359
  ![add_one.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/add_one.png)
360
360
 
361
- 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/function_call.py&play).
361
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/function_call.py&play).
362
362
 
363
363
  In the printed output we see that only `a` is changed as a result of the function call:
364
364
  ```
@@ -387,7 +387,7 @@ print(f"a:{a} b:{b[0]}")
387
387
  ```
388
388
  a:10 b:11
389
389
  ```
390
- 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/wrap.py&breakpoints=5&continues=1&play)
390
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/wrap.py&breakpoints=5&continues=1&play)
391
391
 
392
392
  The effect of calling `add_one()` is that `b[0]` increases by 1, while `a` is unaffected.
393
393
 
@@ -428,7 +428,7 @@ print( factorial(4) )
428
428
 
429
429
  and the result is: 1 x 2 x 3 x 4 = 24
430
430
 
431
- 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&timestep=1.0&play).
431
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/factorial.py&timestep=1.0&play).
432
432
 
433
433
  ## Binary Conversion ##
434
434
  A more interesting recursive example is function `binary()` that converts a integer from decimal to binary representation.
@@ -452,7 +452,7 @@ print( binary(100) )
452
452
  [1, 1, 0, 0, 1, 0, 0]
453
453
  ```
454
454
 
455
- 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&timestep=1.0&play).
455
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/binary_convert.py&timestep=1.0&play).
456
456
 
457
457
  ## Power Set ##
458
458
  A more complex recursive example is function `power_set()` where lists are shared by different function calls. A power set is the set of all subsets of a collection of values.
@@ -484,7 +484,7 @@ print( power_set(['a', 'b', 'c']) )
484
484
  [['a', 'b', 'c'], ['a', 'b'], ['a', 'c'], ['a'], ['b', 'c'], ['b'], ['c'], []]
485
485
  ```
486
486
 
487
- 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&timestep=1.0&play).
487
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/power_set.py&timestep=1.0&play).
488
488
 
489
489
  ## Invocation Tree ##
490
490
  The memory_graph package visualizes data at the currect time, but to better understand recursion it can also be helpful to visualize different function calls over time. This is what the [invocation_tree](https://github.com/bterwijn/invocation_tree?tab=readme-ov-file#installation) package does.
@@ -648,7 +648,7 @@ for i in range(n):
648
648
  Here we show values being added to a Linked List in Cursor AI. When adding the last value '5' we "Step Into" the code to show more of the details.
649
649
  ![linked_list.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/linked_list.gif)
650
650
 
651
- 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/linked_list.py&timestep=0.2&play).
651
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/linked_list.py&timestep=0.2&play).
652
652
 
653
653
  ## Binary Tree ##
654
654
  ```python
@@ -690,7 +690,7 @@ for i in range(n):
690
690
  Here we show values being inserted in a Binary Tree in Visual Studio Code. When inserting the last value '29' we "Step Into" the code to show the recursive implementation.
691
691
  ![images/bin_tree.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/bin_tree.gif)
692
692
 
693
- 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&timestep=0.2&play) or see the more advanced [Multiway Tree](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/multiway_tree.py&breakpoints=19,33&continues=1&timestep=0.2&play) with more than two children per node, making the tree less deep and more efficient.
693
+ See it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_tree.py&timestep=0.2&play) or see the more advanced [Multiway Tree](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/multiway_tree.py&breakpoints=19,33&continues=1&timestep=0.2&play) with more than two children per node, making the tree less deep and more efficient.
694
694
 
695
695
  ## Hash Set ##
696
696
  ```python
@@ -734,7 +734,7 @@ for i in range(n):
734
734
  Here we show values being inserted in a HashSet in PyCharm. When inserting the last value '44' we "Step Into" the code to show more of the details.
735
735
  ![images/hash_set.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/hash_set.gif)
736
736
 
737
- 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/hash_set.py&breakpoints=32&continues=1&timestep=0.5&play).
737
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/hash_set.py&breakpoints=32&continues=1&timestep=0.5&play).
738
738
 
739
739
 
740
740
  # Sorting Algorithms #
@@ -761,7 +761,7 @@ In this configuration example we show the decimal, binary and [two's complement
761
761
 
762
762
  A sliding puzzle solver as a challenging example showing how memory_graph deals with large amounts of data. Click "Continue" to step through the breadth-first search generations until a solution path is found:
763
763
 
764
- - [sliding puzzle solver](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/sliding_puzzle.py&breakpoints=16,26,28,39&continues=1)
764
+ - [sliding puzzle solver](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/sliding_puzzle.py&breakpoints=16,26,28,39,136&continues=1)
765
765
 
766
766
  ![sliding_puzzle.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/sliding_puzzle.png)
767
767
 
@@ -1255,7 +1255,66 @@ mg.config.type_to_node[List_View] = (lambda l: mg.Node_Linear(l,
1255
1255
  ```
1256
1256
  ![bin_search_linear.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/bin_search_linear.png)
1257
1257
 
1258
- 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_search.py&breakpoints=32&continues=1&timestep=0.5&play)
1258
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_search.py&breakpoints=38&continues=1&timestep=0.5&play)
1259
+
1260
+ ## String Types ##
1261
+
1262
+ For special string formatting different `str` types are available:
1263
+
1264
+ | string type | format |
1265
+ |:--------------------------:|:--------------------:|
1266
+ | `str` | normal Python `str` type is limited by `config.max_string_length` |
1267
+ | `mg.full_str('text')` | not limited |
1268
+ | `mg.unquoted_str('text')` | not limited and not quoted |
1269
+ | `mg.html_str('text')` | for [Grahviz html-like formatting](https://graphviz.org/doc/info/shapes.html#html) |
1270
+
1271
+ The [Grahviz html-like formatting](https://graphviz.org/doc/info/shapes.html#html) supports a subset of html tags that allow for things like:
1272
+ ```python
1273
+ import memory_graph as mg
1274
+
1275
+ elements = ['<B>bold</B>',
1276
+ '<I>italic</I>',
1277
+ '<S>strikethrough</S>',
1278
+ '<U>under</U><O>over</O>',
1279
+ '<SUB>sub</SUB><SUP>sup</SUP>',
1280
+ '<FONT FACE="Courier">monospaced</FONT>',
1281
+ '<FONT COLOR="red">red</FONT><FONT COLOR="green">green</FONT>',
1282
+ '<FONT POINT-SIZE="20">Large</FONT><FONT POINT-SIZE="10">small</FONT>',
1283
+ '<TABLE BORDER="1"><TR><TD>c1</TD><TD>c2</TD></TR></TABLE>',
1284
+ 'line1<BR/>line2<BR/>line3<BR/>']
1285
+
1286
+ normal_str = '<TABLE BORDER="0">\n'
1287
+ for element in elements:
1288
+ normal_str += '<TR><TD> ' + mg.utils.html_escape(element) + ' </TD><TD> ' + element+ ' </TD></TR>element\n'
1289
+ normal_str += '</TABLE>\n'
1290
+
1291
+ html_example = mg.html_str(normal_str)
1292
+ del elements, element, normal_str
1293
+ mg.show(locals())
1294
+ ```
1295
+ ![html_str_example.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/html_str_example.png)
1296
+
1297
+ Including the `<IMG>` tag that allows for showing local image files only, but that currently doesn't work in the Memory Graph Web Debugger, that uses 'Viz.js' for graph rendering, unfortunately.
1298
+
1299
+ ```python
1300
+ import memory_graph as mg
1301
+ import matplotlib.pyplot as plt
1302
+ import random
1303
+ random.seed(0)
1304
+
1305
+ N = 100
1306
+ value = 0
1307
+ data = [value]
1308
+ for i in range(N):
1309
+ value += random.uniform(-1, 1)
1310
+ data.append(value)
1311
+
1312
+ plt.plot(data)
1313
+ plt.savefig('plot.png')
1314
+ image = {mg.html_str('<IMG SRC="plot.png"/>')}
1315
+ mg.show(locals())
1316
+ ```
1317
+ ![html_str_image.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/html_str_image.png)
1259
1318
 
1260
1319
  ## Collapse Type ##
1261
1320
 
@@ -1388,7 +1447,7 @@ mg.show(locals())
1388
1447
  ```
1389
1448
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_numpy.png)
1390
1449
 
1391
- Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_numpy.py&play).
1450
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_numpy.py&play).
1392
1451
 
1393
1452
  ## Pandas ##
1394
1453
  For pandas types `Series` and `DataFrame`, use `mg.extend_pandas()`:
@@ -1409,7 +1468,7 @@ mg.show(locals())
1409
1468
  ```
1410
1469
  ![extension_pandas.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_pandas.png)
1411
1470
 
1412
- Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#micropip=pandas&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_pandas.py&play).
1471
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#micropip=pandas&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_pandas.py&play).
1413
1472
 
1414
1473
  ## PyTorch ##
1415
1474
  For torch type `tensor`, use `mg.extend_torch()`:
@@ -7,7 +7,7 @@ Additionally [Graphviz](https://graphviz.org/download/) needs to be installed.
7
7
 
8
8
  # Highlights #
9
9
  ![vscode_copying.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/vscode_copying.gif)
10
- Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph.com/#breakpoints=8&continues=1&timestep=1.0&play) 👈 now, no installation required!
10
+ Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph.com/#breakpoints=8&continues=1&play) 👈 now, no installation required!
11
11
 
12
12
  - learn the right **mental model** to think about Python data (references, mutability, shallow vs deep copy)
13
13
  - **visualize the structure of your data** to more easily understand and debug any data structure
@@ -15,7 +15,7 @@ Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph
15
15
 
16
16
  An example Binary Tree data structure:
17
17
  ![bin_tree_vs.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/bin_tree_vs.gif)
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&timestep=0.2&play).
18
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_tree.py&timestep=0.2&play).
19
19
 
20
20
  # Videos #
21
21
  | [![Quick Intro](https://img.youtube.com/vi/23_bHcr7hqo/0.jpg)](https://www.youtube.com/watch?v=23_bHcr7hqo) | [![Mutability](https://img.youtube.com/vi/pvIJgHCaXhU/0.jpg)](https://www.youtube.com/watch?v=pvIJgHCaXhU) |
@@ -143,7 +143,7 @@ Bas Terwijn
143
143
  ## Inspiration ##
144
144
  Inspired by [Python Tutor](https://pythontutor.com/).
145
145
 
146
- The main differences are that by running memory_graph locally we support Python Tutor’s [unsupported features](https://github.com/pythontutor-dev/pythontutor/blob/master/unsupported-features.md#unsupported-features) so that it scales to full programs in many environments and IDEs instead of just code snippets in a webbrowser, and by mirroring the data’s hierarchy we improve graph readability for larger graphs.
146
+ The main differences are that by running memory_graph locally we support Python Tutor’s [unsupported features](https://github.com/pythontutor-dev/pythontutor/blob/master/unsupported-features.md#unsupported-features) so that it scales to full multi-file programs in many environments and IDEs instead of just code snippets in a webbrowser, and by mirroring the data’s hierarchy we improve graph readability for larger graphs.
147
147
 
148
148
  ## Social Media #
149
149
  * [LinkedIn](https://www.linkedin.com/groups/13244150/)
@@ -222,7 +222,7 @@ mg.show(locals())
222
222
 
223
223
  ![copy_mutbale.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/copy_mutable.png)
224
224
 
225
- 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/copies.py&play).
225
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/copies.py&play).
226
226
 
227
227
  ## Custom Copy ##
228
228
  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.
@@ -250,7 +250,7 @@ mg.show(locals())
250
250
  ```
251
251
  ![copy_method.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/copy_method.png)
252
252
 
253
- 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/custom_copy.py&breakpoints=15&continues=1&play).
253
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/custom_copy.py&breakpoints=15&continues=1&play).
254
254
 
255
255
  ## Name Rebinding ##
256
256
  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 affecting any other variable.
@@ -280,7 +280,7 @@ mg.render(locals(), 'rebinding3.png')
280
280
  |:--------------:|:--------------:|:--------------:|
281
281
  | rebinding1.png | rebinding2.png | rebinding3.png |
282
282
 
283
- 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/rebind.py&play).
283
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/rebind.py&play).
284
284
 
285
285
  ## Copying Values of Immutable Type ##
286
286
  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.
@@ -338,7 +338,7 @@ print(f"a:{a} b:{b} c:{c}")
338
338
  ```
339
339
  ![add_one.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/add_one.png)
340
340
 
341
- 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/function_call.py&play).
341
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/function_call.py&play).
342
342
 
343
343
  In the printed output we see that only `a` is changed as a result of the function call:
344
344
  ```
@@ -367,7 +367,7 @@ print(f"a:{a} b:{b[0]}")
367
367
  ```
368
368
  a:10 b:11
369
369
  ```
370
- 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/wrap.py&breakpoints=5&continues=1&play)
370
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/wrap.py&breakpoints=5&continues=1&play)
371
371
 
372
372
  The effect of calling `add_one()` is that `b[0]` increases by 1, while `a` is unaffected.
373
373
 
@@ -408,7 +408,7 @@ print( factorial(4) )
408
408
 
409
409
  and the result is: 1 x 2 x 3 x 4 = 24
410
410
 
411
- 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&timestep=1.0&play).
411
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/factorial.py&timestep=1.0&play).
412
412
 
413
413
  ## Binary Conversion ##
414
414
  A more interesting recursive example is function `binary()` that converts a integer from decimal to binary representation.
@@ -432,7 +432,7 @@ print( binary(100) )
432
432
  [1, 1, 0, 0, 1, 0, 0]
433
433
  ```
434
434
 
435
- 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&timestep=1.0&play).
435
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/binary_convert.py&timestep=1.0&play).
436
436
 
437
437
  ## Power Set ##
438
438
  A more complex recursive example is function `power_set()` where lists are shared by different function calls. A power set is the set of all subsets of a collection of values.
@@ -464,7 +464,7 @@ print( power_set(['a', 'b', 'c']) )
464
464
  [['a', 'b', 'c'], ['a', 'b'], ['a', 'c'], ['a'], ['b', 'c'], ['b'], ['c'], []]
465
465
  ```
466
466
 
467
- 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&timestep=1.0&play).
467
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/power_set.py&timestep=1.0&play).
468
468
 
469
469
  ## Invocation Tree ##
470
470
  The memory_graph package visualizes data at the currect time, but to better understand recursion it can also be helpful to visualize different function calls over time. This is what the [invocation_tree](https://github.com/bterwijn/invocation_tree?tab=readme-ov-file#installation) package does.
@@ -628,7 +628,7 @@ for i in range(n):
628
628
  Here we show values being added to a Linked List in Cursor AI. When adding the last value '5' we "Step Into" the code to show more of the details.
629
629
  ![linked_list.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/linked_list.gif)
630
630
 
631
- 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/linked_list.py&timestep=0.2&play).
631
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/linked_list.py&timestep=0.2&play).
632
632
 
633
633
  ## Binary Tree ##
634
634
  ```python
@@ -670,7 +670,7 @@ for i in range(n):
670
670
  Here we show values being inserted in a Binary Tree in Visual Studio Code. When inserting the last value '29' we "Step Into" the code to show the recursive implementation.
671
671
  ![images/bin_tree.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/bin_tree.gif)
672
672
 
673
- 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&timestep=0.2&play) or see the more advanced [Multiway Tree](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/multiway_tree.py&breakpoints=19,33&continues=1&timestep=0.2&play) with more than two children per node, making the tree less deep and more efficient.
673
+ See it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_tree.py&timestep=0.2&play) or see the more advanced [Multiway Tree](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/multiway_tree.py&breakpoints=19,33&continues=1&timestep=0.2&play) with more than two children per node, making the tree less deep and more efficient.
674
674
 
675
675
  ## Hash Set ##
676
676
  ```python
@@ -714,7 +714,7 @@ for i in range(n):
714
714
  Here we show values being inserted in a HashSet in PyCharm. When inserting the last value '44' we "Step Into" the code to show more of the details.
715
715
  ![images/hash_set.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/hash_set.gif)
716
716
 
717
- 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/hash_set.py&breakpoints=32&continues=1&timestep=0.5&play).
717
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/hash_set.py&breakpoints=32&continues=1&timestep=0.5&play).
718
718
 
719
719
 
720
720
  # Sorting Algorithms #
@@ -741,7 +741,7 @@ In this configuration example we show the decimal, binary and [two's complement
741
741
 
742
742
  A sliding puzzle solver as a challenging example showing how memory_graph deals with large amounts of data. Click "Continue" to step through the breadth-first search generations until a solution path is found:
743
743
 
744
- - [sliding puzzle solver](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/sliding_puzzle.py&breakpoints=16,26,28,39&continues=1)
744
+ - [sliding puzzle solver](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/sliding_puzzle.py&breakpoints=16,26,28,39,136&continues=1)
745
745
 
746
746
  ![sliding_puzzle.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/sliding_puzzle.png)
747
747
 
@@ -1235,7 +1235,66 @@ mg.config.type_to_node[List_View] = (lambda l: mg.Node_Linear(l,
1235
1235
  ```
1236
1236
  ![bin_search_linear.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/bin_search_linear.png)
1237
1237
 
1238
- 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_search.py&breakpoints=32&continues=1&timestep=0.5&play)
1238
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_search.py&breakpoints=38&continues=1&timestep=0.5&play)
1239
+
1240
+ ## String Types ##
1241
+
1242
+ For special string formatting different `str` types are available:
1243
+
1244
+ | string type | format |
1245
+ |:--------------------------:|:--------------------:|
1246
+ | `str` | normal Python `str` type is limited by `config.max_string_length` |
1247
+ | `mg.full_str('text')` | not limited |
1248
+ | `mg.unquoted_str('text')` | not limited and not quoted |
1249
+ | `mg.html_str('text')` | for [Grahviz html-like formatting](https://graphviz.org/doc/info/shapes.html#html) |
1250
+
1251
+ The [Grahviz html-like formatting](https://graphviz.org/doc/info/shapes.html#html) supports a subset of html tags that allow for things like:
1252
+ ```python
1253
+ import memory_graph as mg
1254
+
1255
+ elements = ['<B>bold</B>',
1256
+ '<I>italic</I>',
1257
+ '<S>strikethrough</S>',
1258
+ '<U>under</U><O>over</O>',
1259
+ '<SUB>sub</SUB><SUP>sup</SUP>',
1260
+ '<FONT FACE="Courier">monospaced</FONT>',
1261
+ '<FONT COLOR="red">red</FONT><FONT COLOR="green">green</FONT>',
1262
+ '<FONT POINT-SIZE="20">Large</FONT><FONT POINT-SIZE="10">small</FONT>',
1263
+ '<TABLE BORDER="1"><TR><TD>c1</TD><TD>c2</TD></TR></TABLE>',
1264
+ 'line1<BR/>line2<BR/>line3<BR/>']
1265
+
1266
+ normal_str = '<TABLE BORDER="0">\n'
1267
+ for element in elements:
1268
+ normal_str += '<TR><TD> ' + mg.utils.html_escape(element) + ' </TD><TD> ' + element+ ' </TD></TR>element\n'
1269
+ normal_str += '</TABLE>\n'
1270
+
1271
+ html_example = mg.html_str(normal_str)
1272
+ del elements, element, normal_str
1273
+ mg.show(locals())
1274
+ ```
1275
+ ![html_str_example.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/html_str_example.png)
1276
+
1277
+ Including the `<IMG>` tag that allows for showing local image files only, but that currently doesn't work in the Memory Graph Web Debugger, that uses 'Viz.js' for graph rendering, unfortunately.
1278
+
1279
+ ```python
1280
+ import memory_graph as mg
1281
+ import matplotlib.pyplot as plt
1282
+ import random
1283
+ random.seed(0)
1284
+
1285
+ N = 100
1286
+ value = 0
1287
+ data = [value]
1288
+ for i in range(N):
1289
+ value += random.uniform(-1, 1)
1290
+ data.append(value)
1291
+
1292
+ plt.plot(data)
1293
+ plt.savefig('plot.png')
1294
+ image = {mg.html_str('<IMG SRC="plot.png"/>')}
1295
+ mg.show(locals())
1296
+ ```
1297
+ ![html_str_image.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/html_str_image.png)
1239
1298
 
1240
1299
  ## Collapse Type ##
1241
1300
 
@@ -1368,7 +1427,7 @@ mg.show(locals())
1368
1427
  ```
1369
1428
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_numpy.png)
1370
1429
 
1371
- Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_numpy.py&play).
1430
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_numpy.py&play).
1372
1431
 
1373
1432
  ## Pandas ##
1374
1433
  For pandas types `Series` and `DataFrame`, use `mg.extend_pandas()`:
@@ -1389,7 +1448,7 @@ mg.show(locals())
1389
1448
  ```
1390
1449
  ![extension_pandas.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_pandas.png)
1391
1450
 
1392
- Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#micropip=pandas&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_pandas.py&play).
1451
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#micropip=pandas&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_pandas.py&play).
1393
1452
 
1394
1453
  ## PyTorch ##
1395
1454
  For torch type `tensor`, use `mg.extend_torch()`:
@@ -2,7 +2,7 @@
2
2
  # Copyright (c) 2023, Bas Terwijn.
3
3
  # SPDX-License-Identifier: BSD-2-Clause
4
4
 
5
- __version__ = "0.3.78"
5
+ __version__ = "0.3.79"
6
6
  __author__ = 'Bas Terwijn'
7
7
 
8
8
  import memory_graph.memory_to_nodes as memory_to_nodes
@@ -26,6 +26,7 @@ if not hasattr(builtins, "mg"):
26
26
  builtins.mg = mg
27
27
 
28
28
  # re-exports for shorter names
29
+ from .config_default import dark_mode, transparent_background
29
30
  from .slicer import Slicer
30
31
  from .node_leaf import Node_Leaf
31
32
  from .node_linear import Node_Linear
@@ -29,6 +29,11 @@ type_to_string = { }
29
29
 
30
30
  type_to_node = { }
31
31
 
32
+ color_mode_dark = False
33
+ transparent_background = False
34
+ foreground_color = None
35
+ index_color = None
36
+ background_color = None
32
37
  type_to_color = { }
33
38
 
34
39
  type_to_horizontal = { }
@@ -17,8 +17,98 @@ import memory_graph.utils as utils
17
17
 
18
18
  import types
19
19
 
20
+ """ Colors of the graph. """
21
+ foreground_color_light = 'black'
22
+ index_color_light = '#505050'
23
+ background_color_light = 'white'
24
+ """ Colors of different types in the graph. """
25
+ type_to_color_light = {
26
+ # ================= singular
27
+ type(None) : "gray",
28
+ bool : "pink",
29
+ int : "darkolivegreen1",
30
+ float : "plum",
31
+ complex : "yellow",
32
+ str : "cyan",
33
+ # ================= linear
34
+ tuple : "orange",
35
+ list : "lightcoral",
36
+ set : "orchid1",
37
+ frozenset : "orchid2",
38
+ bytes : "khaki1",
39
+ bytearray : "khaki2",
40
+ # ================= key_value
41
+ Node_Key_Value : "seagreen1", # for classes
42
+ call_stack : 'khaki',
43
+ type: "seagreen3", # where class variables are stored
44
+ dict : "#60a5ff",
45
+ types.MappingProxyType : "dodgerblue2", # not used
46
+ range : "cornsilk2",
47
+ # ================= exception
48
+ BaseException : "#ff6666",
49
+ }
50
+
51
+ background_color_dark = "#1d1d1d"
52
+ foreground_color_dark = "#cccccc"
53
+ index_color_dark = "#999999"
54
+ type_to_color_dark = {
55
+ # ================= singular
56
+ type(None) : "#646464",
57
+ bool : "#8d646d",
58
+ int : "#507835",
59
+ float : "#7e4974",
60
+ complex : "#707500",
61
+ str : "#006f6f",
62
+ # ================= linear
63
+ tuple : "#956200",
64
+ list : "#783438",
65
+ set : "#811b7d",
66
+ frozenset : "#6a1666",
67
+ bytes : "#73753f",
68
+ bytearray : "#6a6c3b",
69
+ # ================= key_value
70
+ Node_Key_Value : "#00905d",
71
+ call_stack : '#7e8148',
72
+ type: "#00784e",
73
+ dict : "#355393",
74
+ types.MappingProxyType : "#304a84",
75
+ range : "#7e7d6c",
76
+ # ================= exception
77
+ BaseException : "#a52e37",
78
+ }
79
+
80
+ def set_colors(dark, transparent):
81
+ if dark:
82
+ config.foreground_color = foreground_color_dark
83
+ config.index_color = index_color_dark
84
+ config.background_color = background_color_dark
85
+ config.type_to_color = type_to_color_dark
86
+ else:
87
+ config.foreground_color = foreground_color_light
88
+ config.index_color = index_color_light
89
+ config.background_color = background_color_light
90
+ config.type_to_color = type_to_color_light
91
+ if transparent:
92
+ config.background_color = "transparent"
93
+
94
+ def transparent_background(transparent = None):
95
+ if transparent is None:
96
+ config.transparent_background = not config.transparent_background
97
+ else:
98
+ config.transparent_background = transparent
99
+ set_colors(config.color_mode_dark, config.transparent_background)
100
+
101
+ def dark_mode(dark = None):
102
+ if dark is None:
103
+ config.color_mode_dark = not config.color_mode_dark
104
+ else:
105
+ config.color_mode_dark = dark
106
+ set_colors(config.color_mode_dark, config.transparent_background)
107
+
20
108
  def reset():
21
109
 
110
+ set_colors(config.color_mode_dark, config.transparent_background)
111
+
22
112
  """ Reopen viewer each time show() is called, this might change window focus. """
23
113
  config.reopen_viewer = True
24
114
 
@@ -42,7 +132,8 @@ def reset():
42
132
 
43
133
  """ Types that by default will be embedded in the node of their parent. """
44
134
  config.embedded_types = {
45
- type(None), bool, int, float, complex, str, unquoted_str, html_str,
135
+ type(None), bool, int, float, complex,
136
+ str, full_str, unquoted_str, html_str,
46
137
  types.FunctionType,
47
138
  types.MethodType,
48
139
  classmethod,
@@ -85,34 +176,6 @@ def reset():
85
176
  ),
86
177
  BaseException: lambda data: Node_Leaf(data, data),
87
178
  }
88
-
89
- """ Colors of different types in the graph. """
90
- config.type_to_color = {
91
- # ================= singular
92
- type(None) : "gray",
93
- bool : "pink",
94
- int : "darkolivegreen1",
95
- float : "plum",
96
- complex : "yellow",
97
- str : "cyan",
98
- # ================= linear
99
- tuple : "orange",
100
- list : "lightcoral",
101
- set : "orchid1",
102
- frozenset : "orchid2",
103
- bytes : "khaki1",
104
- bytearray : "khaki2",
105
- # ================= key_value
106
- Node_Key_Value : "seagreen1", # for classes
107
- call_stack : 'khaki',
108
- type: "seagreen3", # where class variables are stored
109
- dict : "#60a5ff",
110
- types.MappingProxyType : "dodgerblue2", # not used
111
- range : "cornsilk2",
112
- # ================= exception
113
- BaseException : "#ff5555",
114
- }
115
-
116
179
 
117
180
  """ Types that will be visualized in horizontal or vertical orientation based on a True/False value.
118
181
  The 'type_to_horizontal' takes precedence over 'type_to_vertical'.
@@ -6,9 +6,9 @@ import memory_graph.config as config
6
6
  import memory_graph.config_helpers as config_helpers
7
7
  import memory_graph.utils as utils
8
8
 
9
- def html_table_frame(s, border, color, spacing=5):
9
+ def html_table_frame(s, border, color, line_color='black', spacing=5):
10
10
  """ Helper function to add the HTML table frame to the string s setting the 'border' and 'color'. """
11
- return (f'<\n<TABLE BORDER="{border}" CELLBORDER="1" CELLSPACING="{spacing}" CELLPADDING="0" BGCOLOR="{color}" PORT="table">\n <TR>' +
11
+ return (f'<\n<TABLE BORDER="{border}" CELLBORDER="1" CELLSPACING="{spacing}" CELLPADDING="0" BGCOLOR="{color}" COLOR="{line_color}" PORT="table">\n <TR>' +
12
12
  s + '</TR>\n</TABLE>\n>')
13
13
 
14
14
  def format_string(value, quote_str):
@@ -60,7 +60,7 @@ class HTML_Table:
60
60
  def add_index(self, s):
61
61
  """ Add an index s to the table. """
62
62
  self.check_add_new_line()
63
- self.html += f'<TD BORDER="0"><font color="#505050">{str(s)}</font></TD>'
63
+ self.html += f'<TD BORDER="0"><font color="{config.index_color}">{str(s)}</font></TD>'
64
64
  self.col_count += 1
65
65
 
66
66
  def add_entry(self, node, nodes, child, id_to_slices, rounded=False, border=1, dashed=False, embed=False):
@@ -100,13 +100,13 @@ class HTML_Table:
100
100
  self.html += f'<TD BORDER="{border}" {r}>...</TD>'
101
101
  self.col_count += 1
102
102
 
103
- def to_string(self, border=1, color='white'):
103
+ def to_string(self, border=1, color='white', line_color='black'):
104
104
  """ Construct the HTML table string with the 'border' and 'color' settings. """
105
105
  if self.col_count == 0 and self.row_count == 0:
106
106
  if self.is_empty:
107
107
  self.add_value(utils.unquoted_str(''), border=0)
108
- return html_table_frame(self.html, border, color, spacing=0)
109
- return html_table_frame(self.html, border, color)
108
+ return html_table_frame(self.html, border, color, line_color, spacing=0)
109
+ return html_table_frame(self.html, border, color, line_color)
110
110
 
111
111
  def get_column(self):
112
112
  """ Get the number of columns in the table. """
@@ -218,11 +218,11 @@ def build_graph(graphviz_graph, nodes, root_id, id_to_slices):
218
218
  border = 3 if node.is_root() else 1
219
219
  if config.type_labels:
220
220
  graphviz_graph.node(node.get_name(),
221
- html_table.to_string(border, color),
221
+ html_table.to_string(border, color, config.foreground_color),
222
222
  xlabel=node.get_label(slices))
223
223
  else:
224
224
  graphviz_graph.node(node.get_name(),
225
- html_table.to_string(border, color))
225
+ html_table.to_string(border, color, config.foreground_color))
226
226
  # ------------ edges
227
227
  for parent,child,dashed in edges:
228
228
  graphviz_graph.edge(parent, child+':table', style='dashed' if dashed else 'solid')
@@ -261,9 +261,9 @@ def memory_to_nodes(data):
261
261
  id_to_slices = add_missing_edges(nodes, id_to_slices, config.max_missing_edges)
262
262
  #print('id_to_slices:',id_to_slices)
263
263
  embed_keys_in_key_value_nodes(nodes, nodes_key_value, id_to_slices)
264
- graphviz_graph_attr = {'fontname': config.fontname, 'fontsize': config.fontsize}
265
- graphviz_node_attr = {'fontname': config.fontname, 'fontsize': config.fontsize, 'shape': 'plaintext'}
266
- graphviz_edge_attr = {'fontname': config.fontname, 'fontsize': config.fontsize}
264
+ graphviz_graph_attr = {'fontname': config.fontname, 'fontsize': config.fontsize, 'fontcolor': config.foreground_color, 'bgcolor': config.background_color}
265
+ graphviz_node_attr = {'fontname': config.fontname, 'fontsize': config.fontsize, 'shape': 'plaintext', 'fontcolor': config.foreground_color}
266
+ graphviz_edge_attr = {'fontname': config.fontname, 'fontsize': config.fontsize, 'fontcolor': config.foreground_color, 'color': config.foreground_color}
267
267
  graphviz_graph=graphviz.Digraph('memory_graph',
268
268
  graph_attr=graphviz_graph_attr,
269
269
  node_attr=graphviz_node_attr,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memory_graph
3
- Version: 0.3.78
3
+ Version: 0.3.79
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-Expression: BSD-2-Clause
@@ -27,7 +27,7 @@ Additionally [Graphviz](https://graphviz.org/download/) needs to be installed.
27
27
 
28
28
  # Highlights #
29
29
  ![vscode_copying.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/vscode_copying.gif)
30
- Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph.com/#breakpoints=8&continues=1&timestep=1.0&play) 👈 now, no installation required!
30
+ Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph.com/#breakpoints=8&continues=1&play) 👈 now, no installation required!
31
31
 
32
32
  - learn the right **mental model** to think about Python data (references, mutability, shallow vs deep copy)
33
33
  - **visualize the structure of your data** to more easily understand and debug any data structure
@@ -35,7 +35,7 @@ Run a live demo in the 👉 [**Memory Graph Web Debugger**](https://memory-graph
35
35
 
36
36
  An example Binary Tree data structure:
37
37
  ![bin_tree_vs.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/bin_tree_vs.gif)
38
- 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&timestep=0.2&play).
38
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_tree.py&timestep=0.2&play).
39
39
 
40
40
  # Videos #
41
41
  | [![Quick Intro](https://img.youtube.com/vi/23_bHcr7hqo/0.jpg)](https://www.youtube.com/watch?v=23_bHcr7hqo) | [![Mutability](https://img.youtube.com/vi/pvIJgHCaXhU/0.jpg)](https://www.youtube.com/watch?v=pvIJgHCaXhU) |
@@ -163,7 +163,7 @@ Bas Terwijn
163
163
  ## Inspiration ##
164
164
  Inspired by [Python Tutor](https://pythontutor.com/).
165
165
 
166
- The main differences are that by running memory_graph locally we support Python Tutor’s [unsupported features](https://github.com/pythontutor-dev/pythontutor/blob/master/unsupported-features.md#unsupported-features) so that it scales to full programs in many environments and IDEs instead of just code snippets in a webbrowser, and by mirroring the data’s hierarchy we improve graph readability for larger graphs.
166
+ The main differences are that by running memory_graph locally we support Python Tutor’s [unsupported features](https://github.com/pythontutor-dev/pythontutor/blob/master/unsupported-features.md#unsupported-features) so that it scales to full multi-file programs in many environments and IDEs instead of just code snippets in a webbrowser, and by mirroring the data’s hierarchy we improve graph readability for larger graphs.
167
167
 
168
168
  ## Social Media #
169
169
  * [LinkedIn](https://www.linkedin.com/groups/13244150/)
@@ -242,7 +242,7 @@ mg.show(locals())
242
242
 
243
243
  ![copy_mutbale.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/copy_mutable.png)
244
244
 
245
- 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/copies.py&play).
245
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/copies.py&play).
246
246
 
247
247
  ## Custom Copy ##
248
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.
@@ -270,7 +270,7 @@ mg.show(locals())
270
270
  ```
271
271
  ![copy_method.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/copy_method.png)
272
272
 
273
- 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/custom_copy.py&breakpoints=15&continues=1&play).
273
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/custom_copy.py&breakpoints=15&continues=1&play).
274
274
 
275
275
  ## Name Rebinding ##
276
276
  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 affecting any other variable.
@@ -300,7 +300,7 @@ mg.render(locals(), 'rebinding3.png')
300
300
  |:--------------:|:--------------:|:--------------:|
301
301
  | rebinding1.png | rebinding2.png | rebinding3.png |
302
302
 
303
- 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/rebind.py&play).
303
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/rebind.py&play).
304
304
 
305
305
  ## Copying Values of Immutable Type ##
306
306
  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.
@@ -358,7 +358,7 @@ print(f"a:{a} b:{b} c:{c}")
358
358
  ```
359
359
  ![add_one.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/add_one.png)
360
360
 
361
- 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/function_call.py&play).
361
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/function_call.py&play).
362
362
 
363
363
  In the printed output we see that only `a` is changed as a result of the function call:
364
364
  ```
@@ -387,7 +387,7 @@ print(f"a:{a} b:{b[0]}")
387
387
  ```
388
388
  a:10 b:11
389
389
  ```
390
- 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/wrap.py&breakpoints=5&continues=1&play)
390
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/wrap.py&breakpoints=5&continues=1&play)
391
391
 
392
392
  The effect of calling `add_one()` is that `b[0]` increases by 1, while `a` is unaffected.
393
393
 
@@ -428,7 +428,7 @@ print( factorial(4) )
428
428
 
429
429
  and the result is: 1 x 2 x 3 x 4 = 24
430
430
 
431
- 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&timestep=1.0&play).
431
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/factorial.py&timestep=1.0&play).
432
432
 
433
433
  ## Binary Conversion ##
434
434
  A more interesting recursive example is function `binary()` that converts a integer from decimal to binary representation.
@@ -452,7 +452,7 @@ print( binary(100) )
452
452
  [1, 1, 0, 0, 1, 0, 0]
453
453
  ```
454
454
 
455
- 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&timestep=1.0&play).
455
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/binary_convert.py&timestep=1.0&play).
456
456
 
457
457
  ## Power Set ##
458
458
  A more complex recursive example is function `power_set()` where lists are shared by different function calls. A power set is the set of all subsets of a collection of values.
@@ -484,7 +484,7 @@ print( power_set(['a', 'b', 'c']) )
484
484
  [['a', 'b', 'c'], ['a', 'b'], ['a', 'c'], ['a'], ['b', 'c'], ['b'], ['c'], []]
485
485
  ```
486
486
 
487
- 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&timestep=1.0&play).
487
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/power_set.py&timestep=1.0&play).
488
488
 
489
489
  ## Invocation Tree ##
490
490
  The memory_graph package visualizes data at the currect time, but to better understand recursion it can also be helpful to visualize different function calls over time. This is what the [invocation_tree](https://github.com/bterwijn/invocation_tree?tab=readme-ov-file#installation) package does.
@@ -648,7 +648,7 @@ for i in range(n):
648
648
  Here we show values being added to a Linked List in Cursor AI. When adding the last value '5' we "Step Into" the code to show more of the details.
649
649
  ![linked_list.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/linked_list.gif)
650
650
 
651
- 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/linked_list.py&timestep=0.2&play).
651
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/linked_list.py&timestep=0.2&play).
652
652
 
653
653
  ## Binary Tree ##
654
654
  ```python
@@ -690,7 +690,7 @@ for i in range(n):
690
690
  Here we show values being inserted in a Binary Tree in Visual Studio Code. When inserting the last value '29' we "Step Into" the code to show the recursive implementation.
691
691
  ![images/bin_tree.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/bin_tree.gif)
692
692
 
693
- 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&timestep=0.2&play) or see the more advanced [Multiway Tree](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/multiway_tree.py&breakpoints=19,33&continues=1&timestep=0.2&play) with more than two children per node, making the tree less deep and more efficient.
693
+ See it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_tree.py&timestep=0.2&play) or see the more advanced [Multiway Tree](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/multiway_tree.py&breakpoints=19,33&continues=1&timestep=0.2&play) with more than two children per node, making the tree less deep and more efficient.
694
694
 
695
695
  ## Hash Set ##
696
696
  ```python
@@ -734,7 +734,7 @@ for i in range(n):
734
734
  Here we show values being inserted in a HashSet in PyCharm. When inserting the last value '44' we "Step Into" the code to show more of the details.
735
735
  ![images/hash_set.gif](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/hash_set.gif)
736
736
 
737
- 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/hash_set.py&breakpoints=32&continues=1&timestep=0.5&play).
737
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/hash_set.py&breakpoints=32&continues=1&timestep=0.5&play).
738
738
 
739
739
 
740
740
  # Sorting Algorithms #
@@ -761,7 +761,7 @@ In this configuration example we show the decimal, binary and [two's complement
761
761
 
762
762
  A sliding puzzle solver as a challenging example showing how memory_graph deals with large amounts of data. Click "Continue" to step through the breadth-first search generations until a solution path is found:
763
763
 
764
- - [sliding puzzle solver](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/sliding_puzzle.py&breakpoints=16,26,28,39&continues=1)
764
+ - [sliding puzzle solver](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/sliding_puzzle.py&breakpoints=16,26,28,39,136&continues=1)
765
765
 
766
766
  ![sliding_puzzle.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/sliding_puzzle.png)
767
767
 
@@ -1255,7 +1255,66 @@ mg.config.type_to_node[List_View] = (lambda l: mg.Node_Linear(l,
1255
1255
  ```
1256
1256
  ![bin_search_linear.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/bin_search_linear.png)
1257
1257
 
1258
- 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_search.py&breakpoints=32&continues=1&timestep=0.5&play)
1258
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/bin_search.py&breakpoints=38&continues=1&timestep=0.5&play)
1259
+
1260
+ ## String Types ##
1261
+
1262
+ For special string formatting different `str` types are available:
1263
+
1264
+ | string type | format |
1265
+ |:--------------------------:|:--------------------:|
1266
+ | `str` | normal Python `str` type is limited by `config.max_string_length` |
1267
+ | `mg.full_str('text')` | not limited |
1268
+ | `mg.unquoted_str('text')` | not limited and not quoted |
1269
+ | `mg.html_str('text')` | for [Grahviz html-like formatting](https://graphviz.org/doc/info/shapes.html#html) |
1270
+
1271
+ The [Grahviz html-like formatting](https://graphviz.org/doc/info/shapes.html#html) supports a subset of html tags that allow for things like:
1272
+ ```python
1273
+ import memory_graph as mg
1274
+
1275
+ elements = ['<B>bold</B>',
1276
+ '<I>italic</I>',
1277
+ '<S>strikethrough</S>',
1278
+ '<U>under</U><O>over</O>',
1279
+ '<SUB>sub</SUB><SUP>sup</SUP>',
1280
+ '<FONT FACE="Courier">monospaced</FONT>',
1281
+ '<FONT COLOR="red">red</FONT><FONT COLOR="green">green</FONT>',
1282
+ '<FONT POINT-SIZE="20">Large</FONT><FONT POINT-SIZE="10">small</FONT>',
1283
+ '<TABLE BORDER="1"><TR><TD>c1</TD><TD>c2</TD></TR></TABLE>',
1284
+ 'line1<BR/>line2<BR/>line3<BR/>']
1285
+
1286
+ normal_str = '<TABLE BORDER="0">\n'
1287
+ for element in elements:
1288
+ normal_str += '<TR><TD> ' + mg.utils.html_escape(element) + ' </TD><TD> ' + element+ ' </TD></TR>element\n'
1289
+ normal_str += '</TABLE>\n'
1290
+
1291
+ html_example = mg.html_str(normal_str)
1292
+ del elements, element, normal_str
1293
+ mg.show(locals())
1294
+ ```
1295
+ ![html_str_example.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/html_str_example.png)
1296
+
1297
+ Including the `<IMG>` tag that allows for showing local image files only, but that currently doesn't work in the Memory Graph Web Debugger, that uses 'Viz.js' for graph rendering, unfortunately.
1298
+
1299
+ ```python
1300
+ import memory_graph as mg
1301
+ import matplotlib.pyplot as plt
1302
+ import random
1303
+ random.seed(0)
1304
+
1305
+ N = 100
1306
+ value = 0
1307
+ data = [value]
1308
+ for i in range(N):
1309
+ value += random.uniform(-1, 1)
1310
+ data.append(value)
1311
+
1312
+ plt.plot(data)
1313
+ plt.savefig('plot.png')
1314
+ image = {mg.html_str('<IMG SRC="plot.png"/>')}
1315
+ mg.show(locals())
1316
+ ```
1317
+ ![html_str_image.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/html_str_image.png)
1259
1318
 
1260
1319
  ## Collapse Type ##
1261
1320
 
@@ -1388,7 +1447,7 @@ mg.show(locals())
1388
1447
  ```
1389
1448
  ![extension_numpy.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_numpy.png)
1390
1449
 
1391
- Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_numpy.py&play).
1450
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_numpy.py&play).
1392
1451
 
1393
1452
  ## Pandas ##
1394
1453
  For pandas types `Series` and `DataFrame`, use `mg.extend_pandas()`:
@@ -1409,7 +1468,7 @@ mg.show(locals())
1409
1468
  ```
1410
1469
  ![extension_pandas.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_pandas.png)
1411
1470
 
1412
- Or see it in the [Memory Grah Web Debugger](https://memory-graph.com/#micropip=pandas&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_pandas.py&play).
1471
+ Or see it in the [Memory Graph Web Debugger](https://memory-graph.com/#micropip=pandas&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/mg_pandas.py&play).
1413
1472
 
1414
1473
  ## PyTorch ##
1415
1474
  For torch type `tensor`, use `mg.extend_torch()`:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memory_graph"
7
- version = "0.3.78"
7
+ version = "0.3.79"
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"}
File without changes
File without changes
File without changes