memory-graph 0.3.89__tar.gz → 0.3.91__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 (43) hide show
  1. {memory_graph-0.3.89 → memory_graph-0.3.91}/PKG-INFO +83 -13
  2. {memory_graph-0.3.89 → memory_graph-0.3.91}/README.md +82 -12
  3. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/__init__.py +34 -10
  4. memory_graph-0.3.91/memory_graph/extension_polars.py +30 -0
  5. memory_graph-0.3.91/memory_graph/extension_sqlite3.py +104 -0
  6. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/utils.py +9 -0
  7. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph.egg-info/PKG-INFO +83 -13
  8. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph.egg-info/SOURCES.txt +2 -0
  9. {memory_graph-0.3.89 → memory_graph-0.3.91}/pyproject.toml +1 -1
  10. {memory_graph-0.3.89 → memory_graph-0.3.91}/LICENSE.txt +0 -0
  11. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/call_stack.py +0 -0
  12. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/config.py +0 -0
  13. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/config_default.py +0 -0
  14. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/config_helpers.py +0 -0
  15. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/extension_numpy.py +0 -0
  16. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/extension_pandas.py +0 -0
  17. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/extension_torch.py +0 -0
  18. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/html_table.py +0 -0
  19. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/list_view.py +0 -0
  20. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/memory_to_nodes.py +0 -0
  21. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/node_base.py +0 -0
  22. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/node_key_value.py +0 -0
  23. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/node_leaf.py +0 -0
  24. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/node_linear.py +0 -0
  25. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/node_table.py +0 -0
  26. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/sequence.py +0 -0
  27. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/slicer.py +0 -0
  28. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/slices.py +0 -0
  29. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/slices_iterator.py +0 -0
  30. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/slices_table_iterator.py +0 -0
  31. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test.py +0 -0
  32. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_max_graph_depth.py +0 -0
  33. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_memory_graph.py +0 -0
  34. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_memory_to_nodes.py +0 -0
  35. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_sequence.py +0 -0
  36. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_slicer.py +0 -0
  37. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_slices.py +0 -0
  38. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_slices_iterator.py +0 -0
  39. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph.egg-info/dependency_links.txt +0 -0
  40. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph.egg-info/requires.txt +0 -0
  41. {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph.egg-info/top_level.txt +0 -0
  42. {memory_graph-0.3.89 → memory_graph-0.3.91}/setup.cfg +0 -0
  43. {memory_graph-0.3.89 → memory_graph-0.3.91}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memory_graph
3
- Version: 0.3.89
3
+ Version: 0.3.91
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
@@ -1190,14 +1190,28 @@ mg.show(locals())
1190
1190
  ```
1191
1191
  ![avltree_fail.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_fail.png)
1192
1192
 
1193
- ## All attributes using dir() ##
1194
- Then first give it some color, show the its attributes using either of:
1193
+ ## Show attributes using build_node() ##
1194
+ Then first give it some color, show its attributes using:
1195
1195
 
1196
- - mg.node_all_attributes(data)
1197
- - mg.node_non_callable_attributes(data)
1198
- - mg.node_non_dunder_attributes(data)
1196
+ ```python
1197
+ mg.build_node(data)
1198
+ ```
1199
1199
 
1200
- and set an empty Slicer to see all attributes.
1200
+ optionally filter attributes using:
1201
+
1202
+ ```python
1203
+ mg.build_node(data,
1204
+ filters=[mg.filter_non_callable,
1205
+ mg.filter_non_dunder,
1206
+ mg.filter_non_underscore
1207
+ mg.filter_names({'left', 'right'}),
1208
+ lambda kvs : ((k,v) for k,v in kvs
1209
+ if k in {'left', 'right'} and
1210
+ not callable(v))
1211
+ ])
1212
+ ```
1213
+
1214
+ and set an empty Slicer to show all attributes even if the sequence is long.
1201
1215
 
1202
1216
  ```python
1203
1217
  import memory_graph as mg
@@ -1211,8 +1225,8 @@ tree.insert(20, "twenty")
1211
1225
  tree.insert(15, "fifteen")
1212
1226
 
1213
1227
  mg.config.type_to_color[bintrees.avltree.Node] = "sandybrown"
1214
- mg.config.type_to_node[bintrees.avltree.Node] = lambda data:
1215
- mg.node_non_dunder_attributes(data)
1228
+ mg.config.type_to_node[bintrees.avltree.Node] = lambda data: mg.build_node(data,
1229
+ filters=[mg.filter_non_dunder])
1216
1230
  mg.config.type_to_slicer[bintrees.avltree.Node] = mg.Slicer()
1217
1231
 
1218
1232
  mg.show(locals())
@@ -1542,8 +1556,8 @@ mg.show(locals())
1542
1556
  # Extensions #
1543
1557
  Different extensions are available for types from other Python packages.
1544
1558
 
1545
- ## Numpy ##
1546
- For Numpy types `array` and `matrix` and `ndarray`, use `mg.extend_numpy()`:
1559
+ ## NumPy ##
1560
+ For NumPy types `array` and `matrix` and `ndarray`, use `mg.extend_numpy()`:
1547
1561
 
1548
1562
  ```python
1549
1563
  import memory_graph as mg
@@ -1562,10 +1576,10 @@ mg.show(locals())
1562
1576
 
1563
1577
  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).
1564
1578
 
1565
- See this [introduction to numpy operations](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/numpy_operations.py&timestep=0.5&play).
1579
+ See this [introduction to NumPy operations](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/numpy_operations.py&timestep=0.5&play).
1566
1580
 
1567
1581
  ## Pandas ##
1568
- For pandas types `Series` and `DataFrame`, use `mg.extend_pandas()`:
1582
+ For Pandas types `Series` and `DataFrame`, use `mg.extend_pandas()`:
1569
1583
 
1570
1584
  ```python
1571
1585
  import memory_graph as mg
@@ -1585,6 +1599,29 @@ mg.show(locals())
1585
1599
 
1586
1600
  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).
1587
1601
 
1602
+ See this [introduction to Pandas operations](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/pandas_operations.py&timestep=0.5&play).
1603
+
1604
+ ## Polars ##
1605
+ For Polars types `DataFrame`, use `mg.extend_polars()`:
1606
+
1607
+ ```python
1608
+ import memory_graph as mg
1609
+ import polars as pl
1610
+ mg.extend_polars()
1611
+
1612
+ df = pl.DataFrame(
1613
+ {
1614
+ "name": ["Alice Archer", "Ben Brown", "Chloe Cooper", "Daniel Donovan"],
1615
+ "weight": [57.9, 72.5, 53.6, 83.1], # (kg)
1616
+ "height": [1.56, 1.77, 1.65, 1.75], # (m)
1617
+ }
1618
+ )
1619
+
1620
+ mg.show(locals())
1621
+ ```
1622
+ ![extension_polars.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_polars.png)
1623
+
1624
+
1588
1625
  ## PyTorch ##
1589
1626
  For torch type `tensor`, use `mg.extend_torch()`:
1590
1627
 
@@ -1602,6 +1639,39 @@ mg.show(locals())
1602
1639
  ```
1603
1640
  ![extension_torch.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_torch.png)
1604
1641
 
1642
+ ## SQLite3 ##
1643
+ For sqlite3 use `mg.extend_sqlite3()`:
1644
+
1645
+ ```python
1646
+ import memory_graph as mg
1647
+ import sqlite3
1648
+ mg.extend_sqlite3()
1649
+
1650
+ conn = sqlite3.connect(":memory:")
1651
+
1652
+ conn.executescript("""
1653
+ CREATE TABLE students (
1654
+ id INTEGER PRIMARY KEY,
1655
+ name TEXT NOT NULL,
1656
+ age INTEGER
1657
+ );
1658
+ """)
1659
+
1660
+ conn.executemany(
1661
+ "INSERT INTO students VALUES (?, ?, ?)",
1662
+ [
1663
+ (1, "Alice", 20),
1664
+ (2, "Bob", 21),
1665
+ (3, "Charlie", 22),
1666
+ ]
1667
+ )
1668
+
1669
+ mg.show(locals())
1670
+ conn.close()
1671
+ ```
1672
+ ![extension_sqlite3.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_sqlite3.png)
1673
+
1674
+
1605
1675
  # Memory Graph Web Debugger #
1606
1676
  The <a href="https://memory-graph.com/#play" target="_blank">Memory Graph Web Debugger</a> lets us use memory_graph without any installation.
1607
1677
  ![memory_graph_web_debugger.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/memory_graph_web_debugger.png)
@@ -1170,14 +1170,28 @@ mg.show(locals())
1170
1170
  ```
1171
1171
  ![avltree_fail.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_fail.png)
1172
1172
 
1173
- ## All attributes using dir() ##
1174
- Then first give it some color, show the its attributes using either of:
1173
+ ## Show attributes using build_node() ##
1174
+ Then first give it some color, show its attributes using:
1175
1175
 
1176
- - mg.node_all_attributes(data)
1177
- - mg.node_non_callable_attributes(data)
1178
- - mg.node_non_dunder_attributes(data)
1176
+ ```python
1177
+ mg.build_node(data)
1178
+ ```
1179
1179
 
1180
- and set an empty Slicer to see all attributes.
1180
+ optionally filter attributes using:
1181
+
1182
+ ```python
1183
+ mg.build_node(data,
1184
+ filters=[mg.filter_non_callable,
1185
+ mg.filter_non_dunder,
1186
+ mg.filter_non_underscore
1187
+ mg.filter_names({'left', 'right'}),
1188
+ lambda kvs : ((k,v) for k,v in kvs
1189
+ if k in {'left', 'right'} and
1190
+ not callable(v))
1191
+ ])
1192
+ ```
1193
+
1194
+ and set an empty Slicer to show all attributes even if the sequence is long.
1181
1195
 
1182
1196
  ```python
1183
1197
  import memory_graph as mg
@@ -1191,8 +1205,8 @@ tree.insert(20, "twenty")
1191
1205
  tree.insert(15, "fifteen")
1192
1206
 
1193
1207
  mg.config.type_to_color[bintrees.avltree.Node] = "sandybrown"
1194
- mg.config.type_to_node[bintrees.avltree.Node] = lambda data:
1195
- mg.node_non_dunder_attributes(data)
1208
+ mg.config.type_to_node[bintrees.avltree.Node] = lambda data: mg.build_node(data,
1209
+ filters=[mg.filter_non_dunder])
1196
1210
  mg.config.type_to_slicer[bintrees.avltree.Node] = mg.Slicer()
1197
1211
 
1198
1212
  mg.show(locals())
@@ -1522,8 +1536,8 @@ mg.show(locals())
1522
1536
  # Extensions #
1523
1537
  Different extensions are available for types from other Python packages.
1524
1538
 
1525
- ## Numpy ##
1526
- For Numpy types `array` and `matrix` and `ndarray`, use `mg.extend_numpy()`:
1539
+ ## NumPy ##
1540
+ For NumPy types `array` and `matrix` and `ndarray`, use `mg.extend_numpy()`:
1527
1541
 
1528
1542
  ```python
1529
1543
  import memory_graph as mg
@@ -1542,10 +1556,10 @@ mg.show(locals())
1542
1556
 
1543
1557
  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).
1544
1558
 
1545
- See this [introduction to numpy operations](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/numpy_operations.py&timestep=0.5&play).
1559
+ See this [introduction to NumPy operations](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/numpy_operations.py&timestep=0.5&play).
1546
1560
 
1547
1561
  ## Pandas ##
1548
- For pandas types `Series` and `DataFrame`, use `mg.extend_pandas()`:
1562
+ For Pandas types `Series` and `DataFrame`, use `mg.extend_pandas()`:
1549
1563
 
1550
1564
  ```python
1551
1565
  import memory_graph as mg
@@ -1565,6 +1579,29 @@ mg.show(locals())
1565
1579
 
1566
1580
  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).
1567
1581
 
1582
+ See this [introduction to Pandas operations](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/pandas_operations.py&timestep=0.5&play).
1583
+
1584
+ ## Polars ##
1585
+ For Polars types `DataFrame`, use `mg.extend_polars()`:
1586
+
1587
+ ```python
1588
+ import memory_graph as mg
1589
+ import polars as pl
1590
+ mg.extend_polars()
1591
+
1592
+ df = pl.DataFrame(
1593
+ {
1594
+ "name": ["Alice Archer", "Ben Brown", "Chloe Cooper", "Daniel Donovan"],
1595
+ "weight": [57.9, 72.5, 53.6, 83.1], # (kg)
1596
+ "height": [1.56, 1.77, 1.65, 1.75], # (m)
1597
+ }
1598
+ )
1599
+
1600
+ mg.show(locals())
1601
+ ```
1602
+ ![extension_polars.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_polars.png)
1603
+
1604
+
1568
1605
  ## PyTorch ##
1569
1606
  For torch type `tensor`, use `mg.extend_torch()`:
1570
1607
 
@@ -1582,6 +1619,39 @@ mg.show(locals())
1582
1619
  ```
1583
1620
  ![extension_torch.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_torch.png)
1584
1621
 
1622
+ ## SQLite3 ##
1623
+ For sqlite3 use `mg.extend_sqlite3()`:
1624
+
1625
+ ```python
1626
+ import memory_graph as mg
1627
+ import sqlite3
1628
+ mg.extend_sqlite3()
1629
+
1630
+ conn = sqlite3.connect(":memory:")
1631
+
1632
+ conn.executescript("""
1633
+ CREATE TABLE students (
1634
+ id INTEGER PRIMARY KEY,
1635
+ name TEXT NOT NULL,
1636
+ age INTEGER
1637
+ );
1638
+ """)
1639
+
1640
+ conn.executemany(
1641
+ "INSERT INTO students VALUES (?, ?, ?)",
1642
+ [
1643
+ (1, "Alice", 20),
1644
+ (2, "Bob", 21),
1645
+ (3, "Charlie", 22),
1646
+ ]
1647
+ )
1648
+
1649
+ mg.show(locals())
1650
+ conn.close()
1651
+ ```
1652
+ ![extension_sqlite3.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_sqlite3.png)
1653
+
1654
+
1585
1655
  # Memory Graph Web Debugger #
1586
1656
  The <a href="https://memory-graph.com/#play" target="_blank">Memory Graph Web Debugger</a> lets us use memory_graph without any installation.
1587
1657
  ![memory_graph_web_debugger.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/memory_graph_web_debugger.png)
@@ -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.89"
5
+ __version__ = "0.3.91"
6
6
  __author__ = 'Bas Terwijn'
7
7
 
8
8
  import memory_graph.memory_to_nodes as memory_to_nodes
@@ -520,6 +520,13 @@ def extend_pandas(on=True):
520
520
  else:
521
521
  ext_pd.unextend_pandas()
522
522
 
523
+ def extend_polars(on=True):
524
+ import memory_graph.extension_polars as ext_pl
525
+ if on:
526
+ ext_pl.extend_polars()
527
+ else:
528
+ ext_pl.unextend_polars()
529
+
523
530
  def extend_torch(on=True):
524
531
  import memory_graph.extension_torch as ext_torch
525
532
  if on:
@@ -527,6 +534,12 @@ def extend_torch(on=True):
527
534
  else:
528
535
  ext_torch.unextend_torch()
529
536
 
537
+ def extend_sqlite3(on=True):
538
+ import memory_graph.extension_sqlite3 as ext_sqlite3
539
+ if on:
540
+ ext_sqlite3.extend_sqlite3()
541
+ else:
542
+ ext_sqlite3.unextend_sqlite3()
530
543
 
531
544
  # ------------ collapse type
532
545
 
@@ -540,12 +553,23 @@ def reset_type(type_name):
540
553
 
541
554
  # ------------ atributes to Node_Key_Value
542
555
 
