Skip to content

Instantly share code, notes, and snippets.

@mcg1969
Created September 17, 2016 18:11
Show Gist options
  • Save mcg1969/5b6ae95ff16cfe1c751285451ebc679d to your computer and use it in GitHub Desktop.
Save mcg1969/5b6ae95ff16cfe1c751285451ebc679d to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import inspect\n",
"import dask\n",
"from operator import getitem\n",
"from collections import namedtuple\n",
"from graphviz import Digraph\n",
"from dask import delayed\n",
"from dask.delayed import Delayed, to_task_dasks\n",
"from dask.dot import dot_graph, to_graphviz\n",
"from dask.async import get_sync\n",
"from dask.base import tokenize, visualize"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class SimpleDelayed(object):\n",
" def __init__(self, func, nout):\n",
" if nout == 0:\n",
" raise RuntimeError('SimpleDelayed functions must have at least one output')\n",
" self.nout = nout\n",
" self.func = func\n",
" self.dfunc = delayed(func)\n",
" if func.__doc__:\n",
" self.__doc__ = 'This is a SimpleDelayed wrapper around the following function:\\n--------\\n%s' % func.__doc__\n",
" \n",
" def __call__(self, *args, **kwargs):\n",
" delayed = kwargs.pop('delayed', None)\n",
" if (delayed or any(isinstance(arg, Delayed) for arg in args) or\n",
" kwargs and any(isinstance(arg, Delayed) for arg in kwargs.values())):\n",
" res = self.dfunc(*args, **kwargs)\n",
" if delayed is not None and not delayed:\n",
" res = res.compute()\n",
" elif kwargs:\n",
" res = self.func(*args, **kwargs)\n",
" else:\n",
" res = self.func(*args)\n",
" if self.nout == 1 or type(res) is tuple:\n",
" return res\n",
" else:\n",
" return tuple(res[k] for k in range(self.nout))\n",
" \n",
" def visualize(self):\n",
" graph = Digraph(graph_attr={'rankdir':'BT'})\n",
" fname = self.func.__name__\n",
" argspec = inspect.getargspec(self.func)\n",
" graph.node(fname, shape='circle')\n",
" args = list(argspec.args)\n",
" if argspec.varargs:\n",
" args.append('*' + argspec.varargs)\n",
" if argspec.keywords:\n",
" args.append('**' + argspec.keywords)\n",
" for k_name in args:\n",
" graph.node(k_name, shape='box')\n",
" graph.edge(k_name, fname)\n",
" for k in range(self.nout):\n",
" k_name = '%s_out[%d]' % (fname, k)\n",
" graph.node(k_name, shape='box')\n",
" graph.edge(fname, k_name)\n",
" return graph\n",
"\n",
" def __repr__(self):\n",
" return 'SimpleDelayed: name=%s, nout=%d' % (self.func.__name__, self.nout)\n",
"\n",
" def _repr_svg_(self):\n",
" return self.visualize()._repr_svg_()\n",
"\n",
"def simple_delayed(nout):\n",
" def decorator(function):\n",
" return SimpleDelayed(function, nout)\n",
" return decorator"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"@simple_delayed(2)\n",
"def f(x, y, z, *args, **kwargs):\n",
" \"\"\"Testing\"\"\"\n",
" return x + y, y + z"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: %3 Pages: 1 -->\n",
"<svg width=\"366pt\" height=\"188pt\"\n",
" viewBox=\"0.00 0.00 366.09 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
"<title>%3</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-184 362.094,-184 362.094,4 -4,4\"/>\n",
"<!-- f -->\n",
"<g id=\"node1\" class=\"node\"><title>f</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"171\" cy=\"-90\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"171\" y=\"-85.8\" font-family=\"Times,serif\" font-size=\"14.00\">f</text>\n",
"</g>\n",
"<!-- f_out[0] -->\n",
"<g id=\"node7\" class=\"node\"><title>f_out[0]</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"161.876,-180 100.124,-180 100.124,-144 161.876,-144 161.876,-180\"/>\n",
"<text text-anchor=\"middle\" x=\"131\" y=\"-157.8\" font-family=\"Times,serif\" font-size=\"14.00\">f_out[0]</text>\n",
"</g>\n",
"<!-- f&#45;&gt;f_out[0] -->\n",
"<g id=\"edge6\" class=\"edge\"><title>f&#45;&gt;f_out[0]</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M162.321,-106.189C157.515,-114.599 151.409,-125.285 145.867,-134.984\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"142.709,-133.454 140.787,-143.873 148.787,-136.927 142.709,-133.454\"/>\n",
"</g>\n",
"<!-- f_out[1] -->\n",
"<g id=\"node8\" class=\"node\"><title>f_out[1]</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"241.876,-180 180.124,-180 180.124,-144 241.876,-144 241.876,-180\"/>\n",
"<text text-anchor=\"middle\" x=\"211\" y=\"-157.8\" font-family=\"Times,serif\" font-size=\"14.00\">f_out[1]</text>\n",
"</g>\n",
"<!-- f&#45;&gt;f_out[1] -->\n",
"<g id=\"edge7\" class=\"edge\"><title>f&#45;&gt;f_out[1]</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M179.679,-106.189C184.485,-114.599 190.591,-125.285 196.133,-134.984\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"193.213,-136.927 201.213,-143.873 199.291,-133.454 193.213,-136.927\"/>\n",
"</g>\n",
"<!-- x -->\n",
"<g id=\"node2\" class=\"node\"><title>x</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"54,-36 0,-36 0,-0 54,-0 54,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">x</text>\n",
"</g>\n",
"<!-- x&#45;&gt;f -->\n",
"<g id=\"edge1\" class=\"edge\"><title>x&#45;&gt;f</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M54.0853,-32.1665C80.5259,-45.0195 120.422,-64.4133 146.091,-76.8917\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"144.652,-80.0833 155.175,-81.3075 147.712,-73.7877 144.652,-80.0833\"/>\n",
"</g>\n",
"<!-- y -->\n",
"<g id=\"node3\" class=\"node\"><title>y</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"126,-36 72,-36 72,-0 126,-0 126,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"99\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">y</text>\n",
"</g>\n",
"<!-- y&#45;&gt;f -->\n",
"<g id=\"edge2\" class=\"edge\"><title>y&#45;&gt;f</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M116.798,-36.3034C127.253,-46.468 140.487,-59.3349 151.262,-69.8099\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"148.987,-72.4804 158.597,-76.9417 153.867,-67.4614 148.987,-72.4804\"/>\n",
"</g>\n",
"<!-- z -->\n",
"<g id=\"node4\" class=\"node\"><title>z</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"198,-36 144,-36 144,-0 198,-0 198,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"171\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">z</text>\n",
"</g>\n",
"<!-- z&#45;&gt;f -->\n",
"<g id=\"edge3\" class=\"edge\"><title>z&#45;&gt;f</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M171,-36.3034C171,-44.0173 171,-53.2875 171,-61.8876\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"167.5,-61.8956 171,-71.8957 174.5,-61.8957 167.5,-61.8956\"/>\n",
"</g>\n",
"<!-- *args -->\n",
"<g id=\"node5\" class=\"node\"><title>*args</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"270,-36 216,-36 216,-0 270,-0 270,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"243\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">*args</text>\n",
"</g>\n",
"<!-- *args&#45;&gt;f -->\n",
"<g id=\"edge4\" class=\"edge\"><title>*args&#45;&gt;f</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M225.202,-36.3034C214.747,-46.468 201.513,-59.3349 190.738,-69.8099\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"188.133,-67.4614 183.403,-76.9417 193.013,-72.4804 188.133,-67.4614\"/>\n",
"</g>\n",
"<!-- **kwargs -->\n",
"<g id=\"node6\" class=\"node\"><title>**kwargs</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"358.189,-36 287.811,-36 287.811,-0 358.189,-0 358.189,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"323\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">**kwargs</text>\n",
"</g>\n",
"<!-- **kwargs&#45;&gt;f -->\n",
"<g id=\"edge5\" class=\"edge\"><title>**kwargs&#45;&gt;f</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M287.746,-35.2354C259.719,-48.1425 221.196,-65.8835 196.199,-77.3954\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"194.634,-74.2624 187.015,-81.6246 197.562,-80.6206 194.634,-74.2624\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.dot.Digraph at 0x113d32b10>"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f.visualize()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Calling a SimpleDelayed function"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Calling the function with non-delayed arguments produces an immediate result."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"(3, 5)"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a, b = f(1,2,3)\n",
"(a, b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Calling the function with a `delayed` input produces `delayed` output. However, because the number of outputs is _known_, the function can return a tuple of each separate output."
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"(Delayed('getitem-6d75232e95c9de2b282c1908c88d0e7a'),\n",
" Delayed('getitem-7de94c591141577a8a8d2392873273b4'))"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a, b = f(delayed(1), 2, 3)\n",
"(a, b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Adding `delayed=True` forces delayed computation, even with constant inputs."
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"(Delayed('getitem-41867693f5e3b7907b6689055a15a460'),\n",
" Delayed('getitem-d48445505b3c5219bde203afdccf3e1f'))"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a, b = f(1, 2, 3, delayed=True)\n",
"(a, b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Adding `delayed=False` forces immediate computation even with delayed input."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"(3, 5)"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f(delayed(1), 2, 3, delayed=False)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class PipelineFunction:\n",
" \n",
" def __init__(self, func, outputs):\n",
" self.nout = len(outputs)\n",
" self.func = func\n",
" self.__name__ = func.__name__\n",
" self.dfunc = delayed(func)\n",
" self.outputs = outputs\n",
" self.tuple = namedtuple(self.__name__ + '_out', outputs)._make\n",
" argspec = inspect.getargspec(func)\n",
" if argspec.varargs or argspec.keywords:\n",
" raise RuntimeError('PipelineFunctions cannot have *args or **kwargs')\n",
" self.inputs = argspec.args\n",
" \n",
" def __call__(self, *args, **kwargs):\n",
" delayed = kwargs.pop('delayed', None)\n",
" if delayed is False or delayed is None:\n",
" delay_comp = self.any_delayed(args)\n",
" delay_out = delay_comp and delayed is None\n",
" else:\n",
" delay_comp = delay_out = True\n",
" res = (self.dfunc if delay_comp else self.func)(*args)\n",
" if delay_comp != delay_out:\n",
" res = res.compute()\n",
" if self.nout <= 1:\n",
" return res\n",
" elif delay_out:\n",
" res = [res[k] for k in range(self.nout)]\n",
" return self.tuple(res)\n",
"\n",
" def to_dask(self, table=None):\n",
" if table is None:\n",
" table = {k: None for k in self.inputs}\n",
" if any(table.get(k) for k in self.outputs):\n",
" bad = [k for k in self.outputs if table.get(k)]\n",
" raise RuntimeError('The following output values are already written: %s' % (', '.join(bad),))\n",
" res = (self,) + tuple(self.inputs)\n",
" if len(self.outputs) == 1:\n",
" table[self.outputs[0]] = res\n",
" else:\n",
" nm = '@%s-%s' % (self.__name__,tokenize(res))\n",
" table[nm] = res\n",
" table.update({out: (getitem, nm, k) for k, out in enumerate(self.outputs)})\n",
" return table\n",
" \n",
" def visualize(self, graph=None):\n",
" if graph is None:\n",
" graph = Digraph(graph_attr={'rankdir':'BT'})\n",
" fname = self.__name__\n",
" graph.node(fname, shape='circle')\n",
" for k_name in self.inputs:\n",
" graph.node(k_name, shape='box')\n",
" graph.edge(k_name, fname)\n",
" for k_name in self.outputs:\n",
" graph.node(k_name, shape='box')\n",
" graph.edge(fname, k_name)\n",
" return graph\n",
"\n",
" def compute(self, table, delayed=None):\n",
" try:\n",
" args = [table[k] for k in self.inputs]\n",
" except KeyError:\n",
" bad = [k for k in self.inputs if table.get(k) is None]\n",
" raise RuntimeError('Missing inputs: %s' % (','.join(bad),))\n",
" res = self.__call__(*args, delayed=delayed)\n",
" if len(self.outputs) == 1:\n",
" table[self.outputs[0]] = res\n",
" elif isinstance(res, Delayed):\n",
" table.update({out: self.dextract(res, k) for k, out in enumerate(self.outputs)})\n",
" else:\n",
" table.update({out: val for out, val in zip(self.outputs, res)})\n",
" return table\n",
" \n",
" def __repr__(self):\n",
" return 'PipelineFunction: name=%s, inputs=(%s), outputs=(%s)' % (self.__name__, ','.join(self.inputs),','.join(self.outputs))\n",
" \n",
" def _repr_svg_(self):\n",
" return self.visualize()._repr_svg_()\n",
"\n",
"def pipe(*outputs):\n",
" def decorator(function):\n",
" return PipelineFunction(function, outputs)\n",
" return decorator"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [],
"source": [
"@pipe('a', 'b')\n",
"def f(x, y, z):\n",
" return x + y, y + z\n",
"@pipe('c')\n",
"def g(w):\n",
" return 2 * w"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Examining the function in IPython produces a nice graph output."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: %3 Pages: 1 -->\n",
"<svg width=\"206pt\" height=\"188pt\"\n",
" viewBox=\"0.00 0.00 206.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
"<title>%3</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-184 202,-184 202,4 -4,4\"/>\n",
"<!-- f -->\n",
"<g id=\"node1\" class=\"node\"><title>f</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-90\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"99\" y=\"-85.8\" font-family=\"Times,serif\" font-size=\"14.00\">f</text>\n",
"</g>\n",
"<!-- a -->\n",
"<g id=\"node5\" class=\"node\"><title>a</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"90,-180 36,-180 36,-144 90,-144 90,-180\"/>\n",
"<text text-anchor=\"middle\" x=\"63\" y=\"-157.8\" font-family=\"Times,serif\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- f&#45;&gt;a -->\n",
"<g id=\"edge4\" class=\"edge\"><title>f&#45;&gt;a</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M91.0104,-106.535C86.7846,-114.752 81.4796,-125.068 76.6261,-134.505\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"73.4409,-133.046 71.9799,-143.539 79.6659,-136.247 73.4409,-133.046\"/>\n",
"</g>\n",
"<!-- b -->\n",
"<g id=\"node6\" class=\"node\"><title>b</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"162,-180 108,-180 108,-144 162,-144 162,-180\"/>\n",
"<text text-anchor=\"middle\" x=\"135\" y=\"-157.8\" font-family=\"Times,serif\" font-size=\"14.00\">b</text>\n",
"</g>\n",
"<!-- f&#45;&gt;b -->\n",
"<g id=\"edge5\" class=\"edge\"><title>f&#45;&gt;b</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M106.99,-106.535C111.215,-114.752 116.52,-125.068 121.374,-134.505\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.334,-136.247 126.02,-143.539 124.559,-133.046 118.334,-136.247\"/>\n",
"</g>\n",
"<!-- x -->\n",
"<g id=\"node2\" class=\"node\"><title>x</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"54,-36 0,-36 0,-0 54,-0 54,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">x</text>\n",
"</g>\n",
"<!-- x&#45;&gt;f -->\n",
"<g id=\"edge1\" class=\"edge\"><title>x&#45;&gt;f</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M44.7978,-36.3034C55.2528,-46.468 68.4873,-59.3349 79.2616,-69.8099\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"76.9874,-72.4804 86.5972,-76.9417 81.867,-67.4614 76.9874,-72.4804\"/>\n",
"</g>\n",
"<!-- y -->\n",
"<g id=\"node3\" class=\"node\"><title>y</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"126,-36 72,-36 72,-0 126,-0 126,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"99\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">y</text>\n",
"</g>\n",
"<!-- y&#45;&gt;f -->\n",
"<g id=\"edge2\" class=\"edge\"><title>y&#45;&gt;f</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M99,-36.3034C99,-44.0173 99,-53.2875 99,-61.8876\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"95.5001,-61.8956 99,-71.8957 102.5,-61.8957 95.5001,-61.8956\"/>\n",
"</g>\n",
"<!-- z -->\n",
"<g id=\"node4\" class=\"node\"><title>z</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"198,-36 144,-36 144,-0 198,-0 198,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"171\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">z</text>\n",
"</g>\n",
"<!-- z&#45;&gt;f -->\n",
"<g id=\"edge3\" class=\"edge\"><title>z&#45;&gt;f</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M153.202,-36.3034C142.747,-46.468 129.513,-59.3349 118.738,-69.8099\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"116.133,-67.4614 111.403,-76.9417 121.013,-72.4804 116.133,-67.4614\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"PipelineFunction: name=f, inputs=(x,y,z), outputs=(a,b)"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: %3 Pages: 1 -->\n",
"<svg width=\"62pt\" height=\"188pt\"\n",
" viewBox=\"0.00 0.00 62.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
"<title>%3</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-184 58,-184 58,4 -4,4\"/>\n",
"<!-- g -->\n",
"<g id=\"node1\" class=\"node\"><title>g</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-85.8\" font-family=\"Times,serif\" font-size=\"14.00\">g</text>\n",
"</g>\n",
"<!-- c -->\n",
"<g id=\"node3\" class=\"node\"><title>c</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"54,-180 0,-180 0,-144 54,-144 54,-180\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-157.8\" font-family=\"Times,serif\" font-size=\"14.00\">c</text>\n",
"</g>\n",
"<!-- g&#45;&gt;c -->\n",
"<g id=\"edge2\" class=\"edge\"><title>g&#45;&gt;c</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M27,-108.303C27,-116.017 27,-125.288 27,-133.888\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"23.5001,-133.896 27,-143.896 30.5001,-133.896 23.5001,-133.896\"/>\n",
"</g>\n",
"<!-- w -->\n",
"<g id=\"node2\" class=\"node\"><title>w</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"54,-36 0,-36 0,-0 54,-0 54,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">w</text>\n",
"</g>\n",
"<!-- w&#45;&gt;g -->\n",
"<g id=\"edge1\" class=\"edge\"><title>w&#45;&gt;g</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M27,-36.3034C27,-44.0173 27,-53.2875 27,-61.8876\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"23.5001,-61.8956 27,-71.8957 30.5001,-61.8957 23.5001,-61.8956\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"PipelineFunction: name=g, inputs=(w), outputs=(c)"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment