{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Pila (*Stack*) DMA (Datu Mota Abstraktua)\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Pila (*Stack*) DMA (Datu Mota Abstraktua)\n",
"\n",
"* LIFO (*Last-In First-Out*) motako elementu sorta lineala eta dinamikoa.\n",
" * Gehitzen den azkeneko elementua, ateratzen den lehenengoa.\n",
" * Ezin dira azken elementuaren *azpitik* dagoen elementuak atzitu.\n",
"* Pilaren **oinarria**: gehitutako lehen elementua\n",
"* Pilaren **gailurra**: gehitutako azken elementua\n",
"* Erabilpenak: funtzioak, analizatzaileak, espresioen ebaluazioak..."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Oinarrrizko eragiketak:\n",
"* Hutsik dagoeneko pila berria **sortu/hasieratu**\n",
"* **push**: elementu berri bat gehitu\n",
"* **top**: gailurreko elementua kontsultatu\n",
"* **pop**: gailurreko elementua atera\n",
"* **len**: elementu kopurua\n",
"* **isEmpty**: hutsik dagoen kontsultatu\n",
" * [bool()](https://docs.python.org/3/library/stdtypes.html#truth) ere erabil dezakegu → **len**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"%%html\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"
"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Erabilpen adibide bat: elementu segida bat aztekoz aurrera jarri\n",
"\n",
"```python\n",
"def myReversed(it):\n",
" s = Stack()\n",
" for x in it :\n",
" s.push(x)\n",
" z = []\n",
" #while not s.isEmpty() :\n",
" while s :\n",
" z.append(s.pop())\n",
" return z\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Gainera...\n",
"\n",
"* Funtzio eraikitzaileari iteragarri bat emateko aukera bagenu: `Stack(it)` \n",
" * → iteragarriko elementu guztiak pilari gehitu\n",
"* `Stack` objektuak iteragarriak balira\n",
" * → zeharkatu ahala, elementu guztiak atera"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"```python\n",
"def myReversed(it):\n",
" return Stack(it)\n",
"```\n",
"\n",
"→ **Interesgarria litzateke bi propietate hauek inplementatzea**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Stack klasea inplementatzen"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* Pila bat inplementatzeko egitura egokia: **zerrenda** (**list**)\n",
" * Oinarria → list[0]\n",
" * Gailurra → list[-1] "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* `Stack.push` → `list.append`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* `Stack.pop` → `list.pop`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* `len(Stack)` → `len(list)`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* `iter(Stack)` $\\not \\Rightarrow$ `iter(list)`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"class Stack(object):\n",
"\n",
" def __init__(self,it):\n",
" pass\n",
" \n",
" def push(self,value):\n",
" pass\n",
"\n",
" def top(self):\n",
" pass\n",
" \n",
" def pop(self):\n",
" pass\n",
" \n",
" def __len__(self):\n",
" pass\n",
" \n",
" def __iter__(self):\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"class Stack(object):\n",
"\n",
" def __init__(self,it=()):\n",
" #self.z = []\n",
" # for x in it :\n",
" # self.push(x) (edo self.z.append(x))\n",
" self.z = list(it)\n",
" \n",
" def push(self,value):\n",
" pass\n",
" \n",
" def top(self):\n",
" pass\n",
" \n",
" def pop(self):\n",
" pass\n",
" \n",
" def __len__(self):\n",
" pass\n",
" \n",
" def __iter__(self):\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"class Stack(object):\n",
"\n",
" def __init__(self,it=()):\n",
" self.z = list(it)\n",
" \n",
" def push(self,value):\n",
" self.z.append(value)\n",
" \n",
" def top(self):\n",
" pass\n",
" \n",
" def pop(self):\n",
" pass\n",
" \n",
" def __len__(self):\n",
" pass\n",
" \n",
" def __iter__(self):\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"class Stack(object):\n",
"\n",
" def __init__(self,it=()):\n",
" self.z = list(it)\n",
" \n",
" def push(self,value):\n",
" self.z.append(value)\n",
" \n",
" def top(self):\n",
" return self.z[-1]\n",
" \n",
" def pop(self):\n",
" pass\n",
" \n",
" def __len__(self):\n",
" pass\n",
" \n",
" def __iter__(self):\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"class Stack(object):\n",
"\n",
" def __init__(self,it=()):\n",
" self.z = list(it)\n",
" \n",
" def push(self,value):\n",
" self.z.append(value)\n",
" \n",
" def top(self):\n",
" return self.z[-1]\n",
" \n",
" def pop(self):\n",
" return self.z.pop()\n",
" \n",
" def __len__(self):\n",
" pass\n",
" \n",
" def __iter__(self):\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"class Stack(object):\n",
"\n",
" def __init__(self,it=()):\n",
" self.z = list(it)\n",
" \n",
" def push(self,value):\n",
" self.z.append(value)\n",
" \n",
" def top(self):\n",
" return self.z[-1]\n",
" \n",
" def pop(self):\n",
" return self.z.pop()\n",
" \n",
" def __len__(self):\n",
" return len(self.z)\n",
" \n",
" def __iter__(self):\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"class Stack(object):\n",
"\n",
" def __init__(self,it=()):\n",
" self.z = list(it)\n",
" \n",
" def push(self,value):\n",
" self.z.append(value)\n",
" \n",
" def top(self):\n",
" return self.z[-1]\n",
" \n",
" def pop(self):\n",
" return self.z.pop()\n",
" \n",
" def __len__(self):\n",
" return len(self.z)\n",
" \n",
" def __iter__(self):\n",
" # hustu egin behar dugu!!!\n",
" #return iter(self.z[::-1])\n",
" # kontuz honekin..\n",
" #return iter(list(self))\n",
" x = list()\n",
" while self.z :\n",
" x.append(self.z.pop())\n",
" #while self :\n",
" # x.append(self.pop()) \n",
" return iter(x)\n",
" \n",
" def __iter__(self):\n",
" return (self.pop() for _ in range(len(self)))\n",
" \n",
" def __iter__(self):\n",
" while self :\n",
" yield self.pop()\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"s = Stack(range(10))\n",
"print(len(s))\n",
"#print(list(s))\n",
"print(*s)\n",
"print(len(s))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"s = Stack()\n",
"for i in \"aeiou\":\n",
" s.push(i)\n",
" print(f'top: {s.top()} len: {len(s)}')\n",
"print('-----')\n",
"while s :\n",
" x = s.pop()\n",
" print(f'pop: {x} len: {len(s)}')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"s = Stack()\n",
"for i in \"aeiou\":\n",
" s.push(i)\n",
" print(f'top: {s.top()} len: {len(s)}')\n",
"print('-----')\n",
"for x in s:\n",
" print(f'pop: {x} len: {len(s)}')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Eta `str` ?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* `print(Stack(\"aeiou\"))` :"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"```\n",
"---\n",
"'u'\n",
"'o'\n",
"'i'\n",
"'e'\n",
"'a'\n",
"---\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"class Stack(object):\n",
"\n",
" def __init__(self,it=()):\n",
" self.z = list(it)\n",
" \n",
" def push(self,value):\n",
" self.z.append(value)\n",
" \n",
" def top(self):\n",
" return self.z[-1]\n",
" \n",
" def pop(self):\n",
" return self.z.pop()\n",
" \n",
" def __len__(self):\n",
" return len(self.z)\n",
" \n",
" def __iter__(self):\n",
" return (self.pop() for _ in range(len(self)))\n",
" \n",
" def __str__(self):\n",
" return '\\n'.join(['---'] + [repr(x) for x in self.z[::-1]] + ['---'])\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"s = Stack(\"aeiou\")\n",
"print(s)\n",
"print(len(s))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"print(Stack([1,2,3,'kaixo',1.3]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Eta `repr` ?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* `s == eval(repr(s))` bete dadin saiatu\n",
" * `Stack([., ., ., ...])` erabili\n",
" * `==` → `__eq__()`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"class Stack(object):\n",
"\n",
" def __init__(self,it=()):\n",
" self.z = list(it)\n",
" \n",
" def push(self,value):\n",
" self.z.append(value)\n",
" \n",
" def top(self):\n",
" return self.z[-1]\n",
" \n",
" def pop(self):\n",
" return self.z.pop()\n",
" \n",
" def __len__(self):\n",
" return len(self.z)\n",
" \n",
" def __iter__(self):\n",
" return (self.pop() for _ in range(len(self)))\n",
" \n",
" def __str__(self):\n",
" return '\\n'.join(['---'] + [repr(x) for x in self.z[::-1]] + ['---'])\n",
" \n",
" def __repr__(self):\n",
" return f'Stack({repr(self.z)})'\n",
" \n",
" def __eq__(self,other):\n",
" return type(other) == Stack and self.z == other.z\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"s = Stack([1,2,3,'kaixo',1.3,(5,6),[64,24,(23,234,265)]])\n",
"print(s)\n",
"print(repr(s))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"s == eval(repr(s)) , s == Stack() , s == Stack(range(10)) , s == \"kaixo\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## InFixu - PostFixu adierazpenak "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"* **InFixu**: $\\;\\;a \\; + \\; b \\; * \\; c \\; = \\; a + (b * c)$\n",
" * Eragilea eragigaien **artean**\n",
" * Espresioak ezkerretik eskuinera ebaluatzen dira, baina...\n",
" * Eragileen lehentasuna: `* , /` → `+ , -`\n",
" * Parentesiek lehentasuna alda dezakete:\n",
" * $a + b * c \\; \\not = \\; (a + b) * c$\n",
" * Notazio matematikoan erabilia"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"* **PostFixu**: $\\;\\;a \\; b \\; c \\; * \\; + \\; \\equiv \\; a + b * c\\;\\;$ edo $\\;\\;b \\; c \\; * \\; a \\; + \\; \\equiv \\; b * c + a$\n",
" * Eragilea bi eragigaien **atzetik**\n",
" * Espresioak ezkerretik eskuinera exekutatzen dira\n",
" * Ez dago eragile lehentasunik\n",
" * → Automatikoki prozesatzeko adierazpen aproposa\n",
" * Kalkulagailu zientifiko batzuetan erabilia"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"| InFix | PostFix |\n",
"|:-----------------:|:-------------:|\n",
"| A + B | A B + |\n",
"| A + B * C | A B C * + |\n",
"| (A + B) * C | A B + C * |\n",
"| A + B * C + D | A B C * + D + |\n",
"| (A + B) * (C + D) | A B + C D + * |\n",
"| A * B + C * D | A B * C D * + |\n",
"| A + B + C + D | A B + C + D + |"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Postfixu adierazpenen ebaluazioa\n",
"\n",
"* Oso erraza **Pila** baten bidez\n",
"* Algoritmoaren sarrera: elementu sekuentzia\n",
" * Eragigaiak\n",
" * Eragileak\n",
"* Algoritmoaren irteera: emaitza"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### PostFixu Ebaluazio Algoritmoa:\n",
"\n",
"* Elementu sekuentzia zeharkatu\n",
" * eragigaia → pilara\n",
" * eragilea\n",
" * pilatik bi eragigai atera\n",
" * eragiketaren emaitza → pilara\n",
"* Pilako elementu bakarra **emaitza** da."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"**Adibidea**: $\\;\\;3 \\;\\; 4 \\; + \\; 10 \\;\\; * \\;\\; \\equiv \\;\\; (3+4) * 10$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"
"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"# sarrerako sekuentzia: 3 4 + 10 *\n",
"s = Stack()\n",
"# 3 --> pilara\n",
"s.push(3)\n",
"# 4 --> pilara\n",
"s.push(4)\n",
"# + --> bi eragileak atera eta emaitza pilara\n",
"b = s.pop()\n",
"a = s.pop()\n",
"s.push(a+b)\n",
"# 10 --> pilara\n",
"s.push(10)\n",
"# * --> bi eragileak atera eta emaitza pilara\n",
"b = s.pop()\n",
"a = s.pop()\n",
"s.push(a*b)\n",
"# EMAITZA: pilako gailurra (elementu bakarra dago)\n",
"e = s.pop()\n",
"\n",
"print(e,len(s))"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"# sarrera: hutsunez banandutako karaktere katea\n",
"def eval_postfix(txt):\n",
" s = Stack()\n",
" for x in txt.split():\n",
" if x in '+-*/' :\n",
" b = s.pop()\n",
" a = s.pop()\n",
" if x == '+' :\n",
" s.push(a+b)\n",
" elif x == '-' :\n",
" s.push(a-b)\n",
" elif x == '*' :\n",
" s.push(a*b)\n",
" else :\n",
" s.push(a/b)\n",
" else :\n",
" s.push(eval(x))\n",
" return s.pop()"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"70 70\n",
"44.0 44.0\n",
"44.0 44.0\n",
"44.0 44.0\n"
]
}
],
"source": [
"print(((3+4)*10), eval_postfix('3 4 + 10 *'))\n",
"print(((7+3)*8/2+4), eval_postfix('7 3 + 8 * 2 / 4 +'))\n",
"print((8*(7+3)/2+4), eval_postfix('8 7 3 + * 2 / 4 +'))\n",
"print((4+8*(7+3)/2), eval_postfix('4 8 7 3 + * 2 / +'))\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Parentesirik gabeko InFixuak → PostFixu\n",
"\n",
"* Oso erraza **Pila** baten bidez\n",
"* Algoritmoaren sarrera: elementu sekuentzia (eragileak + eragigaiak)\n",
"* Algoritmoaren irteera: elementu sekuentzia (eragileak + eragigaiak)\n",
" * Espresio InFixuan eragigaien ordena berdina izango da"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### InFixuak → PostFixu (parentesirik gabe) Algoritmoa:\n",
"\n",
"* Elementu sekuentzia zeharkatu\n",
" * eragigaia → irteera sekuentzira\n",
" * eragilea\n",
" * gailurreko lehentasun berdineko edo handiagoko eragileak → irteera sekuentzira\n",
" * → eragilea pilara\n",
"* Pilako elementu guztiak → irteera sekuentzira"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"**Adibidez:** `1 * 2 + 3 * 4` → `1 2 * 3 4 * +`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"# Sarrerako sekuentzia: 1 * 2 + 3 * 4\n",
"s = Stack()\n",
"z = []\n",
"# 1 --> irteerara\n",
"z.append(1)\n",
"# * --> pilako lehentasun handiko eragileak irteerara eta eragile hau pilara\n",
"print(len(s) == 0)\n",
"s.push('*')\n",
"# 2 --> irteerara\n",
"z.append(2)\n",
"# + --> pilako lehentasun handiko eragileak irteerara eta eragile hau pilara\n",
"print(s.top() == '*')\n",
"z.append(s.pop())\n",
"print(len(s) == 0)\n",
"s.push('+')\n",
"# 3 --> irteerara\n",
"z.append(3)\n",
"# * --> pilako lehentasun handiko eragileak irteerara eta eragile hau pilara\n",
"print(s.top() == '+')\n",
"s.push('*')\n",
"# 4 --> irteerara\n",
"z.append(4)\n",
"# pila hustu\n",
"z.extend(s)\n",
"\n",
"print(z,len(s))"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"# sarrera: hutsunez banandutako karaktere katea\n",
"# irteera: hutsunez banandutako karaktere katea\n",
"def infix2postfix(txt):\n",
" s = Stack()\n",
" z = []\n",
" priority = {'*':2 , '/':2 , '+':1 , '-':1}\n",
" for x in txt.split():\n",
" if x in '+-*/' :\n",
" px = priority[x]\n",
" while s and priority[s.top()] >= px :\n",
" z.append(s.pop())\n",
" s.push(x)\n",
" else :\n",
" z.append(x)\n",
" z.extend(s)\n",
" return ' '.join(z)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"scrolled": true,
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"A + B --> A B +\n",
"A + B * C --> A B C * +\n",
"A + B * C + D --> A B C * + D +\n",
"A * B + C * D --> A B * C D * +\n",
"A + B + C + D --> A B + C + D +\n",
"A / B * C / D --> A B / C * D /\n",
"A / B * C + D * E - F / G --> A B / C * D E * + F G / -\n"
]
}
],
"source": [
"frogak='''\n",
"A + B\n",
"A + B * C\n",
"A + B * C + D\n",
"A * B + C * D\n",
"A + B + C + D\n",
"A / B * C / D\n",
"A / B * C + D * E - F / G\n",
"'''\n",
"for x in frogak.strip().split('\\n') :\n",
" print(f'{x} --> {infix2postfix(x)}')"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"17052.1\n",
"34.1 254 67 * +\n",
"17052.1\n"
]
}
],
"source": [
"x = \"34.1 + 254 * 67\"\n",
"print(eval(x))\n",
"print(infix2postfix(x))\n",
"print(eval_postfix(infix2postfix(x)))"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"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.7.6"
},
"rise": {
"autolaunch": false,
"footer": "