543
- def node_all_attributes(data):
544
- return Node_Key_Value(data, [(attr, getattr(data, attr)) for attr in dir(data)])
545
-
546
- def node_non_callable_attributes(data):
547
- attr_values = [(attr, getattr(data, attr)) for attr in dir(data)]
548
- return Node_Key_Value(data, [(attr, value) for attr, value in attr_values if not callable(value)])
549
-
550
- def node_non_dunder_attributes(data):
551
- return Node_Key_Value(data, [(attr, getattr(data, attr)) for attr in dir(data) if not attr.startswith('__')])
556
+ def build_node(data, filters=None):
557
+ attr_values = ((attr, utils.safe_getattr(data, attr)) for attr in dir(data))
558
+ if filters is not None:
559
+ for filter in filters:
560
+ attr_values = filter(attr_values)
561
+ return Node_Key_Value(data, ((attr, value)
562
+ for attr, value in attr_values
563
+ if value is not utils.SENTINEL
564
+ ))
565
+
566
+ def filter_non_callable(tuples):
567
+ return ((k,v) for k, v in tuples if not callable(v))
568
+ def filter_non_dunder(tuples):
569
+ return ((k,v) for k, v in tuples if not k.startswith('__'))
570
+ def filter_non_underscore(tuples):
571
+ return ((k,v) for k, v in tuples if not k.startswith('_'))
572
+ def filter_names(names):
573
+ def filter(tuples):
574
+ return ((k,v) for k, v in tuples if k in names)
575
+ return filter
@@ -0,0 +1,30 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
5
+ """ Extension to add the memory graph configuration for Polars types. """
6
+ from memory_graph.node_table import Node_Table
7
+
8
+ import memory_graph.config as config
9
+ import memory_graph.config_default as config_default
10
+
11
+ def extend_polars():
12
+ import polars as pl
13
+
14
+ #config.type_to_color[pl.DataFrame] = "aquamarine"
15
+ config.type_to_node[pl.DataFrame] = lambda df: Node_Table(df,
16
+ df.iter_rows(),
17
+ col_names = df.columns)
18
+ config_default.type_to_color_light[pl.DataFrame] = "aquamarine"
19
+ config_default.type_to_color_dark[pl.DataFrame] = "#295345"
20
+
21
+ if not config.color_mode_dark:
22
+ config.type_to_color[pl.DataFrame] = config_default.type_to_color_light[pl.DataFrame]
23
+ else:
24
+ config.type_to_color[pl.DataFrame] = config_default.type_to_color_dark[pl.DataFrame]
25
+
26
+ def unextend_polars():
27
+ import polars as pl
28
+
29
+ del config.type_to_node[pl.DataFrame]
30
+ del config.type_to_color[pl.DataFrame]
@@ -0,0 +1,104 @@
1
+ # This file is part of memory_graph.
2
+ # Copyright (c) 2023, Bas Terwijn.
3
+ # SPDX-License-Identifier: BSD-2-Clause
4
+
5
+ """ Extension to add the memory graph configuration for Numpy types. """
6
+ from memory_graph.node_key_value import Node_Key_Value
7
+ from memory_graph.node_table import Node_Table
8
+
9
+
10
+ import memory_graph.config as config
11
+ import memory_graph.config_default as config_default
12
+
13
+
14
+ class SQLite3_Table:
15
+ def __init__(self, header, rows, column_types, primary_keys, foreign_keys):
16
+ self.header = header
17
+ self.rows = rows
18
+ self.column_types = column_types
19
+ self.primary_keys = primary_keys
20
+ self.foreign_keys = foreign_keys
21
+
22
+
23
+ def get_table(conn, table_name):
24
+ # Quote the table name safely
25
+ name = '"' + table_name.replace('"', '""') + '"'
26
+
27
+ cursor = conn.execute(f"SELECT * FROM {name}")
28
+ header = [col[0] for col in cursor.description]
29
+ rows = iter(cursor) # lazy iteration
30
+ # Column types: column name -> declared SQLite type
31
+ # Primary keys: column name -> position in composite primary key
32
+ column_info = list(conn.execute(f"PRAGMA table_info({name})"))
33
+ column_types = {
34
+ col[1]: col[2]
35
+ for col in column_info
36
+ }
37
+ primary_keys = {
38
+ col[1]: col[5]
39
+ for col in column_info
40
+ if col[5] > 0
41
+ }
42
+ # Foreign keys: (column, referenced table, referenced column)
43
+ foreign_keys = [
44
+ (fk[3], fk[2], fk[4])
45
+ for fk in conn.execute(f"PRAGMA foreign_key_list({name})")
46
+ ]
47
+ return SQLite3_Table(
48
+ header, rows, column_types, primary_keys, foreign_keys
49
+ )
50
+
51
+
52
+ def get_tables(conn):
53
+ table_names = (
54
+ row[0] for row in conn.execute(
55
+ "SELECT name FROM sqlite_master "
56
+ "WHERE type = 'table' AND name NOT LIKE 'sqlite_%'"
57
+ )
58
+ )
59
+ tables = {name: get_table(conn, name) for name in table_names}
60
+ return tables
61
+
62
+
63
+ def sqlite_table_node(d):
64
+ headers = []
65
+ for name in d.header:
66
+ labels = []
67
+ # Declared SQLite column type
68
+ column_type = d.column_types.get(name)
69
+ if column_type:
70
+ labels.append(column_type)
71
+ # Primary key
72
+ if name in d.primary_keys:
73
+ labels.append("PK")
74
+ # Foreign key
75
+ if any(fk[0] == name for fk in d.foreign_keys):
76
+ labels.append("FK")
77
+
78
+ suffix = f" ({', '.join(labels)})" if labels else ""
79
+ headers.append(name + suffix)
80
+ return Node_Table(
81
+ d,
82
+ list(d.rows),
83
+ col_names=headers
84
+ )
85
+
86
+ def extend_sqlite3():
87
+ import sqlite3
88
+
89
+ config.type_to_node[sqlite3.Connection] = (
90
+ lambda d: Node_Key_Value(d, get_tables(d).items())
91
+ )
92
+ config.type_to_node[SQLite3_Table] = sqlite_table_node
93
+
94
+ config_default.type_to_color_light[SQLite3_Table] = "lightcyan"
95
+ config_default.type_to_color_dark[SQLite3_Table] = "#2c4f52"
96
+
97
+ if not config.color_mode_dark:
98
+ config.type_to_color[SQLite3_Table] = config_default.type_to_color_light[SQLite3_Table]
99
+ else:
100
+ config.type_to_color[SQLite3_Table] = config_default.type_to_color_dark[SQLite3_Table]
101
+
102
+ def unextend_sqlite3():
103
+ del config.type_to_node[SQLite3_Table]
104
+ del config.type_to_color[SQLite3_Table]
@@ -11,6 +11,14 @@ import html
11
11
 
12
12
  import memory_graph.config as config
13
13
 
14
+ SENTINEL = object()
15
+
16
+ def safe_getattr(obj, attr):
17
+ try:
18
+ return getattr(obj, attr, SENTINEL)
19
+ except Exception:
20
+ return SENTINEL
21
+
14
22
  class Base_Str():
15
23
  def __init__(self, s):
16
24
  self.s = s
@@ -198,3 +206,4 @@ def generator_has_data(generator):
198
206
  return True
199
207
  except StopIteration:
200
208
  return False
209
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memory_graph
3
- Version: 0.3.89
3
+ Version: 0.3.91
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
@@ -1190,14 +1190,28 @@ mg.show(locals())
1190
1190
  ```
1191
1191
  ![avltree_fail.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/avltree_fail.png)
1192
1192
 
1193
- ## All attributes using dir() ##
1194
- Then first give it some color, show the its attributes using either of:
1193
+ ## Show attributes using build_node() ##
1194
+ Then first give it some color, show its attributes using:
1195
1195
 
1196
- - mg.node_all_attributes(data)
1197
- - mg.node_non_callable_attributes(data)
1198
- - mg.node_non_dunder_attributes(data)
1196
+ ```python
1197
+ mg.build_node(data)
1198
+ ```
1199
1199
 
1200
- and set an empty Slicer to see all attributes.
1200
+ optionally filter attributes using:
1201
+
1202
+ ```python
1203
+ mg.build_node(data,
1204
+ filters=[mg.filter_non_callable,
1205
+ mg.filter_non_dunder,
1206
+ mg.filter_non_underscore
1207
+ mg.filter_names({'left', 'right'}),
1208
+ lambda kvs : ((k,v) for k,v in kvs
1209
+ if k in {'left', 'right'} and
1210
+ not callable(v))
1211
+ ])
1212
+ ```
1213
+
1214
+ and set an empty Slicer to show all attributes even if the sequence is long.
1201
1215
 
1202
1216
  ```python
1203
1217
  import memory_graph as mg
@@ -1211,8 +1225,8 @@ tree.insert(20, "twenty")
1211
1225
  tree.insert(15, "fifteen")
1212
1226
 
1213
1227
  mg.config.type_to_color[bintrees.avltree.Node] = "sandybrown"
1214
- mg.config.type_to_node[bintrees.avltree.Node] = lambda data:
1215
- mg.node_non_dunder_attributes(data)
1228
+ mg.config.type_to_node[bintrees.avltree.Node] = lambda data: mg.build_node(data,
1229
+ filters=[mg.filter_non_dunder])
1216
1230
  mg.config.type_to_slicer[bintrees.avltree.Node] = mg.Slicer()
1217
1231
 
1218
1232
  mg.show(locals())
@@ -1542,8 +1556,8 @@ mg.show(locals())
1542
1556
  # Extensions #
1543
1557
  Different extensions are available for types from other Python packages.
1544
1558
 
