Skip to content

Instantly share code, notes, and snippets.

@astynax
Created September 11, 2013 07:22
Show Gist options
  • Save astynax/6520298 to your computer and use it in GitHub Desktop.
Save astynax/6520298 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# \u0421\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u044b, greenlets \u0438 \u043f\u0440\u043e\u0447"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### \u0412\u0441\u043f\u043e\u043c\u043d\u0438\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def f():\n",
" yield 'a'\n",
" yield 'b'\n",
" yield 'c'"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ff = f()\n",
"print ff.next()\n",
"print ff.next()\n",
"print ff.next()\n",
"print ff.next() # <- \u0442\u0443\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435"
],
"language": "python",
"metadata": {},
"outputs": [
{
"ename": "StopIteration",
"evalue": "",
"output_type": "pyerr",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mStopIteration\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-2-bb1aa0307e4c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mprint\u001b[0m \u001b[0mff\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mprint\u001b[0m \u001b[0mff\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[1;32mprint\u001b[0m \u001b[0mff\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# <- \u0442\u0443\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mStopIteration\u001b[0m: "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"a\n",
"b\n",
"c\n"
]
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### \u0421\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def f():\n",
" print \"Started!\"\n",
" while True:\n",
" x = (yield) # \u0441\u043a\u043e\u0431\u043a\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b!\n",
" print '>', x"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ff = f()\n",
"print ff"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"<generator object f at 0x93dac34>\n"
]
}
],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c - \u044d\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c. \u0421\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f \u0434\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e ```yield``` \u0438 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430 \u043d\u0435\u043c."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ff.next()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Started!\n"
]
}
],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f!"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ff.send(20)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"> 20\n"
]
}
],
"prompt_number": 6
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0421\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 \u0432\u043e\u0437\u0431\u0443\u0436\u0434\u0435\u0442 StopIteration \u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0437 \u0435\u0451 \u0442\u0435\u043b\u0430"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def g():\n",
" x = (yield)\n",
" y = (yield)\n",
" print x + y"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"gg = g()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"gg.next()\n",
"gg.send(10)\n",
"gg.send(20)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"ename": "StopIteration",
"evalue": "",
"output_type": "pyerr",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mStopIteration\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-9-498863336f61>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mgg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mgg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mgg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mStopIteration\u001b[0m: "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"30\n"
]
}
],
"prompt_number": 9
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432\u043e\u0437\u0431\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0441\u0442\u0435\u043a\u0430 \u0441\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## dataflow-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\n",
"\n",
"- \u0438\u0441\u0442\u043e\u043a\u0438\n",
"- \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438\n",
"- \u0441\u0442\u043e\u043a\u0438"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Dataflow** \u043d\u0430 **\u0441\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430\u0445** - *\u043f\u0440\u043e\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043d\u0438\u0435* \u0434\u0430\u043d\u043d\u044b\u0445:\n",
"\n",
" \u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a -(send)-> \u0441\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a -(send)-> ... -(send)-> \u0441\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430-\u0441\u0442\u043e\u043a\n",
"\n",
"**Dataflow** \u043d\u0430 **\u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u0430\u0445** - *\u0432\u044b\u0442\u044f\u0433\u0438\u0432\u0430\u043d\u0438\u0435* \u0434\u0430\u043d\u043d\u044b\u0445:\n",
"\n",
" \u0421\u0442\u043e\u043a <-(next)- \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a <-(next)- ... <-(next)- \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\n"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def coroutine(fn):\n",
" \"\"\"\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u044b \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435\"\"\"\n",
" def wrapper(*args, **kwargs):\n",
" obj = fn(*args, **kwargs)\n",
" obj.next()\n",
" return obj\n",
" return wrapper\n",
"\n",
"\n",
"def source(iterable, target):\n",
" \"\"\"\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \"\u0441\u043a\u0430\u0440\u043c\u043b\u0438\u0432\u0430\u044e\u0449\u0438\u0439\" \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0432 \u0441\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443-\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c\"\"\"\n",
" for i in iterable:\n",
" target.send(i)\n",
"\n",
"\n",
"@coroutine\n",
"def filter_(pred, target):\n",
" \"\"\"\u0421\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430-\u0444\u0438\u043b\u044c\u0442\u0440\"\"\"\n",
" while True:\n",
" x = (yield)\n",
" if pred(x):\n",
" target.send(x)\n",
"\n",
"@coroutine\n",
"def map_(fn, target):\n",
" \"\"\"\u0421\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 - \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u0435\u043b\u044c\"\"\"\n",
" while True:\n",
" target.send(fn((yield)))\n",
"\n",
"@coroutine\n",
"def broadcast(*targets):\n",
" \"\"\"\u0421\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 - \u0440\u0430\u0437\u0432\u0435\u0442\u0432\u0438\u0442\u0435\u043b\u044c\"\"\"\n",
" while True:\n",
" x = (yield)\n",
" for t in targets:\n",
" t.send(x)\n",
"\n",
"@coroutine\n",
"def printer(fmt=\"%s\"):\n",
" \"\"\"\u0421\u0442\u043e\u043a, \u0432\u044b\u0432\u043e\u0434\u044f\u0449\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434\"\"\"\n",
" while True:\n",
" print fmt % ((yield))\n",
"\n",
"\n",
"@coroutine\n",
"def reducer(fn, initial, target):\n",
" \"\"\"\u0421\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0449\u0430\u044f \u0441\u0432\u0435\u0440\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445\"\"\"\n",
" res = initial\n",
" while True:\n",
" try:\n",
" res = fn(res, (yield))\n",
" except GeneratorExit:\n",
" target.send(res)\n",
" raise StopIteration()\n",
"\n",
"@coroutine\n",
"def caller(fn):\n",
" \"\"\"\u0421\u0442\u043e\u043a, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e\"\"\"\n",
" while True:\n",
" fn((yield))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"l = []\n",
"print source(\n",
" [1,3,5,7],\n",
" broadcast(\n",
" caller(l.append),\n",
" filter_(\n",
" lambda x: x > 2,\n",
" map_(\n",
" lambda x: x * 10,\n",
" printer())))), l"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"30\n",
"50\n",
"70\n",
"None [1, 3, 5, 7]\n"
]
}
],
"prompt_number": 11
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u041f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0441\u043b\u043e\u0436\u043d\u043e, \u0430 \u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0449\u0451 \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0423\u043f\u0440\u043e\u0441\u0442\u0438\u043c \u0436\u0438\u0437\u043d\u044c - \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043d\u0432\u0435\u0435\u0440:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def chain(*steps):\n",
" \"\"\"\n",
" \u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0438\u0434\u0430:\n",
" [\n",
" (\u0444\u0443\u043d\u043a\u0446\u0438\u044f_\u043f\u043e\u043f\u0440\u043e\u0436\u0434\u0430\u044e\u0449\u0430\u044f_\u0441\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435, \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b, \u043a\u0440\u043e\u043c\u0435, target),\n",
" ...\n",
" \u0444\u0443\u043d\u043a\u0446\u0438\u044f_\u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0430\u044f_\u0442\u043e\u043b\u044c\u043a\u043e_target,\n",
" ...\n",
" ]\n",
" \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443, \u043f\u0440\u043e\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044e\u0449\u0443\u044e \u0434\u0430\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432\n",
" \"\"\"\n",
" steps = steps[::-1]\n",
" arg = steps[0]\n",
" if callable(arg):\n",
" arg = arg()\n",
" for s in steps[1:]:\n",
" if callable(s):\n",
" arg = s(arg)\n",
" else:\n",
" arg = s[0](*(tuple(s[1:]) + (arg,)))\n",
" return arg"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"source(\n",
" xrange(10),\n",
" chain(\n",
" (filter_, lambda x: x % 2 == 0), # \u0431\u0435\u0440\u0435\u043c \u0447\u0451\u0442\u043d\u044b\u0435\n",
" (map_, str), # \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043c \u043a \u0441\u0442\u0440\u043e\u043a\u0435\n",
" (map_, lambda x: x*3), # \u0443\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\n",
" printer() # \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u043d\u0430 \u043f\u0435\u0447\u0430\u0442\u044c\n",
" )\n",
")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"000\n",
"222\n",
"444\n",
"666\n",
"888\n"
]
}
],
"prompt_number": 13
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0415\u0448\u0451 \u043f\u0430\u0440\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 - \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u0435\u043b\u0438:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"@coroutine\n",
"def take(n, target):\n",
" \"\"\"\u041f\u0440\u043e\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442 @n \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0430 \u0432\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 - \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\"\"\"\n",
" cnt = 0\n",
" while True:\n",
" i = (yield)\n",
" if cnt < n:\n",
" target.send(i)\n",
" cnt += 1\n",
"\n",
"@coroutine\n",
"def drop(n, target):\n",
" \"\"\"\u041e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 @n \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0430 \u0432\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 - \u043f\u0440\u043e\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442\"\"\"\n",
" cnt = n\n",
" while True:\n",
" i = (yield)\n",
" if cnt == 0:\n",
" target.send(i)\n",
" else:\n",
" cnt -= 1"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 14
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"l = []\n",
"source(\n",
" xrange(100),\n",
" chain(\n",
" (drop, 51),\n",
" (take, 7),\n",
" caller(l.append)))\n",
"print l"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[51, 52, 53, 54, 55, 56, 57]\n"
]
}
],
"prompt_number": 15
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0432\u0435\u0440\u0442\u043a\u0443:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"source(\n",
" [1, 2, 3],\n",
" reducer(\n",
" lambda x, y: x + y,\n",
" 0, # \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\n",
" printer()))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"6\n"
]
}
],
"prompt_number": 16
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0421\u0432\u0435\u0440\u0442\u043a\u0430, \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0430\u044f \u043f\u0435\u0440\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"@coroutine\n",
"def reducer1(fn, target):\n",
" try:\n",
" res = (yield)\n",
" while True:\n",
" res = fn(res, (yield))\n",
" except GeneratorExit:\n",
" try:\n",
" target.send(res)\n",
" except UnboundLocalError:\n",
" pass\n",
" raise StopIteration()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 17
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"source(\n",
" [1, 2, 3],\n",
" reducer1(\n",
" lambda x, y: x + y,\n",
" printer()))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"6\n"
]
}
],
"prompt_number": 18
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u0430\u0445\u0430\u0440\u0430 - \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c **\u043a\u0430\u043d\u0430\u043b\u044b** \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Pipe(object):\n",
" def __init__(self, *args):\n",
" self._steps = args\n",
" self._chain = None\n",
"\n",
" def __rshift__(self, other):\n",
" if isinstance(other, self.__class__):\n",
" return self.__class__(*(self._steps + other._steps))\n",
" else:\n",
" return self.__class__(*(self._steps + (other,)))\n",
" \n",
" def send(self, data):\n",
" if not self._chain:\n",
" assert self._steps\n",
" self._chain = chain(*self._steps)\n",
" self._chain.send(data)\n",
" \n",
" def close(self):\n",
" assert self._chain\n",
" self._chain.close()\n",
"\n",
" def __call__(self, iterable):\n",
" assert self._steps\n",
" return source(iterable, chain(*self._steps))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 19
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"(\n",
" Pipe() >> (reducer1, lambda x, y: x + y) >> printer\n",
")(\n",
" [1,2,3]\n",
")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"6\n"
]
}
],
"prompt_number": 20
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u041f\u0440\u0438\u0447\u0435\u043c, \u043a\u0430\u043d\u0430\u043b\u044b \u043c\u043e\u0436\u043d\u043e **\u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c**:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"repr_printer = Pipe() >> (map_, repr) >> printer\n",
"none_filter = Pipe() >> (filter_, lambda x: x is not None)\n",
"\n",
"(none_filter >> repr_printer)([1,\"asd\", None, True])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1\n",
"'asd'\n",
"True\n"
]
}
],
"prompt_number": 21
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0411\u043e\u043b\u0435\u0435 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 - \u0441\u0431\u043e\u0440 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u043f\u043e \u043d\u0430\u0431\u043e\u0440\u0443 \u0447\u0438\u0441\u0435\u043b:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import operator as op\n",
"\n",
"def stat(iterable):\n",
" res = {}\n",
"\n",
" def setter(d, k):\n",
" return lambda v: d.__setitem__(k, v)\n",
" (\n",
" Pipe() >> broadcast(\n",
" Pipe() >> (reducer1, max) >> caller(setter(res, 'max')),\n",
" Pipe() >> (reducer1, min) >> caller(setter(res, 'min')),\n",
" Pipe() >> (reducer1, op.add) >> caller(setter(res, 'sum'))\n",
" )\n",
" )(\n",
" iterable\n",
" )\n",
" return res\n",
"\n",
"print stat([1,2,5,2,3,-1,56, -15])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"{'max': 56, 'sum': 53, 'min': -15}\n"
]
}
],
"prompt_number": 22
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0430\u044f \u043c\u043d\u043e\u0433\u043e\u0437\u0430\u0434\u0430\u0447\u043d\u043e\u0441\u0442\u044c"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 \u0437\u0430\u0434\u0430\u0447:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Scheduler(object):\n",
"\n",
" _tick = 0\n",
" _stop_flag = None\n",
" \n",
" def __init__(self):\n",
" self._queue = []\n",
" \n",
" @property\n",
" def tick(self):\n",
" return self._tick\n",
"\n",
" def run(self):\n",
" self._stop_flag = False\n",
" self._tick = 1\n",
" # \u0437\u0430\u043f\u0443\u0441\u043a \u0437\u0430\u0434\u0430\u0447\n",
" for t in self._queue:\n",
" t.next()\n",
" t.send(self)\n",
" # \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0438\u043a\u043b\n",
" while self._queue:\n",
" for t in self._queue[:]:\n",
" try:\n",
" t.send(self._stop_flag)\n",
" except StopIteration:\n",
" # \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0430\u0441\u044c, \u0432\u044b\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u0435\u0451 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438\n",
" self._queue.remove(t)\n",
" self._tick += 1\n",
" \n",
" def stop(self):\n",
" self._stop_flag = True\n",
" \n",
" def add(self, task):\n",
" if not self._stop_flag:\n",
" # \u0435\u0441\u043b\u0438 \u0438\u0434\u0451\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\n",
" if self._tick:\n",
" # \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f\n",
" task.next()\n",
" task.send(self)\n",
" self._queue.append(task)\n",
" return task"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 23
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u041f\u0430\u0440\u0430 \u0437\u0430\u0434\u0430\u0447"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def ticker(msg, interval=1):\n",
" sh = (yield) # \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\n",
" while True:\n",
" # \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443\n",
" if (yield):\n",
" # \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0441\u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0432\u0430\u0442\u044c \"\u0441\u0442\u043e\u043f!\"\n",
" print msg, '<- stopped!'\n",
" break\n",
" if sh.tick % interval == 0:\n",
" print msg\n",
"\n",
"def stop_at(tick):\n",
" sh = (yield)\n",
" while True:\n",
" if (yield):\n",
" break\n",
" if sh.tick >= tick:\n",
" sh.stop() # \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0432\u0430\u0442\u044c \"\u0441\u0442\u043e\u043f!\" \u0438 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\n",
"\n",
"def respawner():\n",
" sh = (yield)\n",
" if not (yield):\n",
" print \"Respawn! Tick:\", sh.tick\n",
" sh.add(respawner()) # \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0430"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 24
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c!"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"sh = Scheduler()\n",
"sh.add(stop_at(20))\n",
"sh.add(ticker(\"Every 3!\", 3))\n",
"sh.add(ticker(\"Every 5!\", 5))\n",
"sh.add(respawner())\n",
"sh.run()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Respawn! Tick: 1\n",
"Respawn! Tick: 2\n",
"Every 3!\n",
"Respawn! Tick: 3\n",
"Respawn! Tick: 4\n",
"Every 5!\n",
"Respawn! Tick: 5\n",
"Every 3!\n",
"Respawn! Tick: 6\n",
"Respawn! Tick: 7\n",
"Respawn! Tick: 8\n",
"Every 3!\n",
"Respawn! Tick: 9\n",
"Every 5!\n",
"Respawn! Tick: 10\n",
"Respawn! Tick: 11\n",
"Every 3!\n",
"Respawn! Tick: 12\n",
"Respawn! Tick: 13\n",
"Respawn! Tick: 14\n",
"Every 3!\n",
"Every 5!\n",
"Respawn! Tick: 15\n",
"Respawn! Tick: 16\n",
"Respawn! Tick: 17\n",
"Every 3!\n",
"Respawn! Tick: 18\n",
"Respawn! Tick: 19\n",
"Every 3! <- stopped!\n",
"Every 5! <- stopped!\n"
]
}
],
"prompt_number": 25
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u041c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0432 \u0432\u0438\u0434\u0435 \u043a\u043b\u0430\u0441\u0441\u043e\u0432"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Counter(object):\n",
" def __init__(self, sch):\n",
" self._sch = sch\n",
" self._cnt = 0\n",
"\n",
" def step(self):\n",
" self._cnt += 1\n",
"\n",
" def stop(self):\n",
" print 'Count:', self._cnt\n",
"\n",
"class Stopper(object):\n",
" def __init__(self, sch, stop_at):\n",
" self._sch = sch\n",
" self._stop_at = stop_at\n",
"\n",
" def step(self):\n",
" if self._sch.tick >= self._stop_at:\n",
" self._sch.stop()\n",
"\n",
" def stop(self):\n",
" pass"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 26
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0422\u0435\u043f\u0435\u0440\u044c, \u0435\u0441\u043b\u0438 \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u0431\u0451\u0440\u0442\u043a\u043e\u0439..."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def as_task(task_clz, *args, **kwargs):\n",
" sch = (yield)\n",
" obj = task_clz(sch, *args, **kwargs)\n",
" while True:\n",
" if (yield):\n",
" obj.stop()\n",
" break\n",
" if obj.step():\n",
" break"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 27
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"...\u0442\u043e Scheduler \u0441\u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043e\u0431\u0451\u0440\u043d\u0443\u0442\u044b\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043d\u0430\u0440\u044f\u0434\u0443 \u0441 \"\u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438\" \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"sch = Scheduler()\n",
"sch.add(as_task(Counter))\n",
"sch.add(as_task(Stopper, stop_at=10))\n",
"sch.add(respawner())\n",
"sch.run()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Respawn! Tick: 1\n",
"Respawn! Tick: 2\n",
"Respawn! Tick: 3\n",
"Respawn! Tick: 4\n",
"Respawn! Tick: 5\n",
"Respawn! Tick: 6\n",
"Respawn! Tick: 7\n",
"Respawn! Tick: 8\n",
"Respawn! Tick: 9\n",
"Count: 10\n"
]
}
],
"prompt_number": 28
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0417\u0430\u0434\u0430\u0447\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u043b\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0438\u0438!"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Swarm(object):\n",
" def __init__(self, sch, gen=1):\n",
" self._sch = sch\n",
" self._gen = gen\n",
" print 'I`m from gen %d!' % gen\n",
" def step(self):\n",
" self._sch.add(as_task(Swarm, self._gen + 1))\n",
" self._sch.add(as_task(Swarm, self._gen + 1))\n",
" return True # \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c \"\u0443\u043c\u0438\u0440\u0430\u0435\u0442\"\n",
" def stop(self):\n",
" pass"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 29
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"sch = Scheduler()\n",
"sch.add(as_task(Swarm))\n",
"sch.add(stop_at(5))\n",
"sch.run()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"I`m from gen 1!\n",
"I`m from gen 2!\n",
"I`m from gen 2!\n",
"I`m from gen 3!\n",
"I`m from gen 3!\n",
"I`m from gen 3!\n",
"I`m from gen 3!\n",
"I`m from gen 4!\n",
"I`m from gen 4!\n",
"I`m from gen 4!\n",
"I`m from gen 4!\n",
"I`m from gen 4!\n",
"I`m from gen 4!\n",
"I`m from gen 4!\n",
"I`m from gen 4!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n",
"I`m from gen 5!\n"
]
}
],
"prompt_number": 30
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c\n",
"## \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class AdvScheduler(object):\n",
" \n",
" _tick = 0\n",
" _stop_flag = None\n",
" \n",
" def __init__(self):\n",
" self._queue = []\n",
" \n",
" @property\n",
" def tick(self):\n",
" return self._tick\n",
"\n",
" def run(self):\n",
" self._stop_flag = False\n",
" self._tick = 1\n",
" # \u0437\u0430\u043f\u0443\u0441\u043a \u0437\u0430\u0434\u0430\u0447\n",
" for t in self._queue:\n",
" t.next()\n",
" t.send(self)\n",
" # \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0438\u043a\u043b\n",
" while self._queue:\n",
" for t in self._queue[:]:\n",
" try:\n",
" t.send(None)\n",
" except StopIteration:\n",
" self._queue.remove(t)\n",
"\n",
" if self._stop_flag:\n",
" for t in self._queue[:]:\n",
" t.close() # <<<- \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440/\u0441\u043e\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 \u0438\u043c\u0435\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438!\n",
"\n",
" self._tick += 1\n",
" \n",
" def stop(self):\n",
" self._stop_flag = True\n",
" \n",
" def add(self, task):\n",
" if not self._stop_flag:\n",
" # \u0435\u0441\u043b\u0438 \u0438\u0434\u0451\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\n",
" if self._tick:\n",
" # \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f\n",
" task.next()\n",
" task.send(self)\n",
" self._queue.append(task)\n",
" return task"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 31
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u042d\u0442\u043e\u0442 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 \u043e\u0441\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0448\u0442\u0430\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 ```close()```, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0443 \u0432\u0441\u0435\u0445 \u0441\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440 \u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432.\n",
"\u0422.\u043e. \u0442\u0430\u043c, \u0433\u0434\u0435 \u0440\u0430\u043d\u044c\u0448\u0435 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 **\u043e\u0436\u0438\u0434\u0430\u043b** \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043e\u0442 \u0437\u0430\u0434\u0430\u0447, \u0437\u0434\u0435\u0441\u044c \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0435\u0451 **\u0437\u0430\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c**!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**\u0417\u0430\u0434\u0430\u0447\u0438** \u0434\u043b\u044f **\u043d\u043e\u0432\u043e\u0433\u043e \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0430**:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def three_step(prefix):\n",
" try:\n",
" sh = (yield)\n",
" print prefix, \": start!\"\n",
" (yield)\n",
" print prefix, \": step 1\"\n",
" (yield)\n",
" print prefix, \": step 2\"\n",
" (yield)\n",
" print prefix, \": step 3\"\n",
" except GeneratorExit: # \u0442\u0443\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443\n",
" print prefix, \": stop!\"\n",
" # \u0442.\u043a. \u043c\u044b \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u043b\u0438 GeneratorExit\n",
" # \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0432\u043e\u0437\u0431\u0443\u0434\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435:\n",
" raise StopIteration()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 32
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def respawn(task, *args, **kwargs):\n",
" \"\"\"\n",
" \u0417\u0430\u0434\u0430\u0447\u0430, \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0430\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u043e\u0441\u043b\u0435 \u0435\u0451 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f\n",
" \"\"\"\n",
" try:\n",
" t = task(*args, **kwargs)\n",
" t.next()\n",
" sch = (yield)\n",
" t.send(sch)\n",
" while True:\n",
" try:\n",
" t.send((yield))\n",
" except StopIteration:\n",
" sch.add(respawn(task, *args, **kwargs))\n",
" break\n",
" except GeneratorExit:\n",
" t.close() # \u0442\u0443\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u0435\u0442 \u0441\u0430\u043c\u043e,\n",
" raise StopIteration() # \u043d\u043e \u043c\u044b \u043f\u043e\u0434\u0441\u0442\u0440\u0430\u0445\u0443\u0435\u043c\u0441\u044f :)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 33
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# \u044d\u0442\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0445\u043e\u0434\u0430 \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u043b\u043e\u0432\u0438\u0442 GeneratorExit\n",
"def stop_at(tick):\n",
" sh = (yield)\n",
" while True:\n",
" (yield)\n",
" if sh.tick >= tick:\n",
" sh.stop()\n",
" break"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 34
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c!**"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"sch = AdvScheduler()\n",
"sch.add(three_step('single'))\n",
"sch.add(respawn(three_step, 'repeating'))\n",
"sch.add(stop_at(10))\n",
"sch.run()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"single : start!\n",
"repeating : start!\n",
"single : step 1\n",
"repeating : step 1\n",
"single : step 2\n",
"repeating : step 2\n",
"single : step 3\n",
"repeating : step 3\n",
"repeating : start!\n",
"repeating : step 1\n",
"repeating : step 2\n",
"repeating : step 3\n",
"repeating : start!\n",
"repeating : step 1\n",
"repeating : step 2\n",
"repeating : step 3\n",
"repeating : start!\n",
"repeating : step 1\n",
"repeating : stop!\n"
]
}
],
"prompt_number": 35
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# greenlets, gevent, ..."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import greenlet"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 36
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"gr = greenlet.greenlet # \u043b\u0435\u043d\u0438\u0432\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 37
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def evens(data, next_g):\n",
" while data > 0:\n",
" data, next_g = next_g.switch( # \u043c\u0435\u0442\u043e\u0434 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0430 greenlet, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f\n",
" data - 1, # \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437 \u043f\u0440\u0438\u0434\u0443\u0442, \u043a\u0430\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0438,\n",
" greenlet.getcurrent() # \u0430 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0443\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043f\u043e\u0442\u043e\u043a\u043e\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\n",
" )\n",
" print \"\u0427\u0435\u0442!\"\n",
"\n",
"def odds(data, next_g):\n",
" while data > 0:\n",
" data, next_g = next_g.switch(\n",
" data - 1,\n",
" greenlet.getcurrent()\n",
" )\n",
" print \"\u041d\u0435\u0447\u0435\u0442!\"\n",
" \n",
"\n",
"g_evens = greenlet.greenlet(evens)\n",
"g_odds = greenlet.greenlet(odds)\n",
"g_evens.switch(1000001, g_odds) # \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 greenlet"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\u041d\u0435\u0447\u0435\u0442!\n"
]
}
],
"prompt_number": 38
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u041f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 **StateMachine** \u0431\u0435\u0437 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u0438 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0435\u043a\u0430!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 \u0437\u0430\u0434\u0430\u0447 \u043d\u0430 greenlets"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def scheduler(tasks, max_ticks=None):\n",
" tasks = list(tasks)\n",
"\n",
" def scheduler_task(parent_tick=None):\n",
" parent = greenlet.getcurrent().parent\n",
"\n",
" tick = 0\n",
" while tasks and (max_ticks and tick < max_ticks if max_ticks else True):\n",
" for t in tasks[:]:\n",
" # \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u0432\u0435\u0440\u0445\n",
" parent.switch()\n",
"\n",
" # \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \n",
" t.switch(tick)\n",
" if t.dead:\n",
" tasks.remove(t)\n",
"\n",
" tick += 1\n",
"\n",
" # \u0441\u0430\u043c \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 - \u0442\u043e\u0436\u0435 greenlet\n",
" sched = gr(scheduler_task)\n",
" for t in tasks:\n",
" # \u0432\u0441\u0435\u043c greenlets \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u0435\u043c\n",
" t.parent = sched\n",
" \n",
" return sched"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 39
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**\u0417\u0430\u0434\u0430\u0447\u0438**"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def task(tick):\n",
" # \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 greenlet, \u0430 \u0443\u0436\u0435 \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0433\u043e - \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 greenlet\n",
" switch = greenlet.getcurrent().parent.switch\n",
"\n",
" print \"task: step 1\"\n",
" switch()\n",
" \n",
" print \"task: step 2\"\n",
" switch()\n",
" \n",
" print \"task: step 3\"\n",
" switch()\n",
" \n",
" print \"done!\"\n",
"\n",
" \n",
"def stop_at(n):\n",
" def task(tick):\n",
" switch = greenlet.getcurrent().parent.switch\n",
"\n",
" print \"born\\t*<:D\"\n",
" while switch() < n:\n",
" print \"alive\\t:)\"\n",
" print \"dead\\tX(\"\n",
"\n",
" return task\n",
"\n",
"\n",
"def nop(tick):\n",
" switch = greenlet.getcurrent().parent.switch\n",
" while True:\n",
" try:\n",
" tick = switch()\n",
" except greenlet.GreenletExit:\n",
" print \"Nop killed at %s tick!\" % tick\n",
" break"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 40
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\u0422.\u043a. \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440, \u044d\u0442\u043e **\u0442\u043e\u0436\u0435 greenlet**, \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \"\u043f\u0438\u043d\u0430\u0442\u044c\""
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def loop(glet):\n",
" cnt = 0\n",
" glet.switch(cnt)\n",
" while glet:\n",
" glet.switch(cnt)\n",
" cnt += 1"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 41
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c!**"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"loop(\n",
" scheduler([\n",
" gr(task),\n",
" gr(stop_at(7)),\n",
" gr(nop),\n",
"\n",
" # \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\n",
" scheduler([\n",
" gr(nop)\n",
" ], max_ticks=10)\n",
"\n",
" ], max_ticks=20)\n",
")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"task: step 1\n",
"born\t*<:D\n",
"task: step 2\n",
"alive\t:)\n",
"task: step 3\n",
"alive\t:)\n",
"done!\n",
"alive\t:)\n",
"alive\t:)\n",
"alive\t:)\n",
"alive\t:)\n",
"dead\tX(\n",
"Nop killed at 9 tick!\n",
"Nop killed at 19 tick!\n"
]
}
],
"prompt_number": 42
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**\u0417\u0430\u0434\u0430\u0447\u0430**, \u043a\u0430\u043a **class**"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Task(object):\n",
"\n",
" def _step(self, tick):\n",
" pass\n",
"\n",
" def _stop(self):\n",
" pass\n",
"\n",
" @classmethod\n",
" def as_greenlet(cls, *args, **kwargs):\n",
" task = cls(*args, **kwargs)\n",
" def worker(tick):\n",
" switch = greenlet.getcurrent().parent.switch\n",
" while True:\n",
" try:\n",
" if task._step(switch()):\n",
" break\n",
" except greenlet.GreenletExit:\n",
" task._stop()\n",
" break\n",
"\n",
" return greenlet.greenlet(worker)\n",
"\n",
"\n",
"class TickCollector(Task):\n",
" def __init__(self):\n",
" self._acc = []\n",
"\n",
" def _step(self, tick):\n",
" self._acc.append(tick)\n",
"\n",
" def _stop(self):\n",
" print self._acc"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 43
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"loop(\n",
" scheduler([\n",
" gr(nop),\n",
" TickCollector.as_greenlet()\n",
" ], max_ticks=20)\n",
")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]\n",
"Nop killed at 19 tick!\n"
]
}
],
"prompt_number": 44
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment