{ "cells": [ { "cell_type": "markdown", "id": "appreciated-barrel", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Matematikai Algoritmusok és Felfedezések I.\n", "\n", "## 4. Előadás: Comprehensions, Objektum orientált programozás\n", "### 2021 március 1." ] }, { "cell_type": "markdown", "id": "understood-transcription", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## List comprehension\n", "\n", "- Flat is better than nested.\n", "- Rövidités a foor loop leggyakoribb használatára, hogy gyorsan tudjunk listákat létrehozni" ] }, { "cell_type": "code", "execution_count": 1, "id": "other-truck", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l = []\n", "for i in range(10):\n", " l.append(2*i+1)\n", "l" ] }, { "cell_type": "markdown", "id": "constant-float", "metadata": {}, "source": [ "Egy soros megfelelő:" ] }, { "cell_type": "code", "execution_count": 2, "id": "secret-spirituality", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l = [2*i+1 for i in range(10)]\n", "l" ] }, { "cell_type": "markdown", "id": "catholic-bibliography", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Az általános formula \n", "\n", "~~~\n", "[ for in ]\n", "~~~" ] }, { "cell_type": "code", "execution_count": 3, "id": "rocky-dynamics", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 4, 16, 36, 64, 100, 144, 196, 256, 324]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "even = [n*n for n in range(20) if n % 2 == 0]\n", "even" ] }, { "cell_type": "markdown", "id": "large-blame", "metadata": {}, "source": [ "Ami azzal ekvivalens, hogy" ] }, { "cell_type": "code", "execution_count": 4, "id": "pending-coast", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "even = []\n", "for n in range(20):\n", " if n % 2 == 0:\n", " even.append(n)\n", "even" ] }, { "cell_type": "markdown", "id": "orange-contributor", "metadata": {}, "source": [ "egy feltételt is megadhatunk, hogy szűrjük az elemeket:\n", "\n", "~~~\n", "[ for in if ]\n", "~~~\n", "- mivel itt szűrésre használjuk az `if` részt, nincs `else` ág\n", "\n", "- viszont a kezdeti kifejezésben használhatunk esetszétválasztást:" ] }, { "cell_type": "code", "execution_count": 5, "id": "disturbed-powder", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 0, -1, 1, -1, -1, 0]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l = [1, 0, -2, 3, -1, -5, 0]\n", "\n", "signum_l = [int(n / abs(n)) if n != 0 else 0 for n in l]\n", "signum_l" ] }, { "cell_type": "markdown", "id": "convinced-attention", "metadata": {}, "source": [ "Ez persze nem a list comprehension extrája, hanem csak annyi, hogy ez is egy értelmes kifejezés:" ] }, { "cell_type": "code", "execution_count": 6, "id": "mexican-reservation", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-1" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "n = -3.2 \n", "int(n / abs(n)) if n != 0 else 0 " ] }, { "cell_type": "markdown", "id": "sonic-colombia", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Több listán is végigfuthatunk:" ] }, { "cell_type": "code", "execution_count": 7, "id": "national-participation", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l1 = [1, 2, 3]\n", "l2 = [4, 5, 6]\n", "\n", "[(i, j) for i in l1 for j in l2]" ] }, { "cell_type": "markdown", "id": "surprising-chapel", "metadata": {}, "source": [ "Egymásba is ágyazhatjuk őket:" ] }, { "cell_type": "code", "execution_count": 8, "id": "fluid-bahrain", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[1, 4, 9], [25, 36, 49]]" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "matrix = [\n", " [1, 2, 3], \n", " [5, 6, 7]\n", "]\n", "\n", "[[e*e for e in row] for row in matrix]" ] }, { "cell_type": "markdown", "id": "strange-infrastructure", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Set és dictionary comprehension\n", "\n", "Minden analóg módon működik:" ] }, { "cell_type": "code", "execution_count": 9, "id": "competitive-spokesman", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(set, 3, {'Apple', 'Pear', 'Plum'})" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fruit_list = [\"apple\", \"plum\", \"apple\", \"pear\"]\n", "\n", "fruits = {fruit.title() for fruit in fruit_list}\n", "\n", "type(fruits), len(fruits), fruits" ] }, { "cell_type": "code", "execution_count": 11, "id": "european-easter", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(dict, 3, {'apple': 5, 'plum': 4, 'pear': 4})" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "word_list = [\"apple\", \"plum\", \"pear\"]\n", "word_length = {word: len(word) for word in word_list}\n", "type(word_length), len(word_length), word_length" ] }, { "cell_type": "markdown", "id": "fresh-shopping", "metadata": {}, "source": [ "#### Vajon mi történik?" ] }, { "cell_type": "code", "execution_count": 12, "id": "plastic-philadelphia", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 'avocado', 'p': 'pear'}" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "word_list = [\"apple\", \"plum\", \"pear\", \"avocado\"]\n", "first_letters = {word[0]: word for word in word_list}\n", "first_letters" ] }, { "cell_type": "markdown", "id": "interior-linux", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Függvények fura viselkedése" ] }, { "cell_type": "code", "execution_count": 13, "id": "permanent-appearance", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3]\n" ] } ], "source": [ "def furcsafuggveny(l):\n", " k = []\n", " l = k\n", "l = [1,2,3]\n", "furcsafuggveny(l)\n", "print(l)" ] }, { "cell_type": "code", "execution_count": 14, "id": "wireless-sunday", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3, 4, 5]\n" ] } ], "source": [ "def furcsafuggveny2(l):\n", " l.append(4)\n", " l += [5]\n", " l = l + [6]\n", " l.append(7)\n", "l = [1,2,3]\n", "furcsafuggveny2(l)\n", "print(l)\n", "#Result: [1, 2, 3, 4, 5]" ] }, { "cell_type": "code", "execution_count": 15, "id": "optical-disaster", "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n" ] } ], "source": [ "a=5\n", "def f():\n", " print(a)\n", "f()" ] }, { "cell_type": "code", "execution_count": 4, "id": "celtic-preserve", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6\n" ] } ], "source": [ "a=5\n", "def f():\n", " global a\n", " a=a+1\n", " print(a)\n", "f()" ] }, { "cell_type": "markdown", "id": "confused-edition", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Namespace (névtér)\n", " A namespace a változó nevek és az objektumok közti leképezés (pont mint egy dictionary). \n", " Pl:\n", " - beépített nevekhez (`abs()`, `sorted()`, `int` stb...) tartozik egy namespace \n", " - globális namespace: ide kerülnek a függvényeken kívül létrehozott változók\n", " - lokális namespece: minden függvény létrehoz egy saját namespacet, először abban keres \n", " \n", " Különböző namespacekben szerepelhet egyező név! " ] }, { "cell_type": "code", "execution_count": 1, "id": "internal-assist", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "11\n", "15\n" ] }, { "data": { "text/plain": [ "5" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Ez egy szándékosan zavaróan megírt kód. \n", "a=5 # a globális namespaceben 'a' az 5-re fog mutatni\n", "def foo(a): # ez már egy másik `a`, ami a foo() függvény namespaceben él\n", " print(a+1) # itt a foo()-hoz tartozó 'a'-ra hivatkozunk. \n", " def belsofugveny(a): # ez egy harmadik 'a' változó, ez már a belsofugveny()-hez tartozik\n", " print(a+5); # itt a belsofugveny()-hez tartozó 'a'-ra hivatkozunk. \n", " belsofugveny(a) # itt a foo()-hoz tartozó 'a'-ra hivatkozunk. \n", " \n", "foo(10)\n", "a # itt a globális 'a'-ra hivatkozunk. " ] }, { "cell_type": "markdown", "id": "automated-ready", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Scope\n", "Minden namespacehez tartozik egy scope. A scope a kódnak az a része, ahol a neveket automatikusan abban az adott namespaceben keresi a program." ] }, { "cell_type": "code", "execution_count": null, "id": "different-origin", "metadata": {}, "outputs": [], "source": [ "a=5 #\n", " #\n", "def foo(a): # \n", " print(a+1) # \n", " # \n", " def belsofugveny(a): # \n", " print(a+5); #\n", " #\n", " belsofugveny(a) # \n", " #\n", "foo(10) # \n", "a # " ] }, { "cell_type": "markdown", "id": "exceptional-murray", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Hogyan érjük el egy másik namespaceben lévő objektumokat?\n", " - a python kifelé keres, először a legbelső namespaceben\n", " - `nonlocal valnev` megmondja, hogy eggyel kintebbi scopeban keressen. (Pontosabban, a \"legutóbbi\" nem lokális használatot keresi)\n", " - `global valnev` megmondja, hogy a globális scopeban keressen. " ] }, { "cell_type": "code", "execution_count": 2, "id": "suspended-shopper", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "lokális értékadás után: test spam\n", "nonlocal kulcsszó után: nonlocal spam\n", "global kulcsszó után: nonlocal spam\n", "globális scopeban: global spam\n" ] } ], "source": [ "def scope_test():\n", " def do_local():\n", " spam = \"local spam\"\n", "\n", " def do_nonlocal():\n", " nonlocal spam\n", " spam = \"nonlocal spam\" \n", "\n", " def do_global():\n", " global spam\n", " spam = \"global spam\"\n", "\n", " spam = \"test spam\"\n", " do_local()\n", " print(\"lokális értékadás után:\", spam)\n", " do_nonlocal()\n", " print(\"nonlocal kulcsszó után:\", spam)\n", " do_global()\n", " print(\"global kulcsszó után:\", spam)\n", "\n", "scope_test()\n", "print(\"globális scopeban:\", spam)" ] }, { "cell_type": "markdown", "id": "artistic-literacy", "metadata": {}, "source": [ "A másik lehetőség, hogy megadjuk, hogy melyik namespaceben kell keresni. " ] }, { "cell_type": "code", "execution_count": null, "id": "intelligent-tulsa", "metadata": {}, "outputs": [], "source": [ "import math\n", "math.pi # a math modul namespaceben keresi a pi nevű változót" ] }, { "cell_type": "markdown", "id": "relative-boards", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Programozási paradigmák\n", "Sokféle van, például:\n", " - Procedurális\n", " - Funckionális\n", " - Objektumorientált \n", " " ] }, { "cell_type": "markdown", "id": "otherwise-aircraft", "metadata": {}, "source": [ "#### Példa: Főzés vs matek vs autók" ] }, { "cell_type": "markdown", "id": "infectious-envelope", "metadata": {}, "source": [ "Mikor melyiket válasszuk? " ] }, { "cell_type": "markdown", "id": "sunset-qualification", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Python\n", " - többféle stílusban is lehet használni, a fentiek mindegyikét tudja többé kevésbé\n", " - sokszor vegyesen is használjuk\n", " - erősen támogatja az objektumorientált paradigmát. Minden objektum! \n", " " ] }, { "cell_type": "code", "execution_count": 44, "id": "quality-camcorder", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[int,\n", " bool,\n", " ,\n", " ]" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# minden objektum\n", "import random\n", "def foo():\n", " pass\n", "[int,bool,foo,random] " ] }, { "cell_type": "markdown", "id": "orange-mayor", "metadata": {}, "source": [ "### Objektumorientált programozás\n", "\n", "- Osztályok: A programot objektumok köré szervezzük. Minden objektum tartalmaz adatokat és metódusokat, amik az adatokat kezelik. \n", "- Öröklődés (Inheritance): Specifikusabb objektumokat hozhatunk létre, melyek öröklik a korábbiak tulajdonságait\n", "- Egységbezárás (Encapsulation): Az összetartozó adatokat és metódusokat együtt kezeljük. \n", "- Absztrakció (Abstraction): A belső működést elrejtjük és csak a szükséges részt mutatjuk meg a felhasználónak. \n", "- Polimorfizmus (Polymorphism): A leszármazottak és példányok felülírhatják a metódusokat. Több osztályból is örököltethetünk egyszerre. " ] }, { "cell_type": "markdown", "id": "experimental-toilet", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Objektum orientáltság Pythonban\n", "https://docs.python.org/3/tutorial/classes.html\n", "### Osztály (class) definiálása\n", "\n", "- `class` kulcsszóval\n", "- példányokat tudunk létrehozni\n", "- minden példánynak van egy saját namespace \n", "- attribútumokat tudunk kapcsolni hozzájuk melyek nem befolyásolják a többi példány attribútumait\n", "\n" ] }, { "cell_type": "code", "execution_count": 46, "id": "awful-count", "metadata": {}, "outputs": [], "source": [ "class Ember:\n", " pass" ] }, { "cell_type": "code", "execution_count": 52, "id": "driving-season", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Gipsz Jakab 24\n", "Gipsz Jakabné 22\n", "Mezga Aladár 23\n" ] } ], "source": [ "a=Ember()\n", "print(type(a))\n", "a.nev=\"Gipsz Jakab\"\n", "a.kor=24\n", "b=Ember()\n", "b.nev=\"Gipsz Jakabné\"\n", "b.kor=22\n", "c=Ember()\n", "c.nev=\"Mezga Aladár\"\n", "c.kor=23\n", "l=[a,b,c]\n", "for e in l:\n", " print(e.nev,e.kor)\n" ] }, { "cell_type": "code", "execution_count": 53, "id": "alternative-virgin", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "__main__.Ember" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(a)" ] }, { "cell_type": "markdown", "id": "ignored-electric", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Init\n", "- `__init__` függvény automatikusan meghívódik amikor a példány elkészül. \n", " - olyasmi mint egy konstruktor\n", " - nem kötelező\n", "- minden metódus első paramétere maga a példány. Ezt megszokásból `self`-nek hívjuk. \n" ] }, { "cell_type": "code", "execution_count": 58, "id": "arctic-reporter", "metadata": {}, "outputs": [], "source": [ "class Ember:\n", " def __init__(self,nevasd,kor):\n", " print(\"Létrejött egy ember\")\n", " self.kor = kor\n", " self.nev = nevasd\n", " " ] }, { "cell_type": "code", "execution_count": 59, "id": "amino-cambridge", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Létrejött egy ember\n", "Létrejött egy ember\n", "Gipsz Jakab 24\n", "Gipsz Jakabné 22\n" ] } ], "source": [ "a=Ember(\"Gipsz Jakab\",24)\n", "b=Ember(\"Gipsz Jakabné\",22)\n", "\n", "l=[a,b]\n", "for e in l:\n", " print(e.nev,e.kor)\n" ] }, { "cell_type": "markdown", "id": "weird-contrary", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Metódusok\n", "\n", "- Függvények az osztály definíciójában\n", "- Automatikusan az első argumentumuk a példány lesz. " ] }, { "cell_type": "code", "execution_count": 63, "id": "congressional-corruption", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1997\n", "False\n" ] } ], "source": [ "class Ember:\n", " def __init__(self,nev,kor):\n", " self.kor = kor\n", " self.nev = nev\n", " \n", " def szuletesi_ev(self): # egy paramétert vár\n", " print(2021-self.kor)\n", " \n", " def egykoru(self,other): \n", " print(self.kor==other.kor)\n", " \n", " \n", "a=Ember(\"Gipsz Jakab\",24)\n", "a.szuletesi_ev() # de paraméter nélkül hívjuk meg, mivel az első paraméter maga 'a' lesz \n", "b=Ember(\"Gipsz Jakabné\",22)\n", "a.egykoru(b)" ] }, { "cell_type": "markdown", "id": "absolute-quantity", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Metódusok meghívása\n", "Két lehetőség van:\n", "\n", "1. `példány.metódus(param)`\n", "2. `class.metódus(példány, param)`" ] }, { "cell_type": "code", "execution_count": 65, "id": "analyzed-browse", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1997\n", "1997\n" ] } ], "source": [ "a=Ember(\"Gipsz Jakab\",24)\n", "a.szuletesi_ev() \n", "Ember.szuletesi_ev(a)" ] }, { "cell_type": "markdown", "id": "geological-interface", "metadata": {}, "source": [ "#### `__str__` metódus\n", "Egy speciális metódus, amit arra használunk hogy megadjuk, hogy a `print()` függvény hogyan írja ki az objektumot. \n", "\n" ] }, { "cell_type": "code", "execution_count": 68, "id": "beneficial-vehicle", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<__main__.Ember object at 0x0000024F3F529208>\n", "(1+4j)\n" ] } ], "source": [ "print(a)\n", "print(1+4j)" ] }, { "cell_type": "code", "execution_count": 69, "id": "fitted-surname", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Gipsz Jakab egy 24 éves budapesti lakos.\n", "Gipsz Jakabné egy 22 éves kecskeméti lakos.\n" ] } ], "source": [ "class Ember:\n", " def __init__(self,nev,kor,lakohely):\n", " self.kor = kor\n", " self.nev = nev\n", " self.lakohely = lakohely\n", " def __str__(self): \n", " return self.nev+\" egy \"+str(self.kor)+\" éves \"+ self.lakohely + \"i lakos.\"\n", " \n", "a=Ember(\"Gipsz Jakab\",24,\"budapest\")\n", "print(a)\n", "b=Ember(\"Gipsz Jakabné\",22,\"kecskemét\")\n", "print(b)" ] }, { "cell_type": "markdown", "id": "supreme-supply", "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Osztály attribútumok \n", "\n", "- Olyan attribútum, amin az ossztály összes tagja osztozik. \n" ] }, { "cell_type": "code", "execution_count": 75, "id": "technical-counter", "metadata": {}, "outputs": [], "source": [ "class Ember:\n", " letszam = 42" ] }, { "cell_type": "markdown", "id": "special-foster", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "#### A példányokon és a class objektumon keresztül is elérjük" ] }, { "cell_type": "code", "execution_count": 71, "id": "manual-driving", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "42" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = Ember()\n", "a.letszam" ] }, { "cell_type": "code", "execution_count": 72, "id": "ethical-monday", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "42" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Ember.letszam" ] }, { "cell_type": "markdown", "id": "alternative-faculty", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "#### Megváltoztatni a classon keresztül lehet" ] }, { "cell_type": "code", "execution_count": 76, "id": "weighted-purchase", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "42 42\n" ] }, { "data": { "text/plain": [ "(43, 42)" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a1 = Ember()\n", "a2 = Ember()\n", "\n", "print(a1.letszam,a2.letszam)\n", "a1.letszam = 43\n", "a1.letszam, a2.letszam" ] }, { "cell_type": "markdown", "id": "convenient-supervision", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### A példányokon keresztül viszont nem" ] }, { "cell_type": "code", "execution_count": 77, "id": "superb-poison", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(11, 42)" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a1 = Ember()\n", "a2 = Ember()\n", "\n", "a1.letszam = 11\n", "a1.letszam , a2.letszam\n" ] }, { "cell_type": "markdown", "id": "effective-columbia", "metadata": {}, "source": [ "Azért, mert ez egy új attribútumot hoz létre a példány namespacében. " ] }, { "cell_type": "code", "execution_count": 78, "id": "vital-storm", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "11" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a1.letszam" ] } ], "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.9" } }, "nbformat": 4, "nbformat_minor": 5 }