|
|
@ -1,334 +0,0 @@
|
|
|
|
{
|
|
|
|
|
|
|
|
"cells": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "raw",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"async def job(t): # async代表这个方法可以异步\n",
|
|
|
|
|
|
|
|
"await代表运行这个方法的时候可以切换到下一个程序"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": 9,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"ename": "NameError",
|
|
|
|
|
|
|
|
"evalue": "name 'sleep' is not defined",
|
|
|
|
|
|
|
|
"output_type": "error",
|
|
|
|
|
|
|
|
"traceback": [
|
|
|
|
|
|
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
|
|
|
|
|
|
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
|
|
|
|
|
|
|
|
"\u001b[0;32m<ipython-input-9-7abcb23d41ae>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;31m# type(ff),type( ff() ) # 是个协程类型\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;31m# asyncio.run(main())\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0;32mawait\u001b[0m \u001b[0mff\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# 这样才能执行\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
|
|
|
|
|
|
"\u001b[0;32m<ipython-input-9-7abcb23d41ae>\u001b[0m in \u001b[0;36mff\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32masync\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mff\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
|
|
|
|
|
|
"\u001b[0;31mNameError\u001b[0m: name 'sleep' is not defined"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"import asyncio\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"async def ff(): \n",
|
|
|
|
|
|
|
|
" sleep(2)\n",
|
|
|
|
|
|
|
|
" print(1)\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"# ff() # 不执行\n",
|
|
|
|
|
|
|
|
"# type(ff),type( ff() ) # 是个协程类型\n",
|
|
|
|
|
|
|
|
"# asyncio.run(main()) \n",
|
|
|
|
|
|
|
|
"await ff() # 这样才能执行\n",
|
|
|
|
|
|
|
|
"print(2)"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": 10,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"name": "stdout",
|
|
|
|
|
|
|
|
"output_type": "stream",
|
|
|
|
|
|
|
|
"text": [
|
|
|
|
|
|
|
|
"hi\n",
|
|
|
|
|
|
|
|
"hi\n",
|
|
|
|
|
|
|
|
"hi\n",
|
|
|
|
|
|
|
|
"result\n",
|
|
|
|
|
|
|
|
"result\n",
|
|
|
|
|
|
|
|
"result\n"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"async def foo():\n",
|
|
|
|
|
|
|
|
" print('hi')\n",
|
|
|
|
|
|
|
|
" return 'result'\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"# 多个函数执行,但是没有用的轮流切换的特点\n",
|
|
|
|
|
|
|
|
"for x in await asyncio.gather( foo(),foo(),foo() ): print(x)"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": 45,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"name": "stdout",
|
|
|
|
|
|
|
|
"output_type": "stream",
|
|
|
|
|
|
|
|
"text": [
|
|
|
|
|
|
|
|
"A\n",
|
|
|
|
|
|
|
|
"B\n",
|
|
|
|
|
|
|
|
"C\n",
|
|
|
|
|
|
|
|
"name = B,<_MainThread(MainThread, started 139785495770944)> \n",
|
|
|
|
|
|
|
|
"name = C,<_MainThread(MainThread, started 139785495770944)> \n",
|
|
|
|
|
|
|
|
"name = A,<_MainThread(MainThread, started 139785495770944)> \n"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"import threading\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"async def foo( s:str, count: int ):\n",
|
|
|
|
|
|
|
|
" print(f\"{s}\")\n",
|
|
|
|
|
|
|
|
" await asyncio.sleep(count) # 假装有一个 io操作,交出控制权\n",
|
|
|
|
|
|
|
|
" print(f\"name = {s},{threading.currentThread()} \") \n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"async def main():\n",
|
|
|
|
|
|
|
|
"# task1 = asyncio.create_task(foo(\"A\", 2))\n",
|
|
|
|
|
|
|
|
"# task2 = asyncio.create_task(foo(\"B\", 3))\n",
|
|
|
|
|
|
|
|
"# task3 = asyncio.create_task(foo(\"C\", 2))\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"# await asyncio.gather( task1,task2,task2 ) #并发运行任务 \n",
|
|
|
|
|
|
|
|
"# await task1\n",
|
|
|
|
|
|
|
|
"# await task2\n",
|
|
|
|
|
|
|
|
"# await task3\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
" await asyncio.gather( foo(\"A\", 4),foo(\"B\", 1),foo(\"C\", 2) ) #并发运行任务 \n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"# asyncio.run(main())\n",
|
|
|
|
|
|
|
|
"await main()"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": 85,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"data": {
|
|
|
|
|
|
|
|
"text/plain": [
|
|
|
|
|
|
|
|
"0.5076558589935303"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"execution_count": 85,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"output_type": "execute_result"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"# 使用一个爬虫来做验证\n",
|
|
|
|
|
|
|
|
"import aiohttp\n",
|
|
|
|
|
|
|
|
" \n",
|
|
|
|
|
|
|
|
"async def fetch(session, url):\n",
|
|
|
|
|
|
|
|
" async with session.get(url) as response:\n",
|
|
|
|
|
|
|
|
" return await response.text()\n",
|
|
|
|
|
|
|
|
" \n",
|
|
|
|
|
|
|
|
"async def main(url):\n",
|
|
|
|
|
|
|
|
" async with aiohttp.ClientSession() as session:\n",
|
|
|
|
|
|
|
|
" html = await fetch(session, url)\n",
|
|
|
|
|
|
|
|
" print(html[:5]) \n",
|
|
|
|
|
|
|
|
" \n",
|
|
|
|
|
|
|
|
"### 或者写成\n",
|
|
|
|
|
|
|
|
"async def main(url):\n",
|
|
|
|
|
|
|
|
" async with aiohttp.ClientSession() as session:\n",
|
|
|
|
|
|
|
|
" async with session.get(url, params=payload) as response:\n",
|
|
|
|
|
|
|
|
" return await response.text() \n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"# 要句句修饰? 不太熟悉,这种写法 \n",
|
|
|
|
|
|
|
|
"async def main(url):\n",
|
|
|
|
|
|
|
|
" async with aiohttp.ClientSession() as session:\n",
|
|
|
|
|
|
|
|
" async with session.get(url, params=payload) as response:\n",
|
|
|
|
|
|
|
|
"# return await response.text()\n",
|
|
|
|
|
|
|
|
" data = await response.text() # 吐数据的地方\n",
|
|
|
|
|
|
|
|
" return data\n",
|
|
|
|
|
|
|
|
" \n",
|
|
|
|
|
|
|
|
"url = \"http://httpbin.org/get\"\n",
|
|
|
|
|
|
|
|
"payload = {'key1': 'value1', 'key2': 'value2'}\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"async def ff():\n",
|
|
|
|
|
|
|
|
" a = time.time() \n",
|
|
|
|
|
|
|
|
" task = asyncio.create_task( main(url) )\n",
|
|
|
|
|
|
|
|
" data = await asyncio.gather( *[ task for x in range(10)] )\n",
|
|
|
|
|
|
|
|
" [ x[:20] for x in data ]\n",
|
|
|
|
|
|
|
|
" return time.time() - a \n",
|
|
|
|
|
|
|
|
" \n",
|
|
|
|
|
|
|
|
"await ff()"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": 82,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"data": {
|
|
|
|
|
|
|
|
"text/plain": [
|
|
|
|
|
|
|
|
"5.514704465866089"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"execution_count": 82,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"output_type": "execute_result"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"# 比较时间消耗\n",
|
|
|
|
|
|
|
|
"import requests\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"a = time.time() \n",
|
|
|
|
|
|
|
|
"[ requests.get( url, params=payload ).text[:20] for x in range(10) ]\n",
|
|
|
|
|
|
|
|
"time.time() - a"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"aiofile, aioredis ..."
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"### 应用案例"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": 11,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"name": "stdout",
|
|
|
|
|
|
|
|
"output_type": "stream",
|
|
|
|
|
|
|
|
"text": [
|
|
|
|
|
|
|
|
"小明放了一个鱼丸,现在锅里还有1个鱼丸\n",
|
|
|
|
|
|
|
|
"mony吃了一个鱼丸,现在锅里还有0个鱼丸\n",
|
|
|
|
|
|
|
|
"小明放了一个鱼丸,现在锅里还有1个鱼丸\n",
|
|
|
|
|
|
|
|
"小明放了一个鱼丸,现在锅里还有2个鱼丸\n",
|
|
|
|
|
|
|
|
"mony吃了一个鱼丸,现在锅里还有1个鱼丸\n",
|
|
|
|
|
|
|
|
"小明放了一个鱼丸,现在锅里还有2个鱼丸\n",
|
|
|
|
|
|
|
|
"小明放了一个鱼丸,现在锅里还有3个鱼丸\n",
|
|
|
|
|
|
|
|
"mony吃了一个鱼丸,现在锅里还有2个鱼丸\n",
|
|
|
|
|
|
|
|
"小明放了一个鱼丸,现在锅里还有3个鱼丸\n",
|
|
|
|
|
|
|
|
"小明放了一个鱼丸,现在锅里还有4个鱼丸\n",
|
|
|
|
|
|
|
|
"mony吃了一个鱼丸,现在锅里还有3个鱼丸\n",
|
|
|
|
|
|
|
|
"小明放了一个鱼丸,现在锅里还有4个鱼丸\n",
|
|
|
|
|
|
|
|
"小明放了一个鱼丸,现在锅里还有5个鱼丸\n",
|
|
|
|
|
|
|
|
"mony吃了一个鱼丸,现在锅里还有4个鱼丸\n",
|
|
|
|
|
|
|
|
"小明放了一个鱼丸,现在锅里还有5个鱼丸\n",
|
|
|
|
|
|
|
|
"mony吃了一个鱼丸,现在锅里还有4个鱼丸\n",
|
|
|
|
|
|
|
|
"mony吃了一个鱼丸,现在锅里还有3个鱼丸\n",
|
|
|
|
|
|
|
|
"mony吃了一个鱼丸,现在锅里还有2个鱼丸\n",
|
|
|
|
|
|
|
|
"mony吃了一个鱼丸,现在锅里还有1个鱼丸\n",
|
|
|
|
|
|
|
|
"mony吃了一个鱼丸,现在锅里还有0个鱼丸\n"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"# 生产者,消费者模式\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"arr = []\n",
|
|
|
|
|
|
|
|
"async def produce():\n",
|
|
|
|
|
|
|
|
" for i in range(10): \n",
|
|
|
|
|
|
|
|
" await asyncio.sleep(1)\n",
|
|
|
|
|
|
|
|
" arr.append(i)\n",
|
|
|
|
|
|
|
|
" print(\"小明放了一个鱼丸,现在锅里还有%s个鱼丸\"%len(arr))\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"async def consumer():\n",
|
|
|
|
|
|
|
|
" while True: \n",
|
|
|
|
|
|
|
|
" await asyncio.sleep(2)\n",
|
|
|
|
|
|
|
|
" if arr: #各一个判断条件\n",
|
|
|
|
|
|
|
|
" arr.pop()\n",
|
|
|
|
|
|
|
|
" print(\"mony吃了一个鱼丸,现在锅里还有%s个鱼丸\"%len(arr)) \n",
|
|
|
|
|
|
|
|
" else:\n",
|
|
|
|
|
|
|
|
" break\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"async def main():\n",
|
|
|
|
|
|
|
|
" # t1 = asyncio.create_task(produce()) #创建任务\n",
|
|
|
|
|
|
|
|
" # t2 = asyncio.create_task(consumer())\n",
|
|
|
|
|
|
|
|
" # await asyncio.gather(t1,t2) #并发运行任务\n",
|
|
|
|
|
|
|
|
" await asyncio.gather( produce(),consumer() ) #并发运行任务\n",
|
|
|
|
|
|
|
|
" \n",
|
|
|
|
|
|
|
|
"await main()"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
"metadata": {
|
|
|
|
|
|
|
|
"hide_input": false,
|
|
|
|
|
|
|
|
"kernelspec": {
|
|
|
|
|
|
|
|
"display_name": "Python 3",
|
|
|
|
|
|
|
|
"language": "python",
|
|
|
|
|
|
|
|
"name": "python3"
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"language_info": {
|
|
|
|
|
|
|
|
"codemirror_mode": {
|
|
|
|
|
|
|
|
"name": "ipython",
|
|
|
|
|
|
|
|
"version": 3
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"file_extension": ".py",
|
|
|
|
|
|
|
|
"mimetype": "text/x-python",
|
|
|
|
|
|
|
|
"name": "python",
|
|
|
|
|
|
|
|
"nbconvert_exporter": "python",
|
|
|
|
|
|
|
|
"pygments_lexer": "ipython3",
|
|
|
|
|
|
|
|
"version": "3.8.3"
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"toc": {
|
|
|
|
|
|
|
|
"base_numbering": 1,
|
|
|
|
|
|
|
|
"nav_menu": {},
|
|
|
|
|
|
|
|
"number_sections": true,
|
|
|
|
|
|
|
|
"sideBar": true,
|
|
|
|
|
|
|
|
"skip_h1_title": false,
|
|
|
|
|
|
|
|
"title_cell": "Table of Contents",
|
|
|
|
|
|
|
|
"title_sidebar": "Contents",
|
|
|
|
|
|
|
|
"toc_cell": false,
|
|
|
|
|
|
|
|
"toc_position": {},
|
|
|
|
|
|
|
|
"toc_section_display": true,
|
|
|
|
|
|
|
|
"toc_window_display": false
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"varInspector": {
|
|
|
|
|
|
|
|
"cols": {
|
|
|
|
|
|
|
|
"lenName": 16,
|
|
|
|
|
|
|
|
"lenType": 16,
|
|
|
|
|
|
|
|
"lenVar": 40
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"kernels_config": {
|
|
|
|
|
|
|
|
"python": {
|
|
|
|
|
|
|
|
"delete_cmd_postfix": "",
|
|
|
|
|
|
|
|
"delete_cmd_prefix": "del ",
|
|
|
|
|
|
|
|
"library": "var_list.py",
|
|
|
|
|
|
|
|
"varRefreshCmd": "print(var_dic_list())"
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"r": {
|
|
|
|
|
|
|
|
"delete_cmd_postfix": ") ",
|
|
|
|
|
|
|
|
"delete_cmd_prefix": "rm(",
|
|
|
|
|
|
|
|
"library": "var_list.r",
|
|
|
|
|
|
|
|
"varRefreshCmd": "cat(var_dic_list()) "
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"types_to_exclude": [
|
|
|
|
|
|
|
|
"module",
|
|
|
|
|
|
|
|
"function",
|
|
|
|
|
|
|
|
"builtin_function_or_method",
|
|
|
|
|
|
|
|
"instance",
|
|
|
|
|
|
|
|
"_Feature"
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
"window_display": false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"nbformat": 4,
|
|
|
|
|
|
|
|
"nbformat_minor": 4
|
|
|
|
|
|
|
|
}
|
|
|
|
|