1545
- ## Numpy ##
1546
- For Numpy types `array` and `matrix` and `ndarray`, use `mg.extend_numpy()`:
1559
+ ## NumPy ##
1560
+ For NumPy types `array` and `matrix` and `ndarray`, use `mg.extend_numpy()`:
1547
1561
 
1548
1562
  ```python
1549
1563
  import memory_graph as mg
@@ -1562,10 +1576,10 @@ mg.show(locals())
1562
1576
 
1563
1577
  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).
1564
1578
 
1565
- See this [introduction to numpy operations](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/numpy_operations.py&timestep=0.5&play).
1579
+ See this [introduction to NumPy operations](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/numpy_operations.py&timestep=0.5&play).
1566
1580
 
1567
1581
  ## Pandas ##
1568
- For pandas types `Series` and `DataFrame`, use `mg.extend_pandas()`:
1582
+ For Pandas types `Series` and `DataFrame`, use `mg.extend_pandas()`:
1569
1583
 
1570
1584
  ```python
1571
1585
  import memory_graph as mg
@@ -1585,6 +1599,29 @@ mg.show(locals())
1585
1599
 
1586
1600
  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).
1587
1601
 
1602
+ See this [introduction to Pandas operations](https://memory-graph.com/#micropip=numpy&codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/pandas_operations.py&timestep=0.5&play).
1603
+
1604
+ ## Polars ##
1605
+ For Polars types `DataFrame`, use `mg.extend_polars()`:
1606
+
1607
+ ```python
1608
+ import memory_graph as mg
1609
+ import polars as pl
1610
+ mg.extend_polars()
1611
+
1612
+ df = pl.DataFrame(
1613
+ {
1614
+ "name": ["Alice Archer", "Ben Brown", "Chloe Cooper", "Daniel Donovan"],
1615
+ "weight": [57.9, 72.5, 53.6, 83.1], # (kg)
1616
+ "height": [1.56, 1.77, 1.65, 1.75], # (m)
1617
+ }
1618
+ )
1619
+
1620
+ mg.show(locals())
1621
+ ```
1622
+ ![extension_polars.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_polars.png)
1623
+
1624
+
1588
1625
  ## PyTorch ##
1589
1626
  For torch type `tensor`, use `mg.extend_torch()`:
1590
1627
 
@@ -1602,6 +1639,39 @@ mg.show(locals())
1602
1639
  ```
1603
1640
  ![extension_torch.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_torch.png)
1604
1641
 
1642
+ ## SQLite3 ##
1643
+ For sqlite3 use `mg.extend_sqlite3()`:
1644
+
1645
+ ```python
1646
+ import memory_graph as mg
1647
+ import sqlite3
1648
+ mg.extend_sqlite3()
1649
+
1650
+ conn = sqlite3.connect(":memory:")
1651
+
1652
+ conn.executescript("""
1653
+ CREATE TABLE students (
1654
+ id INTEGER PRIMARY KEY,
1655
+ name TEXT NOT NULL,
1656
+ age INTEGER
1657
+ );
1658
+ """)
1659
+
1660
+ conn.executemany(
1661
+ "INSERT INTO students VALUES (?, ?, ?)",
1662
+ [
1663
+ (1, "Alice", 20),
1664
+ (2, "Bob", 21),
1665
+ (3, "Charlie", 22),
1666
+ ]
1667
+ )
1668
+
1669
+ mg.show(locals())
1670
+ conn.close()
1671
+ ```
1672
+ ![extension_sqlite3.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/extension_sqlite3.png)
1673
+
1674
+
1605
1675
  # Memory Graph Web Debugger #
1606
1676
  The <a href="https://memory-graph.com/#play" target="_blank">Memory Graph Web Debugger</a> lets us use memory_graph without any installation.
1607
1677
  ![memory_graph_web_debugger.png](https://raw.githubusercontent.com/bterwijn/memory_graph/main/images/memory_graph_web_debugger.png)
@@ -9,6 +9,8 @@ memory_graph/config_default.py
9
9
  memory_graph/config_helpers.py
10
10
  memory_graph/extension_numpy.py
11
11
  memory_graph/extension_pandas.py
12
+ memory_graph/extension_polars.py
13
+ memory_graph/extension_sqlite3.py
12
14
  memory_graph/extension_torch.py
13
15
  memory_graph/html_table.py
14
16
  memory_graph/list_view.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memory_graph"
7
- version = "0.3.89"
7
+ version = "0.3.91"
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