{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Konzept 1: Ausdrücke und Variablen" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ausdrücke\n", "\n", "Eine ganz einfache Variante sind einfache Rechnungen.\n", "In jeder Zelle stehen in oder mehrere Zeilen Programmcode, die mittels `Shift+Return` ausgewertet werden.\n", "(`Ctrl+Return` gibt es auch, es wird hierbei nicht zur nächsten Zelle vorwärts gesprungen)\n", "z.B.:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "11" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3 + 8" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "8.0" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5 + (1 + 5) / 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apropos Sprachversionen: aus \"mathematischer\" Sicht gibt es bei Divisionen einen entscheidenden Unterschied. In Version 2 ist die Division mit \"`/`\" abrundend auf die nächste Ganzzahl, während in Verion 3 die handelsübliche Interpretation einer Division verwendet wird (abrundend ist \"`//`\").\n", "\n", "Mittels \"`from __future__ import division`\" kann in Version 2 das Verhalten von Version 3 erzwungen werden:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2.25" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "9 / 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Im Allgmeinen ist es eine gute Idee, diesen Import immer zu aktivieren.\n", "\n", "Striktes Abrunden:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "9 // 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "... und Modulorechnungen mit `%`:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "9 % 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Zahlentypen" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(123)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(1.23)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(5.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Brüche mit `Fraction`" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2673/38275585202254501783218213917955539030103719395100\n" ] } ], "source": [ "from fractions import Fraction\n", "a = Fraction(\"33/31003100\")\n", "b = Fraction(\"-9/100000100001\")\n", "print(a * b ** 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dezimalzahlen, die nicht die übliche in dem Computer eingebaute fixe\n", "[IEEE 754-2008](http://en.wikipedia.org/wiki/IEEE_floating_point) Genauigkeit haben und eventuelle Rundungsfehler erzeugen,\n", "sondern [IEEE 854-1987](http://en.wikipedia.org/wiki/IEEE_854-1987) für strengere Genauigkeit folgen, mittels `Decimal`:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4.440892098500626e-16\n" ] } ], "source": [ "print(1.1 + 2.2 - 3.3)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.0\n" ] } ], "source": [ "from decimal import Decimal\n", "u = Decimal(\"1.1\") + Decimal(\"2.2\")\n", "v = Decimal(\"-3.3\")\n", "print(u + v)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`mpmath` erlaubt, analytische Ausdrücke auf höherer Genauigkeit auszuwerten" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import mpmath as mpm\n", "mpm.mp.dps = 100" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "mpf('0.999999999999999997346938775510204087172011661807580164514785506039150372463854346403284314358813079585')" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = mpm.mpf(\"49.00000000000000001\")\n", "b = mpm.mpf( \"7.00000000000000001\")\n", "a / b**2" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "mpf('0.00000000008979323846264338327938221965910388125990692946182694867743526330407406677351504727435623041438215811254')" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mpm.sin(mpm.mpf(\"3.1415926535\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Intervallzahlen mit `mpmath`'s `mpi`" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1.0, 2.0] * [3.0, 4.5] = [3.0, 9.0]\n" ] } ], "source": [ "x = mpm.mpi(\"1\", \"2\")\n", "y = mpm.mpi(\"3\", \"4.5\")\n", "z = x * y\n", "print(x, \"*\", y, \"=\", z)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Zeichenketten (Strings)\n", "\n", "Eine ganz wichtige Kategorie von Ausdrücken sind Zeichenketten (engl. \"strings\").\n", "Diese werden zwischen einfachen oder doppelten Anführungszeichen eingegeben.\n", "Später mehr dazu (siehe \"Konzept 5: Datenstrukturen\"), hier nur ein einfaches Beispiel:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'dies ist eine Zeichenkette'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"dies ist eine Zeichenkette\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Zusammenführen mehrerer Strings" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'String1String2'" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"String1\" + \"String2\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Einfügen eines Strings in eine bestehende Zeichenkette (an der Stelle `%s`).\n", "Beachte, einfache Anführungszeichen können innerhalb doppelter Anführungszeichen verwendet werden (und umgekehrt)." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "\"Der Name 'Hubert' ist männlich.\"" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"Der Name '%s' ist männlich.\" % \"Hubert\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Formatieren einer Fließkommazahl in einem String (hier mit 3 Nachkommastellen):" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'Das Wasser hat 3.142 °C'" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"Das Wasser hat %.3f °C\" % 3.1415926535" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Die Methode `.format()` erledigt [komplexere Formatierungsaufgaben](https://docs.python.org/2/library/string.html#formatspec):\n", "\n", "* `{:>20s}`: string-format, auf mindestens 20 Zeichen breite mit Leerzeichen auffüllen, und \"`>`\" macht es rechtsbündig,\n", "* `{abc:.4f}`: formatiert das Argument `abc` als floating-point Zahl mit 4 Nachkommastellen." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "' test: 42.0000'" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"{:>20s}: {abc:.4f}\".format(\"test\", abc = 42)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Vergleichsoperatoren\n", "\n", "Einer der wichtigsten Typen von Ausdrücken sind Vergleichsoperatoren.\n", "Das sind tests auf \n", "\n", "* Identität (\"`is`\") -- wo die zu vergleichenden Objekte exakt ident sein müssen.\n", " Das heißt, sie sind sich nicht nur ähnlich, sondern liegen jeweils tatsächlich in derselben Stelle des Speichers.\n", "* Equvivalenz (\"`==`\") -- hier wird, abhängig von der Vergleichsoperation (!), die Gleichheit festgestellt.\n", "* Relation (\"`<`\", \"`>=`\", ...) -- test auf Ungleichheit, ebenfalls von der konkreten Implementation des Vergleichsoperators abhängig." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"abc\" is \"abc\"" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6 == 2 * 3" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6 > 10" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Es ist auch oft möglich -- wenn sinnvoll -- unterschiedliche Typen zu vergleichen:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6.1 < 10 # float mit int" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variablen\n", "\n", "Die Quintessenz eines Programmes ist dessen Flexibilität gegenüber Eingaben.\n", "Wäre die Eingabe fest vorgegeben,\n", "gäbe es nur wenig Gründe das Programm mehr als nur einmal aufzurufen!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "_Quiz:_ Gib einen Grund an, warum ein Programm ohne Dateneingabe mehrmals aufgerufen werden könnte?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Antwort: " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Zuweisungen passieren so, dass in der Zeile zuerst eine Variable steht,\n", "dann ein Gleichzeitszeichen, und dann ein Ausdruck der Ausgewertet wird.\n", "Hinweis: Der Wert der Variablen `x` ist in der darunterliegenden Zelle weiterhin verfügbar." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "21" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 4\n", "5 * x + 1" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "-4" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = 2 * x + 1\n", "9 - y - x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Wichtig ist, dass die Zuweisung an `x` vor dessen Verwendung in der zweiten Zelle passiert.\n", "Eine Variable ohne vorheriger Zuweisung erzeugt einen Fehler:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "ename": "NameError", "evalue": "name 'p' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mp\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m23\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'p' is not defined" ] } ], "source": [ "p + 23" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Variablen können (und sollen meistens) mehr als einen Buchstaben haben.\n", "Dabei sind Groß- und Kleinbuchstaben und Zahlen ab dem zweiten Zeichen erlaubt.\n", "Als einziges Sonderzeichen gibt es den `_` Unterstrich.\n", "(das gilt für Python in der Sprachversion 2, Version 3 erlaubt mehr Zeichen.)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12.87\n" ] } ], "source": [ "apfel_preis = 0.99\n", "stueck = 13\n", "preis = stueck * apfel_preis\n", "print(preis)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Die vorhergehende Zelle definiert mehrere Variablen und berechnet den Preis des Einkaufs.\n", "Das Wort `print` mit anschließenden Klammern gibt den Inhalt der Variablen `preis` aus\n", "und ist ein Beispiel für den Aufruf einer Funktion." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Wichtig**: Es gibt zwischen den Programmiersprachen subtile Unterschiede,\n", "wie genau die Bedeutung einer Variablen ist und wie sie sich im Kontext von Ausdrücken verhält.\n", "\n", "Bezüglich Python kann man es sich am besten so vorstellen,\n", "dass ein Variablenname das Etikett zur Beschriftung einer Box (dem \"Wert\") ist." ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/svg+xml": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " image/svg+xml\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " 42\n", " \n", " \n", " \n", " \n", " 42\n", " \n", " \n", " a\n", " \n", " \n", " \n", " \n", " 42\n", " \n", " \n", " a\n", " \n", " b\n", " \n", " a=42\n", " b=a\n", " 42\n", " \n", "" ], "text/plain": [ "" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import SVG\n", "from os.path import join\n", "SVG(filename=join('res', 'variable.svg'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Es kann nämlich auch folgendes passieren:\n", "\n", "* Eine Box hat mehr als nur ein Label, sprich, zwei Variablen zeigen auf genau denselben Wert.\n", "* Im konkreten Fall von `b=a`, wird zuerst die rechte Seite auf das jeweilige Objekt hinter `a` \"dereferenziert\", und dann `b` zugeweisen.\n", "* Es existiert ein Label, das auf nichts Zeigt (das ist in Python der \"`None`\" Wert)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = 42\n", "b = a" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "42" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "42" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Der eingebaute Befehl `id` gibt die interne Speicheradresse des Wertes zurück.\n", "Dieser ist hier genau gleich, da es sich um die identischen Objekte im Speicher handelt.\n", "Dies funktioniert mit beliebigen Werten,\n", "jedoch instanzieren wir hier zwei minimale Grundobjekte zur besseren Veranschaulichung:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": true }, "outputs": [], "source": [ "a = object()\n", "b = object()" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(140035719422960, 140035719423008)" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "id(a), id(b)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a is b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Namensänderung: Das Objekt hinter `a` wird mittels `b = a` nun auch `b` genannt.\n", "Das ursprüngliche Objekt hinter `b` verschwindet in den Weiten des Arbeitsspeichers ([garbage collection](http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29)), da es keinen Namen mehr hat." ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": true }, "outputs": [], "source": [ "b = a" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(140035719422960, 140035719422960)" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "id(a), id(b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Die Zuweisung von `a` an `b` hat somit bewirkt, dass der Wert von `a` die Bezeichung `b` bekommen hat.\n", "Es ist also weder der Wert von `a` nach `b` gewandert,\n", "noch wurde eine Kopie erzeugt.\n", "\n", "Letzteres kann bei komplexeren Objekten zu subtilen Fehlern führen, aufpassen!" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a is b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "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.2" } }, "nbformat": 4, "nbformat_minor": 0 }