{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Matematikai Algoritmusok és Felfedezések I.\n", "\n", "## 6. Előadás: String formatálás, Kivéltelkezelés, Iteráció, Fájlkezelés\n", "### 2021 március 15." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# String formatálás\n", "Több módszer van arra, hogy kényelmesebben generáljunk szöveges kimenetet. Az egyik a `format()` függvény. Ez egy stringből egy másik stringet készít úgy, hogy hogy a megadott paramétereket behelyettesíti a kapcsos zárójelek közé. A függvényekhez hasonlóan több féle paraméter átadás működik:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Kedves Ádám, az ön egyenlege 230.2346.\n", "Kedves 230.2346, az ön egyenlege Ádám.\n", "Kedves Ádám, az ön egyenlege 230.2346.\n", "Kedves Ádám, az ön egyenlege 230.2346.\n" ] } ], "source": [ "# default argumentumok\n", "print(\"Kedves {}, az ön egyenlege {}.\".format(\"Ádám\", 230.2346))\n", "\n", "# pozíció szerintei argumentumok \n", "print(\"Kedves {1}, az ön egyenlege {0}.\".format(\"Ádám\", 230.2346))\n", "\n", "# kucsszavas argumentumok\n", "print(\"Kedves {nev}, az ön egyenlege {egyen}.\".format(nev=\"Ádám\", egyen=230.2346))\n", "\n", "# vegyes\n", "print(\"Kedves {0}, az ön egyenlege {egyen}.\".format(\"Ádám\",egyen= 230.2346))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ha az adatok egy dicitionaryben vannak, azt is használhatjuk. " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ádam életkora: 23\n" ] } ], "source": [ "person = {'eletkor': 23, 'nev': 'Ádam'}\n", "\n", "print(\"{p[nev]} életkora: {p[eletkor]}\".format(p=person))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### string interpolation\n", "Egy másik lehetőség az f-stringek használata. (részletek: [PEP498](https://www.python.org/dev/peps/pep-0498/))\n", "- Hasonló az előzőhöz, de bármilyen változót használhatunk\n", "- Figyeld meg a `f` betűt a string előtt!" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Paprika Jancsinak 12 almája és 1 kutyája van.\n" ] } ], "source": [ "szam1 = 12\n", "szam2 = 1\n", "nev=\"Paprika Jancsi\"\n", "print(f\"{nev}nak {szam1} almája és {szam2} kutyája van.\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Kivételkezelés\n", "\n", "- Cél, hogy a hibákat kezeljük. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Feladvány\n", "Mi fog történni ha lefuttatjuk az alábbi kódot?" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "import random" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.16666666666666666\n", "0.125\n", "0.5\n", "0.25\n", "0.14285714285714285\n" ] }, { "ename": "ZeroDivisionError", "evalue": "division by zero", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0mrandom\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrandrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero" ] } ], "source": [ "for i in range(20):\n", " print(1/random.randrange(10))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Néhány tipikus hiba:\n", "\n", "| Hiba neve | Tipikusan miért történt |\n", "| --- | --- |\n", "| IndexError: string index out of range | Egy stringnél túlindexeltél |\n", "| KeyError: 'some_text_here' | Egy dictionaryben olyan kulcsot használtál, ami nincs benne |\n", "| ModuleNotFoundError: No module named 'some_text_here' | Egy olyan modult próbáltál importálni, ami nem található |\n", "| NameError: name 'some_text_here' is not defined | Olyan változó nevet próbáltál kiértékelni, ami még nem mutat objektumra | \n", "| SyntaxError: can't assign to literal | Egy stringet próbáltál meg változó névként használni. Pl `'a'=3` |\n", "| SyntaxError: EOL while scanning string literal | Valamelyik stringet rosszul adtad meg. |\n", "| IndentationError: expected an indented block | Elrontottad az indentálást. |\n", "| SyntaxError: invalid syntax | Szintaktikai hiba. Gyakran azért van, mert lemarad a `:` valahonnan. |\n", "| TypeError: can only concatenate str (not \"int\") to str | Stringként kezeltél valamit, ami nem string. Pl egy számot. | \n", "| TypeError: 'str' object is not callable | Függvényként kezeltél egy stringet. Pl: `\"asd\"(5)` |\n", "| ValueError: invalid literal for int() with base 10: 'some_text_here' | Számmá próbáltál konvertálni egy szöveget, ami nem számokból áll. | \n", "| ZeroDivisionError: division by zero | Nullával osztottál |\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Futásidejű hibák\n", "A futásidejű hibákat tudjuk futásidőben kezelni. Erre valók a `try` és ` except` parancsok. Megadhatjuk, hogy hiba esetén mit tegyen a program, így nem fog rögtön elszállni. A `try` és az `except` közti részben figyel a program és ha olyan hibába ütközik, ami az `except` után áll, akkor végrehajtja a megadott parancsokat. " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.2\n", "0.5\n", "0.25\n", "0.125\n", "0.1111111111111111\n", "0.3333333333333333\n", "0.2\n", "0.3333333333333333\n", "nullával osztottál\n", "0.25\n" ] } ], "source": [ "for i in range(10):\n", " try:\n", " print(1/random.randrange(10))\n", " \n", " except ZeroDivisionError as e:\n", " print(\"nullával osztottál\")" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "invalid literal for int() with base 10: 'abc'\n" ] } ], "source": [ "try:\n", " int(\"abc\")\n", "except ValueError as e:\n", " print(type(e))\n", " print(e)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- több ágat is megadhatunk\n", "- a legspecifikusabbtól megyünk a legkevésbé specifikus felé\n", "- mi is megadhatunk hibákat" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-1\n", "Egy másik típusú kivétel: \n", "Az életkor nem lehet negatív\n" ] } ], "source": [ "try:\n", " eletkor = int(input())\n", " if eletkor < 0:\n", " raise Exception(\"Az életkor nem lehet negatív\")\n", "except ValueError as e:\n", " print(\"ValueError\")\n", "except Exception as e:\n", " print(\"Egy másik típusú kivétel: {}\".format(type(e)))\n", " print(e)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Többféle hibát tudunk együtt is kezelni " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Együtt:\n", " " ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "asd\n", "ValueErrorba futottunk\n" ] } ], "source": [ "def age_printer(age):\n", " next_age = age + 1\n", " print(\"Következő éveben a korod: \" + next_age)\n", " \n", "try:\n", " your_age = input()\n", " your_age = int(your_age)\n", " age_printer(your_age)\n", "except (ValueError, TypeError) as e:\n", " print(\"{}ba futottunk\".format(type(e).__name__))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### except típus nélkül\n", "\n", "- ha nem adjuk meg a hiba típusát, akkor minden hibát elkapunk, de elveszítjük az információkat a hiábról\n", "- utolsónak kell megadni az üres except utasítást. " ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "asd\n", "ValueError elkapva\n" ] } ], "source": [ "try:\n", " age = int(input())\n", " if age < 0:\n", " raise Exception(\"Az életkor nem lehet negatív\")\n", "except ValueError:\n", " print(\"ValueError elkapva\")\n", "except:\n", " print(\"Valamilyen más hibát kaptunk el\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### finally és else\n", "\n", "- A `finally` kód rész mindenképpen lefut, ha volt hiba, ha nem. \n", "- Az `else` utáni rész csak akkor fut le ha nem volt hiba" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n", "Nem volt hiba\n", "Ez mindig lefut\n" ] } ], "source": [ "try:\n", " age = int(input())\n", "except ValueError as e:\n", " print(\"Exception\", e)\n", "else:\n", " print(\"Nem volt hiba\")\n", "finally:\n", " print(\"Ez mindig lefut\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Hibakezelés kibővitése\n", "- Magunk is megadhatjuk, hogy mikor dobjon hibát a program.\n", "- Saját hiba osztályt is definiálhatunk." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `raise` kulcsszó\n", "\n", "- `raise` az utána megadott hibát dobja a program. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " eletkor = int(input())\n", " if eletkor < 0:\n", " raise Exception(\"Az életkor nem lehet negatív\")\n", "except ValueError as e:\n", " print(\"ValueError\")\n", "except Exception as e:\n", " print(\"Egy másik típusú kivétel: \"+ str(type(e)))\n", " print(e)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Hibák definiálása\n", "\n", "- Bármilyen típus, ami a az `Exception` (pontosabban a `BaseException`) osztály leszármazotja, használható hiba objektumként. \n", "- Az ős osztály elkapja a leszármazottait is. " ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "asd\n", "Valamilyen más hibát kaptunk el. Típus: , üzenet: invalid literal for int() with base 10: 'asd'\n" ] } ], "source": [ "class NegativeAgeError(Exception):\n", " def __init__(self, uzenet, adat):\n", " self.uzenet = uzenet\n", " self.adat = adat\n", " \n", "\n", " def __str__(self):\n", " return repr(self.uzenet)+repr(self.adat)\n", "\n", "\n", "try:\n", " age = int(input())\n", " if age < 0:\n", " raise NegativeAgeError(\"Az életkor nem lehet negatív:\",age)\n", "except NegativeAgeError as e:\n", " print(e)\n", " print(e.adat)\n", "except Exception as e:\n", " print(\"Valamilyen más hibát kaptunk el. Típus: {}, üzenet: {}\".format(type(e), e))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Iterálás, funkcionális eszközök" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sokféle objektumot tudunk használni for ciklusokban:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n", "4\n" ] } ], "source": [ "for i in [1, 2, 3, 4]:\n", " print(i)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "p\n", "y\n", "t\n", "h\n", "o\n", "n\n" ] } ], "source": [ "for c in \"python\":\n", " print(c)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x\n", "y\n" ] } ], "source": [ "for k in {\"x\": 1, \"y\": 2}:\n", " print(k)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1,Donielle,Vickar,dvickar0@tmall.com,true\n", "\n", "2,Perle,Claye,pclaye1@blogs.com,true\n", "\n", "3,Flori,Wharf,fwharf2@zdnet.com,true\n", "\n", "4,Kristen,Haryngton,kharyngton3@yelp.com,false\n", "\n", "5,Bibby,Covill,bcovill4@psu.edu,true\n", "\n", "6,Illa,D'Elias,idelias5@twitter.com,true\n", "\n", "7,Genia,Woodyear,gwoodyear6@reuters.com,false\n", "\n", "8,Patrice,Rhys,prhys7@meetup.com,false\n", "\n", "9,Rich,Gavozzi,rgavozzi8@istockphoto.com,false\n", "\n", "10,Elfie,Comben,ecomben9@un.org,true\n" ] } ], "source": [ "with open(\"pelda_fajl.txt\", \"r\") as fajlobj:\n", " for line in fajlobj:\n", " print(line)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Ezeket az osztályokat közösen **iterálható** osztályoknak hívjuk.\n", "Az iterálható osztályokhoz tartozik egy-egy **iterátor**, amit megkaphatunk az `iter` függvénnyel. A `next()` függvény megadja az iterátor következő elemét. Ha már nincs több elem, `StopIteration` hibát kapunk. (Emiatt egyszerhasználatosak az iterátorok.)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "S\n", "ü\n", "s\n", "ü\n" ] }, { "ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmyiter\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmyiter\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmyiter\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mStopIteration\u001b[0m: " ] } ], "source": [ "myiter=iter(\"Süsü\")\n", "print(next(myiter))\n", "print(next(myiter))\n", "print(next(myiter))\n", "print(next(myiter))\n", "print(next(myiter))\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Ez a két tulajdonság definiálja is az iterátorokat. Tehát egy iterátornak a következőket kell tudnia:\n", "1. Van egy `__next__` függvénye, ami visszadja sorban az elemeket és\n", "2. `StopIteration` hibát ad, ha nincs több elem.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Egy osztály **iterálható** ha a van egy `__iter__` függvénye ami visszatér egy **iterátorral**.\n" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Aktuális: 4\n", "4\n", "Aktuális: 3\n", "3\n", "Aktuális: 2\n", "2\n", "Aktuális: 1\n", "1\n", "Aktuális: 0\n", "0\n" ] } ], "source": [ "class MyIterator:\n", " def __init__(self):\n", " self.iter_no = 5\n", " \n", " def __iter__(self):\n", " return self\n", " \n", " def __next__(self):\n", " if self.iter_no <= 0:\n", " raise StopIteration()\n", " self.iter_no = self.iter_no- 1\n", " print(\"Aktuális: {}\".format(self.iter_no))\n", " return self.iter_no\n", " #return \"itt tartunk:\"+str(self.iter_no)\n", " \n", "myiter = MyIterator()\n", "\n", "for i in myiter:\n", " print(i)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Süsü', 1]\n", "['Smaug', 1]\n", "['Hétfejű', 1]\n", "['Hétfejű', 2]\n", "['Hétfejű', 3]\n", "['Hétfejű', 4]\n", "['Hétfejű', 5]\n", "['Hétfejű', 6]\n", "['Hétfejű', 7]\n", "['Ghidorah', 1]\n", "['Ghidorah', 2]\n", "['Ghidorah', 3]\n", "['Süsü', 1]\n", "['Smaug', 1]\n", "['Hétfejű', 1]\n", "['Hétfejű', 2]\n", "['Hétfejű', 3]\n", "['Hétfejű', 4]\n", "['Hétfejű', 5]\n", "['Hétfejű', 6]\n", "['Hétfejű', 7]\n", "['Ghidorah', 1]\n", "['Ghidorah', 2]\n", "['Ghidorah', 3]\n" ] } ], "source": [ "class Sarkanyiterator:\n", " def __init__(self,fejlista):\n", " self.fejlista=fejlista\n", " self.aktualis_sarkany=0\n", " self.aktualis_fej=1\n", " \n", " \n", " def __next__(self):\n", " mostani_sarkany=self.aktualis_sarkany\n", " mostani_fej=self.aktualis_fej\n", " if self.aktualis_sarkany>=len(self.fejlista) or (self.aktualis_sarkany==len(self.fejlista)-1 and self.aktualis_fej>self.fejlista[-1][1]):\n", " raise StopIteration()\n", " \n", " if self.fejlista[self.aktualis_sarkany][1]>self.aktualis_fej:\n", " self.aktualis_fej= self.aktualis_fej+1\n", " else:\n", " self.aktualis_sarkany=self.aktualis_sarkany+1\n", " self.aktualis_fej=1\n", " \n", " return [self.fejlista[ mostani_sarkany][0],mostani_fej]\n", " \n", " \n", "class SarkanyBarlang:\n", " def __init__(self):\n", " self.sarkanyfejlista = [(\"Süsü\",1),(\"Smaug\",1),(\"Hétfejű\",7),(\"Ghidorah\",3)]\n", " \n", " def __iter__(self): \n", " return Sarkanyiterator(self.sarkanyfejlista)\n", " \n", "barlang = SarkanyBarlang()\n", "\n", "for fej in barlang:\n", " print(fej)\n", " \n", "for fej in barlang:\n", " print(fej)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "**Rengeteg függvény van, ami elfogad bármilyen iterátort!** " ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<__main__.Sarkanyiterator at 0x21ec0762c48>" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iter(barlang)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[['Süsü', 1],\n", " ['Smaug', 1],\n", " ['Hétfejű', 1],\n", " ['Hétfejű', 2],\n", " ['Hétfejű', 3],\n", " ['Hétfejű', 4],\n", " ['Hétfejű', 5],\n", " ['Hétfejű', 6],\n", " ['Hétfejű', 7],\n", " ['Ghidorah', 1],\n", " ['Ghidorah', 2],\n", " ['Ghidorah', 3]]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(barlang)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Hétfejű', 7]" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "max(barlang,key=lambda x:x[1])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# Iterátorok gyártása gyorsabban\n", "### Generátor kifejezések\n", "\n", "A **generátorok** speciális iterátorok. A fő gondolat mögöttük, hogy sokszor nincs szükség egy list összes elemének a legyártásához, ha csak végig akarunk haladni a listán, hanem elég, ha mindig ki tudjuk számítani a következő elemet. Így sokkal kevesebb memóriát használ a gép. \n", "\n", "Több mód is van a generátorok létrehozására, az egyik a **generátor kifejezések**, amik a list comprehensionök általánosításai. \n", "\n", "Egy generátor kifejezést megadhatunk úgy, hogy () zárójelek közé írjuk a list comprehension kódját a [] zárójelek helyett. " ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "9999999900000000\n", "Wall time: 18.3 s\n" ] } ], "source": [ "%%time\n", "N = 8\n", "s = sum([i*2 for i in range(int(10**N))])\n", "print(s)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "9999999900000000\n", "Wall time: 11.6 s\n" ] } ], "source": [ "%%time\n", "s = sum((i*2 for i in range(int(10**N))))\n", "print(s)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Mivel a generátorok csak végéghaladnak a listán és nem gyártják azt le, így ezek is csak egyszerhasználatosak." ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " at 0x0000021EC0759A48>" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "even_numbers = (2*n for n in range(10))\n", "even_numbers" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "2\n", "4\n", "6\n", "8\n", "10\n", "12\n", "14\n", "16\n", "18\n" ] } ], "source": [ "for num in even_numbers:\n", " print(num)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Második futásra már üres:" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [], "source": [ "for num in even_numbers:\n", " print(num)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Minden generátor objektum is egyben iterátor, tehát a `next()` függvény megadja a következő elemet, ha pedig már nincs, `StopIteration` hibát ad. " ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "2\n", "4\n", "6\n", "8\n", "10\n", "12\n", "14\n", "16\n", "18\n" ] } ], "source": [ "even_numbers = (2*n for n in range(10))\n", "\n", "while True:\n", " try:\n", " print(next(even_numbers))\n", " except StopIteration:\n", " break" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0meven_numbers\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# StopIteration\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mStopIteration\u001b[0m: " ] } ], "source": [ " next(even_numbers) # StopIteration" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### itertools modul\n", "- az iterátorok akkor válnak igazán hasznossá, ha kibővítjük őke. \n", "- az itertools modulban rengeteg bővítés van iterátorokhoz, megéri elolvasni a hivatalos leírást: https://docs.python.org/3.8/library/itertools.html#module-itertools\n", "\n" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [], "source": [ "import itertools as it" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Végtelen iterátorok:" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A\n", "B\n", "C\n", "D\n", "A\n", "B\n", "C\n", "D\n", "A\n", "B\n" ] } ], "source": [ "gen=it.cycle('ABCD')\n", "for _ in range(10):\n", " print(next(gen))" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "11\n", "12\n" ] } ], "source": [ "gen=it.count(3)\n", "for _ in range(10):\n", " print(next(gen))" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A\n", "B\n", "C\n", "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n" ] } ], "source": [ "c=it.chain.from_iterable(['ABC', range(10)])\n", "for a in c:\n", " print(a)" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 a\n", "0 s\n", "0 d\n", "1 a\n", "1 s\n", "1 d\n", "2 a\n", "2 s\n", "2 d\n" ] } ], "source": [ "for i,j in it.product(range(3),\"asd\"):\n", " print(i,j)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### filter \n", "- feltételnek eleget tevő elemekre szűrés" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 3, 5, 7, 9]" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(filter(lambda x: x%2, range(10)))" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 2, 4, 6, 8]" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(it.filterfalse(lambda x: x%2, range(10)))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### map\n", " a `map` meghívja a megadott függvényt az iterátor minden elemére" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[4, 6, 'abcabc']" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def double(e):\n", " return e + e\n", "\n", "l = [2, 3, \"abc\"]\n", "\n", "list(map(double, l))" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [], "source": [ "m=map(double, l)" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mm\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mStopIteration\u001b[0m: " ] } ], "source": [ "next(m)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### zip\n", "- Két felsorolható objektumból párokat készít\n", "- a * operátor segítségével inverz műveletet is megvalósítható" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(1, 'one', 'one2'), (2, 'two', 'two2'), (3, 'three', 'three2')]\n" ] } ], "source": [ "number_list = [1, 2, 3]\n", "str_list = ['one', 'two', 'three']\n", "str_list2 = ['one2', 'two2', 'three2']\n", "\n", "result = zip(number_list, str_list,str_list2)\n", "\n", "result_list = list(result)\n", "print(result_list)" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[('x', 3), ('y', 4), ('z', 5)]\n", "c = ('x', 'y', 'z')\n", "v = (3, 4, 5)\n" ] } ], "source": [ "coordinate = ['x', 'y', 'z']\n", "value = [3, 4, 5]\n", "\n", "result = zip(coordinate, value)\n", "result_list = list(result)\n", "print(result_list)\n", "\n", "c, v = zip(*result_list)\n", "print('c =', c)\n", "print('v =', v)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Fájlok írása és olvasása\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A legfontosabb operációk:\n", "\n", "- az `open('fajlnev','r')` parancs megnyitva a fajlnev nevű fájlt olvasásra és visszatért a file objektummal\n", "- az `open('fajlnev','w')` parancs megnyitva a fajlnev nevű fájlt írásra és visszatért a file objektummal\n", "- a `fajlobjektum.close()` parancs lezárja a fájlt, akár írtunk bele akár olvastunk \n", "\n", "A következő példa fájlt fogjuk használni, amit a `pelda_fajl.txt`-be mentettem:" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "1,Donielle,Vickar,dvickar0@tmall.com,true\n", "2,Perle,Claye,pclaye1@blogs.com,true\n", "3,Flori,Wharf,fwharf2@zdnet.com,true\n", "4,Kristen,Haryngton,kharyngton3@yelp.com,false\n", "5,Bibby,Covill,bcovill4@psu.edu,true\n", "6,Illa,D'Elias,idelias5@twitter.com,true\n", "7,Genia,Woodyear,gwoodyear6@reuters.com,false\n", "8,Patrice,Rhys,prhys7@meetup.com,false\n", "9,Rich,Gavozzi,rgavozzi8@istockphoto.com,false\n", "10,Elfie,Comben,ecomben9@un.org,true" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Fájl beolvasása \n", "\n", "Egy sort beolvashatunk a `.readline()` függvénnyel: \n", "- Beolvassa a whitespaceket, például a sorvégi új sor karatert is! \n", "- A következő sorra lép, tehát többszöri meghívás esetén végighalad a fájlon.\n", "- A fájl végén hibát jelez, így használható egy while ciklusban" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1,Donielle,Vickar,dvickar0@tmall.com,true\n", "\n", "2,Perle,Claye,pclaye1@blogs.com,true\n", "\n", "'2,Perle,Claye,pclaye1@blogs.com,true\\n'\n" ] } ], "source": [ "fajlobj = open(\"pelda_fajl.txt\", \"r\")\n", "line=fajlobj.readline()\n", "print(line)\n", "line=fajlobj.readline()\n", "print(line)\n", "print(repr(line))\n", "fajlobj.close()" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 Donielle Vickar email: dvickar0@tmall.com\n", "2 Perle Claye email: pclaye1@blogs.com\n", "3 Flori Wharf email: fwharf2@zdnet.com\n", "4 Kristen Haryngton email: kharyngton3@yelp.com\n", "5 Bibby Covill email: bcovill4@psu.edu\n", "6 Illa D'Elias email: idelias5@twitter.com\n", "7 Genia Woodyear email: gwoodyear6@reuters.com\n", "8 Patrice Rhys email: prhys7@meetup.com\n", "9 Rich Gavozzi email: rgavozzi8@istockphoto.com\n", "10 Elfie Comben email: ecomben9@un.org\n" ] } ], "source": [ "fajlobj = open(\"pelda_fajl.txt\", \"r\")\n", "line=fajlobj.readline()\n", "while line:\n", " values = line.strip().split(\",\")\n", " print(\"{} {} {} email: {}\".format(*values))\n", " line=fajlobj.readline()\n", " \n", "fajlobj.close()\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Egy fájlon a for ciklus segítségével is végighaladhatunk:" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['1', 'Donielle', 'Vickar', 'dvickar0@tmall.com', 'true']\n", "['2', 'Perle', 'Claye', 'pclaye1@blogs.com', 'true']\n", "['3', 'Flori', 'Wharf', 'fwharf2@zdnet.com', 'true']\n", "['4', 'Kristen', 'Haryngton', 'kharyngton3@yelp.com', 'false']\n", "['5', 'Bibby', 'Covill', 'bcovill4@psu.edu', 'true']\n", "['6', 'Illa', \"D'Elias\", 'idelias5@twitter.com', 'true']\n", "['7', 'Genia', 'Woodyear', 'gwoodyear6@reuters.com', 'false']\n", "['8', 'Patrice', 'Rhys', 'prhys7@meetup.com', 'false']\n", "['9', 'Rich', 'Gavozzi', 'rgavozzi8@istockphoto.com', 'false']\n", "['10', 'Elfie', 'Comben', 'ecomben9@un.org', 'true']\n" ] } ], "source": [ "fajlobj = open(\"pelda_fajl.txt\", \"r\")\n", "\n", "for line in fajlobj:\n", " values = line.strip().split(\",\")\n", " print(values) \n", " \n", "fajlobj.close()\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Egyéb lehetőségek:\n", "- `fajlobj.read(n)` beolvas n karaktert, vagy ha paraméter nélkül hívjuk az egész fájlt. \n", "- `fajlobj.readlines()` visszaadja a fájl sorait egy listában. \n" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1,Donielle,Vickar,dvickar0@tmall.com,true\n", "2,Perle,Claye,pclaye1@blogs.com,true\n", "3,Flori,Wharf,fwharf2@zdnet.com,true\n", "4,Kristen,Haryngton,kharyngton3@yelp.com,false\n", "5,Bibby,Covill,bcovill4@psu.edu,true\n", "6,Illa,D'Elias,idelias5@twitter.com,true\n", "7,Genia,Woodyear,gwoodyear6@reuters.com,false\n", "8,Patrice,Rhys,prhys7@meetup.com,false\n", "9,Rich,Gavozzi,rgavozzi8@istockphoto.com,false\n", "10,Elfie,Comben,ecomben9@un.org,true\n" ] } ], "source": [ "fajlobj = open(\"pelda_fajl.txt\", \"r\")\n", "\n", "tartalom=fajlobj.read()\n", "print(tartalom)\n", "\n", "fajlobj.close() \n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Fájlok írása\n", "\n", " A `fajlobj.write(egy_string)` parancs a fájl végére írja a megadott stringet. Ehhez a fajlobj-nak egy írásra megnyitott fájlnak kell lennie.\n" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ezt találtam a fájlban: Na ezt most kiírom egy fájlba! xxxx\n" ] } ], "source": [ "fajlirni = open(\"pelda_fajl_irni.txt\", \"w\") # ha nem létezik a fájl létrehozza azt. \n", "\n", "fajlirni.write(\"Na ezt most kiírom egy fájlba! xxxx\")\n", "\n", "fajlirni.close()\n", "\n", "fajlolvasni = open(\"pelda_fajl_irni.txt\", \"r\") \n", "tartalom=fajlolvasni.read()\n", "print(\"Ezt találtam a fájlban: \" + tartalom)\n", "fajlolvasni.close()\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# Hibalehetőségek" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Miért kell lezárni egy fájlt?\n", "Ha nem zárjuk be, gondokat okozhat, hogy korábbi operációk még nem hajtódtak végre. Például: " ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ezt találtam a fájlban: Na ezt most kiírom egy fájlba!\n" ] } ], "source": [ "fajlirni = open(\"pelda_fajl_irni.txt\", \"w\") \n", "\n", "fajlirni.write(\"Na ezt most kiírom egy fájlba!\")\n", "fajlirni.close()\n", "\n", "fajlolvasni = open(\"pelda_fajl_irni.txt\", \"r\") \n", "tartalom=fajlolvasni.read()\n", "print(\"Ezt találtam a fájlban: \" + tartalom)\n", "fajlolvasni.close()\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## with kulcsszó\n", "A `with` kulcsszó automatikusan megoldja nekünk a lezárást és a hibakezelést. Használat:\n", "\n", "`with open(argumentumok) as valtozonev:`\n", " \n", " kód indentálva\n", "\n", "Ha sikerül megnyitni a fájlt, lefuttatja az indentált részt, majd meghívja helyettünk a close() parancsot." ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ezt találtam a fájlban: Na ezt most kiírom egy fájlba!\n" ] } ], "source": [ "with open(\"pelda_fajl_irni.txt\", \"w\") as fajlirni:\n", " fajlirni.write(\"Na ezt most kiírom egy fájlba!\")\n", " \n", "\n", "with open(\"pelda_fajl_irni.txt\", \"r\") as fajlolvasni:\n", " tartalom=fajlolvasni.read()\n", " print(\"Ezt találtam a fájlban: \" + tartalom)\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Karakterkódolás\n", "- Több féle karakterkódolás is létezik. \n", "- Néha meg kell mondani a Pythonnak, hogy melyiket használja, különben rosszul értelmezi a fájlt.\n", "- Leggyakoribbak: utf-8 és latin-1" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ezt találtam a fájlban: árvĂ­ztűrĹ‘ tĂĽkörfĂşrĂłgĂ©p\n" ] } ], "source": [ "with open(\"pelda_fajl_irni.txt\", \"w\", encoding='utf-8') as fajlirni:\n", " fajlirni.write(\"árvíztűrő tükörfúrógép\")\n", "\n", "with open(\"pelda_fajl_irni.txt\", \"r\") as fajlolvasni:\n", " tartalom=fajlolvasni.read()\n", " print(\"Ezt találtam a fájlban: \" + tartalom)\n" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ezt találtam a fájlban: árvíztűrő tükörfúrógép\n" ] } ], "source": [ "with open(\"pelda_fajl_irni.txt\", \"w\", encoding='utf-8') as fajlirni:\n", " fajlirni.write(\"árvíztűrő tükörfúrógép\")\n", "\n", "with open(\"pelda_fajl_irni.txt\", \"r\",encoding='utf-8') as fajlolvasni:\n", " tartalom=fajlolvasni.read()\n", " print(\"Ezt találtam a fájlban: \" + tartalom)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### json (JavaScript Object Notation)\n", "- a json egy fájl formátum, ami nagyon elterjedt, főleg web programozásban. \n", "- a dictionary-k kiírására és beolvasására kényelmesen használható\n", "- Kiírás: `json.dump(data, outfile)`, beolvasás: `json.load(json_file)`" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [], "source": [ "import json \n", "\n", "data = {}\n", "data['sárkányok'] = []\n", "data['sárkányok'].append({\n", " 'nev': 'Süsü',\n", " 'támadás': 'ölelés',\n", " 'lakhely': 'Magyarország'\n", "})\n", "data['sárkányok'].append({\n", " 'nev': 'Smaug',\n", " 'támadás': 'tűzokádás',\n", " 'lakhely': 'Középfölde'\n", "})\n", "data['sárkányok'].append({\n", " 'nev': 'Rhaegal',\n", " 'támadás': 'tűzokádás',\n", " 'lakhely': 'Westeros'\n", "})\n", "\n", "with open('data.txt', 'w') as outfile:\n", " json.dump(data, outfile)" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Név: Süsü\n", "Támadás: ölelés\n", "Lakóhely: Magyarország\n", "\n", "Név: Smaug\n", "Támadás: tűzokádás\n", "Lakóhely: Középfölde\n", "\n", "Név: Rhaegal\n", "Támadás: tűzokádás\n", "Lakóhely: Westeros\n", "\n" ] } ], "source": [ "import json\n", "\n", "with open('data.txt') as json_file:\n", " adat = json.load(json_file)\n", " for p in adat['sárkányok']:\n", " print('Név: ' + p['nev'])\n", " print('Támadás: ' + p['támadás'])\n", " print('Lakóhely: ' + p['lakhely'])\n", " print('')" ] } ], "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.4" } }, "nbformat": 4, "nbformat_minor": 5 }