Skip to content

Commit

Permalink
Feature/diff modified (#15)
Browse files Browse the repository at this point in the history
* WiP

* Refactor create_tree()

* Update CHANGELOG.md

* WiP

* Implement check for node modification in `tree.diff()`.

* `DictWrapper` supports comparision with `==`

* Fix DOT->PNG conversion for special chars

* Update docs
  • Loading branch information
mar10 authored Nov 7, 2024
1 parent 31523b7 commit 66793ee
Show file tree
Hide file tree
Showing 20 changed files with 727 additions and 273 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# Changelog

## 0.10.0 (unreleased)
## 0.11.0 (unreleased)
- Implement check for node modification in `tree.diff()`.
- `DictWrapper` supports comparision with `==`.

## 0.10.0 (2024-11-06)

- BREAKING:
- `kind` parameter is now mandatory for `add()` and related methods.
`kind=None` is still allowed to use the default ('child').
`kind=None` is still allowed to use the default (inherit or 'child').
- Rename `shadow_attrs` argument to `forward_attrs`.
- Enforce that the same object instance is not added multiple times to one parent.
- Rename `GenericNodeData` to `DictWrapper` and remove support for attribut access.
Expand Down
132 changes: 93 additions & 39 deletions docs/jupyter/take_the_tour.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,13 @@
"output_type": "stream",
"text": [
"Tree<'Organization'>\n",
"├── <__main__.Department object at 0x10631fef0>\n",
"│ ├── <__main__.Department object at 0x105bfb560>\n",
"│ │ ╰── <__main__.Person object at 0x10643cad0>\n",
"│ ╰── <__main__.Person object at 0x105bf9850>\n",
"├── <__main__.Department object at 0x105bf9430>\n",
"│ ╰── <__main__.Person object at 0x10643d1c0>\n",
"╰── <__main__.Person object at 0x105bfbb60>\n"
"├── <__main__.Department object at 0x105046a50>\n",
"│ ├── <__main__.Department object at 0x10d13d9d0>\n",
"│ │ ╰── <__main__.Person object at 0x10d13d1c0>\n",
"│ ╰── <__main__.Person object at 0x10d13d130>\n",
"├── <__main__.Department object at 0x10d13ccb0>\n",
"│ ╰── <__main__.Person object at 0x10d13d250>\n",
"╰── <__main__.Person object at 0x10d13cfb0>\n"
]
}
],
Expand Down Expand Up @@ -221,7 +221,7 @@
{
"data": {
"text/plain": [
"Node<'Person<Alice (25)>', data_id=274463670>"
"Node<'Person<Alice (25)>', data_id=282148091>"
]
},
"execution_count": 6,
Expand Down Expand Up @@ -267,9 +267,9 @@
{
"data": {
"text/plain": [
"[Node<'Person<Claire (45)>', data_id=275004589>,\n",
" Node<'Department<Marketing>', data_id=274463043>,\n",
" Node<'Person<Alice (25)>', data_id=274463670>]"
"[Node<'Person<Claire (45)>', data_id=282148124>,\n",
" Node<'Department<Marketing>', data_id=282148043>,\n",
" Node<'Person<Alice (25)>', data_id=282148091>]"
]
},
"execution_count": 8,
Expand Down Expand Up @@ -302,8 +302,8 @@
"output_type": "stream",
"text": [
"Tree<'Organization'>\n",
"╰── Node<'Department<Development>', data_id=1cbcccba-6a6d-4d0b-af21-87790cc0da96>\n",
" ╰── Node<'Person<Bob (35)>', data_id=b37c6bfb-b422-4711-a84c-26157729ffe5>\n"
"╰── Node<'Department<Development>', data_id=113d0d59-d0d4-4ca2-871a-41a0759e3b20>\n",
" ╰── Node<'Person<Bob (35)>', data_id=23bb0f0a-cda2-4cb0-b73e-df12929115b1>\n"
]
}
],
Expand Down Expand Up @@ -331,7 +331,7 @@
{
"data": {
"text/plain": [
"Node<'Person<Bob (35)>', data_id=b37c6bfb-b422-4711-a84c-26157729ffe5>"
"Node<'Person<Bob (35)>', data_id=23bb0f0a-cda2-4cb0-b73e-df12929115b1>"
]
},
"execution_count": 10,
Expand Down Expand Up @@ -459,9 +459,9 @@
"output_type": "stream",
"text": [
"Tree<\"Copy of Tree<'Organization'>\">\n",
"├── Node<'Department<Development>', data_id=274931695>\n",
"│ ╰── Node<'Department<Test>', data_id=274463574>\n",
"╰── Node<'Department<Marketing>', data_id=274463043>\n"
"├── Node<'Department<Development>', data_id=273696421>\n",
"│ ╰── Node<'Department<Test>', data_id=282148253>\n",
"╰── Node<'Department<Marketing>', data_id=282148043>\n"
]
}
],
Expand All @@ -487,8 +487,8 @@
"output_type": "stream",
"text": [
"Tree<\"Copy of Tree<'Organization'>\">\n",
"├── Node<'Department<Development>', data_id=274931695>\n",
"╰── Node<'Department<Marketing>', data_id=274463043>\n"
"├── Node<'Department<Development>', data_id=273696421>\n",
"╰── Node<'Department<Marketing>', data_id=282148043>\n"
]
}
],
Expand Down Expand Up @@ -567,14 +567,14 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Node<'Department<Development>', data_id=274931695>\n",
"├── Node<'Department<Test>', data_id=274463574>\n",
"│ ╰── Node<'Person<Claire (45)>', data_id=275004589>\n",
"╰── Node<'Person<Alice (25)>', data_id=274463670>\n",
"Node<'Department<Marketing>', data_id=274463043>\n",
"├── Node<'Person<Dave (55)>', data_id=275004700>\n",
"╰── Node<'Person<Bob (35)>', data_id=274463109>\n",
"Node<'Person<Alice (25)>', data_id=274463670>\n"
"Node<'Department<Development>', data_id=273696421>\n",
"├── Node<'Department<Test>', data_id=282148253>\n",
"│ ╰── Node<'Person<Claire (45)>', data_id=282148124>\n",
"╰── Node<'Person<Alice (25)>', data_id=282148091>\n",
"Node<'Department<Marketing>', data_id=282148043>\n",
"├── Node<'Person<Dave (55)>', data_id=282148133>\n",
"╰── Node<'Person<Bob (35)>', data_id=282148115>\n",
"Node<'Person<Alice (25)>', data_id=282148091>\n"
]
}
],
Expand All @@ -591,8 +591,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Node<'Person<Alice (25)>', data_id=274463670>, parent=None\n",
"Node<'Person<Alice (25)>', data_id=274463670>, parent=Node<'Department<Development>', data_id=274931695>\n"
"Node<'Person<Alice (25)>', data_id=282148091>, parent=None\n",
"Node<'Person<Alice (25)>', data_id=282148091>, parent=Node<'Department<Development>', data_id=273696421>\n"
]
}
],
Expand Down Expand Up @@ -621,7 +621,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Tree<'4400083696'>\n",
"Tree<'4514376368'>\n",
"├── 'A'\n",
"│ ├── 'a1'\n",
"│ ╰── 'a2'\n",
Expand Down Expand Up @@ -661,11 +661,11 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Tree<'4398245712'>\n",
"├── Node<'A', data_id=-5607366909164962165>\n",
"│ ╰── Node<\"DictWrapper<{'title': 'foo', 'id': 1}>\", data_id=4391236800>\n",
"╰── Node<'B', data_id=-2780248446825982667>\n",
" ╰── Node<\"DictWrapper<{'title': 'foo', 'id': 1}>\", data_id=4391236800>\n"
"Tree<'4514376704'>\n",
"├── Node<'A', data_id=60011971360030034>\n",
"│ ╰── Node<\"DictWrapper<{'title': 'foo', 'id': 1}>\", data_id=4514401856>\n",
"╰── Node<'B', data_id=-4763155670598877281>\n",
" ╰── Node<\"DictWrapper<{'title': 'foo', 'id': 1}>\", data_id=4514401856>\n"
]
}
],
Expand Down Expand Up @@ -702,7 +702,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"TypedTree<'4400083744'>\n",
"TypedTree<'4514377616'>\n",
"╰── friend → Mia\n",
" ├── brother → Noah\n",
" ╰── sister → Olivia\n"
Expand Down Expand Up @@ -739,7 +739,61 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Type Hints\n",
"\n",
"## Diff\n",
"\n",
"Given two trees, for example\n",
"\n",
"```\n",
"Tree<'T0'>\n",
"├── Node<'Department<Development>', data_id={012-345}>\n",
"│ ├── Node<'Person<Alice, 23>', data_id={123-456}>\n",
"│ ╰── Node<'Person<Bob, 32>', data_id={234-456}>\n",
"╰── Node<'Department<Marketing>', data_id={012-456}>\n",
" ├── Node<'Person<Charleen, 43>', data_id={345-456}>\n",
" ╰── Node<'Person<Dave, 54>', data_id={456-456}>\n",
"\n",
"Tree<'T1'>\n",
"├── Node<'Department<Development>', data_id={012-345}>\n",
"│ ╰── Node<'Person<Newman, 67>', data_id={567-567}>\n",
"╰── Node<'Department<Marketing>', data_id={012-456}>\n",
" ├── Node<'Person<Alicia, 23>', data_id={123-456}>\n",
" ├── Node<'Person<Charleen, 43>', data_id={345-456}>\n",
" ╰── Node<'Person<Dave, 55>', data_id={456-456}>\n",
"```\n",
"\n",
"We can generate a merged tree with additional annotations:\n",
"\n",
"```py\n",
"tree_2 = tree_0.diff(tree_1, compare=True, reduce=False)\n",
"tree_2.print(repr=diff_node_formatter)\n",
"```\n",
"\n",
"```\n",
"Tree<\"diff('T0', 'T1')\">\n",
"├── Department<Development>\n",
"│ ├── Person<Newman, 67> - [Added]\n",
"│ ├── Person<Alice, 23> - [Moved away]\n",
"│ ╰── Person<Bob, 32> - [Removed]\n",
"╰── Department<Marketing>\n",
" ├── Person<Alicia, 23> - [Moved here], [Modified]\n",
" ├── Person<Charleen, 43>\n",
" ╰── Person<Dave, 54> - [Modified]\n",
"```\n",
"\n",
"It is also possible to visualize as png, for example:\n",
"```py\n",
"tree_2.to_dotfile(\"tree_diff.png\", format=\"png\", ...)\n",
"```\n",
"\n",
"![image.png](../sphinx/test_graph_diff_2.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Type Hints\n",
"\n",
"Nutree comes fully typed (passing [pyright](https://microsoft.github.io/pyright/#/) \n",
"standard checks). This improves type-safety and auto-complete features inside \n",
Expand Down Expand Up @@ -787,13 +841,13 @@
"name": "stdout",
"output_type": "stream",
"text": [
"22bf4953-5005-44ad-897e-fcbb345f0778\n"
"b6967ba9-2345-46ec-9bd8-72e1a5cfdf8f\n"
]
},
{
"data": {
"text/plain": [
"<bound method Tree.add of Tree<'4400087008'>>"
"<bound method Tree.add of Tree<'4514378672'>>"
]
},
"execution_count": 24,
Expand Down
Loading

0 comments on commit 66793ee

Please sign in to comment.