Skip to content

Instantly share code, notes, and snippets.

@knowsuchagency
Created May 24, 2017 04:32
Show Gist options
  • Select an option

  • Save knowsuchagency/035f6997a5f509685aec2ffc68ab910c to your computer and use it in GitHub Desktop.

Select an option

Save knowsuchagency/035f6997a5f509685aec2ffc68ab910c to your computer and use it in GitHub Desktop.
zodb experimentation.ipynb
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"metadata": {
"ExecuteTime": {
"end_time": "2017-05-11T06:27:22.187668Z",
"start_time": "2017-05-11T06:27:22.163738Z"
},
"collapsed": true,
"trusted": true
},
"cell_type": "code",
"source": "from anytree import NodeMixin, RenderTree, Resolver\nfrom anytree.dotexport import RenderTreeGraph\nfrom IPython.display import display, Image\nfrom tempfile import NamedTemporaryFile\nfrom contextlib import contextmanager\nfrom functools import partial\nfrom textwrap import dedent\nimport itertools\nimport BTrees as btrees\nimport persistent\nimport ZODB as zodb\nimport anytree\n\n# instantiate database\ndb = zodb.DB(None)\n\ndef render_node(node):\n with NamedTemporaryFile(suffix='.png') as fp:\n file = RenderTreeGraph(node).to_picture(fp.name)\n display(Image(fp.name))",
"execution_count": 33,
"outputs": []
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2017-05-11T06:27:22.200191Z",
"start_time": "2017-05-11T06:27:22.190453Z"
},
"collapsed": true,
"trusted": true
},
"cell_type": "code",
"source": "class Unit(persistent.Persistent, NodeMixin):\n def __init__(self, name, parent=None):\n self.name = name\n self.parent = parent\n def __repr__(self):\n return self.name\n ",
"execution_count": 34,
"outputs": []
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2017-05-11T06:27:22.214007Z",
"start_time": "2017-05-11T06:27:22.202335Z"
},
"collapsed": true,
"trusted": true
},
"cell_type": "code",
"source": "a = Unit('a')\nb = Unit('b', parent=a)\nc = Unit('c', parent=a)\nd = Unit('d', parent=c)\ne = Unit('e', parent=c)\nf = Unit('f', parent=d)\ng = Unit('g', parent=f)",
"execution_count": 35,
"outputs": []
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2017-05-11T06:27:22.224039Z",
"start_time": "2017-05-11T06:27:22.216457Z"
},
"collapsed": true,
"trusted": true
},
"cell_type": "code",
"source": "with db.transaction() as conn:\n conn.root.military = btrees.OOBTree.OOBTree()\n conn.root.military['bj'] = a",
"execution_count": 36,
"outputs": []
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2017-05-11T06:27:22.239286Z",
"start_time": "2017-05-11T06:27:22.226460Z"
},
"trusted": true
},
"cell_type": "code",
"source": "with db.transaction() as conn:\n top = conn.root.military['bj']\n print(RenderTree(top))\n z = Unit('z')\n z.parent = top",
"execution_count": 37,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": "a\n├── b\n└── c\n ├── d\n │ └── f\n │ └── g\n └── e\n"
}
]
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2017-05-11T07:38:08.121510Z",
"start_time": "2017-05-11T07:38:08.002615Z"
},
"trusted": true
},
"cell_type": "code",
"source": "with db.transaction() as conn:\n top = conn.root.military['bj']\n render_node(top)\n \n r = Resolver('name')\n \n *_, d = r.glob(top, '*/d')\n \n print('for node d:')\n print(dedent(f\"\"\"\n parent = {d.parent}\n children = {d.children}\n ancestors = {d.anchestors}\n descendants = {d.descendants}\n depth = {d.depth}\n height {d.height}\n \"\"\").strip())\n render_node(d)",
"execution_count": 42,
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": "<IPython.core.display.Image object>"
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": "for node d:\nparent = c\nchildren = (f,)\nancestors = (a, c)\ndescendants = (f, g)\ndepth = 2\nheight 2\n"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAFMAAAD7CAYAAAAW/aiDAAAAAXNSR0IArs4c6QAAEK9JREFUeAHt\nnXmMFEUUxh8ocomAt4iKN+IRBYMEBdFEJIoSD4w3onhGJUS8grfxhBgjUfEPRUUFWU9EQRQEgy6K\nMSpq4om3ggceKB7o830Ve9xs9XT3VNdM9ey+SmZ7trqu/k11dXXVq/raMPNMUueDQOO6kspIHylp\nGkRtFYI/AgrTH0utmR5ZEtrMYO67776jt99+23w+/vhj+uqrr8zn66+/ptWrV9OaNWvo999/p7/+\n+os6dOhgPh07dqRu3bpRjx49zGfLLbek3r1702677Ua77LKLCRPqgtrI05xrlTnALVq0yHwWL15M\ngAa34YYb0o477kgAA0hbbLEFdenSpQSvXbt2BirAAvAPP/xQAv/FF1/Q+++/T3/88Qets846Bujg\nwYNp//33N5/NNtusVpfXUFWY//zzD7300kv02GOPmc9nn31GXbt2pf32248GDRpEffv2NTUK8PK4\nv//+mz744ANTw1955RV68cUX6fXXXyf4DxgwgI488kg66qijaNttt82TTVrcBkLN9O2++eYbvu66\n63ibbbZBrec+ffrwhAkTeOnSpSwX6Du72PR++eUXnjVrFp9yyiksNd+UY8iQITxjxgz+888/Y+Pk\n9JzpFabUDh41ahTLbWkuYNy4cfzOO+/kLGP+6NLm8jPPPMMjRoxgaQpYbn2+6aabWNrl/In/n4If\nmHL7Gogo6E477cRTp05ladv+z6ZA36SN5YsvvpjXX3993mSTTXjSpEks7a2PEuaDiV/85ptv5s6d\nO/P222/PDzzwAK9du9ZHwaqehvQk+NJLL2XpHbD0BnjBggV583SH+e677/Iee+xhCnPNNdewPGnz\nFiZI/OXLl/Phhx9u2tQxY8bwr7/+6loON5j33HMPd+rUiffZZx/+6KOPXDMvVLxHH33UtPN4WC5b\ntsylbJXBlK4O46HSpk0bvuSSSxi3eUtyaPul22ba02effbbSS8sOE92J4447jtdbbz1+6KGHKs2o\nbsLjOk866STTI5k2bVol5c4GEzXy+OOPN7+Yh4a6kgIGC3vRRRdx27ZtuaGhIWsZssHErY0a+dxz\nz2VNuEWEO/fcc7l9+/b8wgsvZLmedJjTp083TzocW5vDHXn00Ueb/qiMI6RdfjLMTz75hOVdms85\n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\nAElFTkSuQmCC\n",
"text/plain": "<IPython.core.display.Image object>"
},
"metadata": {},
"output_type": "display_data"
}
]
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2017-05-11T17:14:22.820444Z",
"start_time": "2017-05-11T17:14:22.718714Z"
},
"trusted": true
},
"cell_type": "code",
"source": "from itertools import chain\nclass Foo:\n \n created = set()\n \n def __new__(cls, *args, **kwargs):\n arguments = (args, tuple(sorted(kwargs.items())))\n print(f'{cls.__name__} new method called with {arguments}')\n if arguments in cls.created:\n raise ValueError(f'{cls.__name__} already created with arguments: {arguments}')\n cls.created.add(arguments)\n return super().__new__(cls)\n \n def __init__(self, *, name=None, parent=None):\n self.name = name\n self.parent = parent\n \n def __repr__(self):\n return f\"name: {self.name}, parent: {self.parent}\"\n \n @classmethod\n def from_dict(cls, dictionary):\n return cls(**dictionary)\n \n#foo = Foo('hello', 'world')\nbar = Foo(parent='world', name='hello')\nbar\n\nfoobar = Foo.from_dict({'name': 'foo', 'parent': 'bar'})\nfoobar",
"execution_count": 80,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": "Foo new method called with ((), (('name', 'hello'), ('parent', 'world')))\n"
},
{
"data": {
"text/plain": "name: hello, parent: world"
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
},
{
"name": "stdout",
"output_type": "stream",
"text": "Foo new method called with ((), (('name', 'foo'), ('parent', 'bar')))\n"
},
{
"data": {
"text/plain": "name: foo, parent: bar"
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {
"collapsed": true,
"trusted": true
},
"cell_type": "code",
"source": "",
"execution_count": null,
"outputs": []
}
],
"metadata": {
"hide_input": false,
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"language_info": {
"name": "python",
"version": "3.6.1",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
},
"gist": {
"id": "",
"data": {
"description": "zodb experimentation.ipynb",
"public": true
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment