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.
- {memory_graph-0.3.89 → memory_graph-0.3.91}/PKG-INFO +83 -13
- {memory_graph-0.3.89 → memory_graph-0.3.91}/README.md +82 -12
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/__init__.py +34 -10
- memory_graph-0.3.91/memory_graph/extension_polars.py +30 -0
- memory_graph-0.3.91/memory_graph/extension_sqlite3.py +104 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/utils.py +9 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph.egg-info/PKG-INFO +83 -13
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph.egg-info/SOURCES.txt +2 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/pyproject.toml +1 -1
- {memory_graph-0.3.89 → memory_graph-0.3.91}/LICENSE.txt +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/call_stack.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/config.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/config_default.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/config_helpers.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/extension_numpy.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/extension_pandas.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/extension_torch.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/html_table.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/list_view.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/memory_to_nodes.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/node_base.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/node_key_value.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/node_leaf.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/node_linear.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/node_table.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/sequence.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/slicer.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/slices.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/slices_iterator.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/slices_table_iterator.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_max_graph_depth.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_memory_graph.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_memory_to_nodes.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_sequence.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_slicer.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_slices.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph/test_slices_iterator.py +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph.egg-info/dependency_links.txt +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph.egg-info/requires.txt +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/memory_graph.egg-info/top_level.txt +0 -0
- {memory_graph-0.3.89 → memory_graph-0.3.91}/setup.cfg +0 -0
- {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.
|
|
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
|

|
|
1192
1192
|
|
|
1193
|
-
##
|
|
1194
|
-
Then first give it some color, show
|
|
1193
|
+
## Show attributes using build_node() ##
|
|
1194
|
+
Then first give it some color, show its attributes using:
|
|
1195
1195
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1196
|
+
```python
|
|
1197
|
+
mg.build_node(data)
|
|
1198
|
+
```
|
|
1199
1199
|
|
|
1200
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
1546
|
-
For
|
|
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
|
|
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×tep=0.5&play).
|
|
1566
1580
|
|
|
1567
1581
|
## Pandas ##
|
|
1568
|
-
For
|
|
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×tep=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
|
+

|
|
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
|

|
|
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
|
+

|
|
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
|

|
|
@@ -1170,14 +1170,28 @@ mg.show(locals())
|
|
|
1170
1170
|
```
|
|
1171
1171
|

|
|
1172
1172
|
|
|
1173
|
-
##
|
|
1174
|
-
Then first give it some color, show
|
|
1173
|
+
## Show attributes using build_node() ##
|
|
1174
|
+
Then first give it some color, show its attributes using:
|
|
1175
1175
|
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1176
|
+
```python
|
|
1177
|
+
mg.build_node(data)
|
|
1178
|
+
```
|
|
1179
1179
|
|
|
1180
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
1526
|
-
For
|
|
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
|
|
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×tep=0.5&play).
|
|
1546
1560
|
|
|
1547
1561
|
## Pandas ##
|
|
1548
|
-
For
|
|
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×tep=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
|
+

|
|
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
|

|
|
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
|
+

|
|
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
|

|
|
@@ -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.
|
|
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
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
return Node_Key_Value(data,
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
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.
|
|
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
|

|
|
1192
1192
|
|
|
1193
|
-
##
|
|
1194
|
-
Then first give it some color, show
|
|
1193
|
+
## Show attributes using build_node() ##
|
|
1194
|
+
Then first give it some color, show its attributes using:
|
|
1195
1195
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1196
|
+
```python
|
|
1197
|
+
mg.build_node(data)
|
|
1198
|
+
```
|
|
1199
1199
|
|
|
1200
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
1546
|
-
For
|
|
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
|
|
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×tep=0.5&play).
|
|
1566
1580
|
|
|
1567
1581
|
## Pandas ##
|
|
1568
|
-
For
|
|
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×tep=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
|
+

|
|
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
|

|
|
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
|
+

|
|
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
|

|
|
@@ -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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|