{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Programmiertechniken\n", "\n", "Die Sammlung all dieser Werkzeuge ist die Basis eines erfolgreichen Programmierers und Programmiererin.\n", "Der Bezug zu den früher vorgestellten Konzepten ist,\n", "dass diese Techniken darauf aufbauen oder weiterführende Aspekte beinhalten.\n", "Insbesondere behandeln diese Techniken die Themen, die im \"Alltag\" ständig verwendet werden.\n", "Es handelt sich hierbei um:\n", "\n", " * **Exceptions:** das ist das Behandeln und Verarbeiten von Fehlermeldungen, die im Programmablauf auftreten könnten\n", " * **Dokumentation:** Module, Klassen, Methoden und Funktionen können mit freiem Text versehen werden, die diese erklären.\n", " Das ist deshalb wichtig, weil beim Programmieren die meiste Zeit an schon bestehendem Programmcode\n", " (der manchmal schon recht alt sein kann, oder von jemand anderem geschrieben wurde) gearbeitet wird.\n", " * **eigenständige Programme:** Das sind nicht diese Zellen in IPython Notebooks, sondern Programmdateien mit der Endung `*.py`.\n", " Eine Sammlung derer kann eine Programmbibliothek bilden.\n", " * **Datenschnittstellen:** Daten können von den unterschiedlichsten Quellen stammen: Textdatei, Binärdatei, Datenbank, ...\n", " * **Netzwerk- & Internetverbindungen:** Kommunikation mit der Außenwelt\n", " * **fortgeschrittene Programmierkonzepte:** Multithreading und -tasking, etc." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exception/Errors (Ausnahmebehandlung)\n", "\n", "Gibt es einen Fehler, einen unvorhergesehenen Zustand oder einen falschen bzw. unerwarteten Wert,\n", "so erlauben \"`Exception`\"s und \"`Error`\"s das Programm abzubrechen.\n", "Dabei handelt es sich um ein Objekt, das die Fehlermeldung beinhaltet und zu einem bestimmten Typ gehört.\n", "\n", "Es gibt auch es die Möglichkeit eine Exception aufzuhalten.\n", "Dann bricht das Programm nicht vollständig ab,\n", "sondern läuft an der Stelle wo die Exception aufgefangen wurde weiter.\n", "\n", "Beispiel: Eine Funktion erwartet, dass ihr eine positive Zahl übergeben wird.\n", "Es wird jedoch eine negative Übergeben und die \"Katastrophe\" abgewendet." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def f(x):\n", " if x < 0:\n", " raise ValueError(\"x ist negativ!\")\n", " from math import sqrt\n", " return sqrt(x) - 1" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.41421356237309515" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(2)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ValueError", "evalue": "x ist negativ!", "output_type": "error", "traceback": [ "\u001b[1;31m\u001b[0m", "\u001b[1;31mValueError\u001b[0mTraceback (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[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;32m\u001b[0m in \u001b[0;36mf\u001b[1;34m(x)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mx\u001b[0m \u001b[1;33m<\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"x ist negativ!\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mmath\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msqrt\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0msqrt\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m-\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mValueError\u001b[0m: x ist negativ!" ] } ], "source": [ "f(-2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nun fangen wir diesen Fehler mit einer `try`-`except` Konstruktion ab:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def outer(k = 2):\n", " try:\n", " x = k - 10\n", " z = f(x)\n", " print(\"Kein Problem, z=%f\" % z)\n", " except Exception as e:\n", " print(\"Es gab einen Fehler: %s\" % e)\n", " # rückgabe von 0 als fallback\n", " return 0\n", " return z" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Es gab einen Fehler: x ist negativ!\n" ] }, { "data": { "text/plain": [ "0" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "outer()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Kein Problem, z=0.414214\n" ] }, { "data": { "text/plain": [ "0.41421356237309515" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "outer(12)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Beachte:** Die Zeile `print(\"Kein Problem...\")` wird nur dann ausgeführt,\n", "wenn es keine Exception gab.\n", "Soll ein Code in jedem Fall ausgeführt werden, gibt es noch das `finally:` Schlüsselwort.\n", "Soll hingegen wenn es keinen Fehler gab ein Codeblock ausgeführt werden,\n", "schreibt man dies in ein `else:`.\n", "\n", "Zusammengefasst ist die volle Struktur so:\n", "\n", "```\n", "try:\n", " ... führe aus ...\n", " ... mit möglichen ...\n", " ... Fehlern ...\n", "except FehlerTyp as variable:\n", " ... Fehlerbehandlung des Fehlers ...\n", "finally:\n", " ... Egal ob Fehler oder nicht ...\n", "else:\n", " ... es gab keinen Fehler ...\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Häufig verwendete Type von Fehlern sind:\n", "\n", "* ValueError: Wert ist falsch, Typ ok\n", "* TypeError: Typ ist flasch\n", "\n", "https://docs.python.org/2/library/exceptions.html\n", "\n", "Es ist auch möglich, eigene Exceptions zu definieren." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class CrazyException(Exception):\n", " def __init__(self, msg):\n", " super(CrazyException, self).__init__(msg)\n", " def __str__(self):\n", " return \"This is crazy! %s\" % super(CrazyException, self).args" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is crazy! Calculation error.\n" ] } ], "source": [ "ex = CrazyException(\"Calculation error.\")\n", "print(ex)" ] } ], "metadata": { "kernelspec": { "display_name": "Anaconda (Python 3)", "language": "python", "name": "anaconda3" }, "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.5.1" } }, "nbformat": 4, "nbformat_minor": 0 }