{ "cells": [ { "cell_type": "markdown", "id": "cd0bab55", "metadata": {}, "source": [ "# Exceptions\n", "\n", "Bisher ist unser Programm abgestürzt, wenn Fehler auftreten. Das muss nicht passieren:" ] }, { "cell_type": "code", "execution_count": 5, "id": "1243337c", "metadata": {}, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "division by zero", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[5], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;241;43m1\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\n", "\u001b[0;31mZeroDivisionError\u001b[0m: division by zero" ] } ], "source": [ "1 / 0" ] }, { "cell_type": "code", "execution_count": 4, "id": "c8d4962e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "division by zero\n", "Fertig.\n" ] } ], "source": [ "try:\n", " 1 / 0\n", "\n", "except ZeroDivisionError as exc:\n", " print(exc)\n", "\n", "finally:\n", " print(\"Fertig.\")\n" ] }, { "cell_type": "markdown", "id": "6d40ff35", "metadata": {}, "source": [ "Schön ist auch `raise` innerhalb eines `except`-Blocks.\n", "\n", "So wird der Fehler bearbeitet, aber bleibt nicht unentdeckt:" ] }, { "cell_type": "code", "execution_count": 7, "id": "f9e8689d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a kann nicht als Integer benutzt werden.\n" ] }, { "ename": "ValueError", "evalue": "invalid literal for int() with base 10: 'a'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[7], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 2\u001b[0m x \u001b[38;5;241m=\u001b[39m \u001b[38;5;28minput\u001b[39m()\n\u001b[0;32m----> 3\u001b[0m x \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m:\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(x, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mkann nicht als Integer benutzt werden.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", "\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'a'" ] } ], "source": [ "try:\n", " x = input()\n", " x = int(x)\n", "except ValueError:\n", " print(x, \"kann nicht als Integer benutzt werden.\")\n", " raise\n", "else:\n", " print(\"Kein Value-Fehler\")\n" ] }, { "cell_type": "markdown", "id": "0631e2b4", "metadata": {}, "source": [ "Man kann auch eigene Fehler definieren, die von Exception erben:" ] }, { "cell_type": "code", "execution_count": 8, "id": "747ab3fa", "metadata": {}, "outputs": [ { "ename": "MeinFehler", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mMeinFehler\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[8], line 4\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mclass\u001b[39;00m \u001b[38;5;21;01mMeinFehler\u001b[39;00m(\u001b[38;5;167;01mException\u001b[39;00m):\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mpass\u001b[39;00m\n\u001b[0;32m----> 4\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m MeinFehler\n", "\u001b[0;31mMeinFehler\u001b[0m: " ] } ], "source": [ "class MeinFehler(Exception):\n", " pass\n", "\n", "raise MeinFehler" ] }, { "cell_type": "markdown", "id": "e3ac0adb", "metadata": {}, "source": [ "# with\n", "\n", "`with` ist ein sogenannter Kontextmanager.\n", "\n", "Eine genauere Beschreibung als hier findet sich unter und .\n", "\n", "Hier folgen nun einige Beispiele.\n", "\n", "## Dateien öffnen" ] }, { "cell_type": "code", "execution_count": 1, "id": "a718b5e9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.\n", "Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.\n", "Suspendisse lectus leo, consectetur in tempor sit amet, placerat quis neque. Etiam luctus porttitor lorem, sed suscipit est rutrum non. Curabitur lobortis nisl a enim congue semper. Aenean commodo ultrices imperdiet. Vestibulum ut justo vel sapien venenatis tincidunt. Phasellus eget dolor sit amet ipsum dapibus condimentum vitae quis lectus. Aliquam ut massa in turpis dapibus convallis. Praesent elit lacus, vestibulum at malesuada et, ornare et est. Ut augue nunc, sodales ut euismod non, adipiscing vitae orci. Mauris ut placerat justo. Mauris in ultricies enim. Quisque nec est eleifend nulla ultrices egestas quis ut quam. Donec sollicitudin lectus a mauris pulvinar id aliquam urna cursus. Cras quis ligula sem, vel elementum mi. Phasellus non ullamcorper urna.\n", "Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In euismod ultrices facilisis. Vestibulum porta sapien adipiscing augue congue id pretium lectus molestie. Proin quis dictum nisl. Morbi id quam sapien, sed vestibulum sem. Duis elementum rutrum mauris sed convallis. Proin vestibulum magna mi. Aenean tristique hendrerit magna, ac facilisis nulla hendrerit ut. Sed non tortor sodales quam auctor elementum. Donec hendrerit nunc eget elit pharetra pulvinar. Suspendisse id tempus tortor. Aenean luctus, elit commodo laoreet commodo, justo nisi consequat massa, sed vulputate quam urna quis eros. Donec vel. \n", "\n" ] } ], "source": [ "with open(\"../Level_04/Beispielcode/loremipsum.txt\") as lorem:\n", " print(lorem.read())" ] }, { "cell_type": "markdown", "id": "4573de3f", "metadata": {}, "source": [ "## Exceptions ignorieren" ] }, { "cell_type": "code", "execution_count": 2, "id": "75ef5391", "metadata": {}, "outputs": [], "source": [ "from contextlib import suppress\n", "\n", "with suppress(ZeroDivisionError):\n", " print(1 / 0)" ] }, { "cell_type": "markdown", "id": "e96478a9", "metadata": {}, "source": [ "## temporäre Dateien und Ordner" ] }, { "cell_type": "code", "execution_count": 3, "id": "0cdf805c", "metadata": {}, "outputs": [], "source": [ "import tempfile\n", "from os.path import join\n", "\n", "with tempfile.TemporaryFile(mode=\"w\") as tmpfile:\n", " tmpfile.write(\"Dies ist ein Test.\\n\")\n", "\n", "with tempfile.TemporaryDirectory() as tmpdir:\n", " with open(join(tmpdir, \"test.txt\"), \"w\") as test:\n", " test.write(\"Dies ist auch ein Test.\\n\")" ] }, { "cell_type": "markdown", "id": "f69a7254", "metadata": {}, "source": [ "contextlib bietet auch Dekoratoren an, um eigene Contextmanager zu erstellen:\n", "" ] }, { "cell_type": "markdown", "id": "9b383d6b", "metadata": {}, "source": [ "# Generatoren\n", "\n", "Generatoren können \"lazy\" Elemente erzeugen:" ] }, { "cell_type": "code", "execution_count": 10, "id": "581b8844", "metadata": {}, "outputs": [], "source": [ "# Generatoren und yield\n", "def gen(s):\n", " for char in s:\n", " yield char" ] }, { "cell_type": "code", "execution_count": 11, "id": "a75ac011", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n", "b\n", "c\n", "d\n", "e\n", "f\n" ] } ], "source": [ "# iterieren mit einer for-Schleife:\n", "for x in gen(\"abcdef\"):\n", " print(x)" ] }, { "cell_type": "code", "execution_count": 13, "id": "8d4afc47", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "f\n", "o\n" ] } ], "source": [ "# oder manuell mit next:\n", "g = gen(\"foobar\")\n", "print(next(g))\n", "print(next(g))" ] }, { "cell_type": "markdown", "id": "4c7e69b4", "metadata": {}, "source": [ "# Dekoratoren\n", "\n", "Dekoratoren sind Funktionen, die auf Funktionen angewandt werden bei deren Definition:" ] }, { "cell_type": "code", "execution_count": 14, "id": "d3ed8738", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n", "9\n" ] } ], "source": [ "def f(x):\n", " return x**2\n", "\n", "print(f(2))\n", "print(f(3))" ] }, { "cell_type": "code", "execution_count": 26, "id": "a2bba8e0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Args: (2,)\n", "Return: 4\n" ] }, { "data": { "text/plain": [ "4" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def dec(func):\n", " def inner_func(*args):\n", " print(f\"Args: {args}\")\n", " r = func(*args)\n", " print(f\"Return: {r}\")\n", " return r\n", "\n", " return inner_func\n", "\n", "\n", "@dec\n", "def f(x):\n", " return x**2\n", "\n", "f(2)" ] }, { "cell_type": "markdown", "id": "7abbcad7", "metadata": {}, "source": [ "# map\n", "\n", "Mit `map` lassen sich Funktionen auf jedes Element eines Generators anwenden:" ] }, { "cell_type": "code", "execution_count": 25, "id": "9caff1aa", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def add_2(x):\n", " return x + 2\n", "\n", "\n", "l = range(10)\n", "result = list(map(add_2, l))\n", "result\n", "\n", "# äquivalent zum folgenden Code:\n", "# result = []\n", "# for i in l:\n", "# result.append(add_2(i))\n", "\n", "# oder auch: result = [add_2(x) for x in l]" ] }, { "cell_type": "markdown", "id": "f1b2b72d", "metadata": {}, "source": [ "# filter\n", "\n", "`filter` funktioniert ähnlich, aber \"siebt\" die Elemente:" ] }, { "cell_type": "code", "execution_count": 24, "id": "ed19bc69", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0,\n", " 2,\n", " 4,\n", " 6,\n", " 8,\n", " 10,\n", " 12,\n", " 14,\n", " 16,\n", " 18,\n", " 20,\n", " 22,\n", " 24,\n", " 26,\n", " 28,\n", " 30,\n", " 32,\n", " 34,\n", " 36,\n", " 38,\n", " 40,\n", " 42,\n", " 44,\n", " 46,\n", " 48,\n", " 50,\n", " 52,\n", " 54,\n", " 56,\n", " 58,\n", " 60,\n", " 62,\n", " 64,\n", " 66,\n", " 68,\n", " 70,\n", " 72,\n", " 74,\n", " 76,\n", " 78,\n", " 80,\n", " 82,\n", " 84,\n", " 86,\n", " 88,\n", " 90,\n", " 92,\n", " 94,\n", " 96,\n", " 98]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def even(n):\n", " return n % 2 == 0\n", "\n", "\n", "r = range(100)\n", "even_numbers = list(filter(even, r))\n", "# oder: even_numbers = [x for x in r if even(x)]\n", "even_numbers" ] }, { "cell_type": "markdown", "id": "f53c24bb", "metadata": {}, "source": [ "# zip\n", "\n", "`zip` fügt mehrere Iteratoren zusammen:" ] }, { "cell_type": "code", "execution_count": 23, "id": "1c3cf39f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, -10),\n", " (1, -9),\n", " (2, -8),\n", " (3, -7),\n", " (4, -6),\n", " (5, -5),\n", " (6, -4),\n", " (7, -3),\n", " (8, -2),\n", " (9, -1)]" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iter1 = range(10)\n", "iter2 = range(-10, 0)\n", "list(zip(iter1, iter2))" ] }, { "cell_type": "markdown", "id": "491e268c", "metadata": {}, "source": [ "# lambda\n", "\n", "Mit `lambda` lassen sich anonyme Funktionen definieren:" ] }, { "cell_type": "code", "execution_count": 22, "id": "92c56dea", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0,\n", " 2,\n", " 4,\n", " 6,\n", " 8,\n", " 10,\n", " 12,\n", " 14,\n", " 16,\n", " 18,\n", " 20,\n", " 22,\n", " 24,\n", " 26,\n", " 28,\n", " 30,\n", " 32,\n", " 34,\n", " 36,\n", " 38,\n", " 40,\n", " 42,\n", " 44,\n", " 46,\n", " 48,\n", " 50,\n", " 52,\n", " 54,\n", " 56,\n", " 58,\n", " 60,\n", " 62,\n", " 64,\n", " 66,\n", " 68,\n", " 70,\n", " 72,\n", " 74,\n", " 76,\n", " 78,\n", " 80,\n", " 82,\n", " 84,\n", " 86,\n", " 88,\n", " 90,\n", " 92,\n", " 94,\n", " 96,\n", " 98]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(filter(lambda x: x % 2 == 0, r))" ] }, { "cell_type": "markdown", "id": "cf140ff2", "metadata": {}, "source": [ "# all / any\n", "\n", "`all` und `any` laufen einen Iterator ab und prüfen Bedigungen, brechen aber ggf. früher ab:" ] }, { "cell_type": "code", "execution_count": 27, "id": "49dbeb10", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all(even(x) for x in even_numbers)" ] }, { "cell_type": "markdown", "id": "90fea9ed", "metadata": {}, "source": [ "Für mehr Spaß mit Generatoren lohnt sich ein Blick auf [itertools](https://docs.python.org/3/library/itertools.html) und [more-itertools](https://more-itertools.readthedocs.io)." ] } ], "metadata": { "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.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }