#!/usr/bin/env python # coding: utf-8 # # Python Kurzeinführung # # [Python](http://www.python.org) ([Wikipedia](http://en.wikipedia.org/wiki/Python_%28programming_language%29)) # ist eine # [multiparadigmatische](http://en.wikipedia.org/wiki/Programming_paradigm#Multi-paradigm) # ([imperativ](http://en.wikipedia.org/wiki/Imperative_programming), # [prozedural](http://en.wikipedia.org/wiki/Procedural_programming), # [funktional](http://en.wikipedia.org/wiki/Functional_programming), # und # [objektorientierte](http://en.wikipedia.org/wiki/Object-oriented_programming)) Programmiersprache. # Sie wurde 1991 von [Guido van Rossum](http://en.wikipedia.org/wiki/Guido_van_Rossum) veröffentlicht # und wurde von [ABC](http://en.wikipedia.org/wiki/ABC_%28programming_language%29), # Java, Haskell und anderen Sprachen maßgeblich beeinflusst. # Seit bald 10 Jahren gehört sie zu den am weitesten verbreiteten und flexiblesten Programmiersprachen weltweit. # Aus der Sicht der Mathematik ist die große Sammlung an mathematischen, statistischen und wissenschaftlichen # [Programmbibliotheken](http://en.wikipedia.org/wiki/Library_%28computing%29) hervorzuheben, # und darauf aufbauende Tools wie Sage erwähnenswert. # Außerdem ist Python eine exzellente Sprache zum funktionellen Kombinieren diverser Programme, Utilities und Systeme. # Der beste Weg Python kennen zu lernen ist ein Sprung ins kalte Wasser. # Ein Programm zu programmieren folgt keinen kochrezeptartigen Regeln, # sondern bedarf des kreativen Kombinierens von Konzepten, Regeln und Ideen. # Daher ist kreatives Denken und ein Schatz an Erfahrungen wichtig -- # ganz ähnlich wie das Führen von Beweisen in der Mathematik. # # Die Funktionsweise der hier vorliegenden Worksheets ist die folgende: # Die mit `In[]` gekennzeichneten Boxen sind die Eingabezellen. # In ihnen stehen in oder mehrere Zeilen Code. # Durch betätigen des Buttons oder der + Tasten wird die aktive Zelle ausgeführt. # Die Ausgabe steht darunter und ist mit `Out[n]` gekennzeichnet. # # Die folgenden Beispiele zeigen anschauliche Beispiele, # die einen ersten groben Umriss um die Funktionalität Python's liefert. # Davon neugierig gemacht, werden in der Folge die darin vorkommenden Grundprinzipien erklärt. # Keine Scheu, kopiere einzelne Zellen in ein neues IPython Notebook und fange an zu experimentieren! # ## Einfache Rechenbeispiele # In[1]: 14 + 3 * (8 - 1) # Achtung, potenziert wird mit `**`! # In[2]: banane = 3**2 + 1 print(banane) # Hierbei ist `banane` eine Variable, die auf den Wert `10` gesetzt wurde. # Das ist das Ergebnis der Auswertung des Ausdrucks `3**2 + 1`. # Abgerufen kann der Wert von `banane`, wenn es an letzter Stelle einer Code-Zelle steht, # oder durch den `print` Befehl. # In[3]: print(banane) # In[4]: banane # Für "mathematisches" Dividieren muss mindestens ein Argument eine Flißekommazahl sein; # Ganzzahldivisionen werden abgerundet! # (Ausnahme: entweder es ist Python in Version 3 **oder** mittels `from __future__ import division` wurde das modernere Verhalten importiert) # In[5]: (2.2 * 9.81) / 2 # Beide Zahlen sind Ganzzahlen, daher striktes Abrunden: # In[6]: 51 / 10 # Ist mindestens eine der beiden Zahlen eine Fließkommazahl (sichtbar an dem kleinen `.` nach der `51`), # so wird eine Fließkommadivision durchgeführt. # In[7]: 51. / 10 # Aktivieren des alternativen Verhaltens für Divisionen. # In[8]: from __future__ import division 51 / 10 # Das IPython Notebook merkt sich derweilen weiter oben definierte Variable `banane`, # solange die "Session" aktiv ist. # Kernel > Restart bzw. starten die Session neu. # `print` kann in Python 2 als Statement verwendet werden, # es geht aber auch die in Python 3 gebräuchliche Variante als Funktion. # Damit können jederzeit Zwischenergebnisse, die während des Ablaufs des Programmes passieren, ausgegeben werden. # Ansonsten wird immer nur der Wert des letzten Ausdrucks ausgegeben. # In[9]: apfel = 8.76 print(3 * banane + 2 * apfel) apfel = 9.81 print(2 * banane + apfel) # Brüche können mit `Fraction` angegeben werden # In[10]: from fractions import Fraction a = Fraction("33/31003100") b = Fraction("-9/100000100001") a * b ** 4 # Liste von Zahlen von 0 bis 9. Es ist außerdem und ganz generell so, dass bei `0` zu zählen begonnen wird und Intervalle auf der linken Seite geschlossen und auf der rechten Seite offen sind. # In[11]: range(10) # Jede dritte Zahl in $-10 \leq x < 10,\; x \in \mathbb{Z}$ # In[12]: range(-10, 10, 3) # Eine `for`-Schleife iteriert -- das heißt, sie wiederholt den darin vorhandenen Codeblock -- für alle angegebenen Werte: # In[13]: for x in range(-10, 10, 4): y = 3 * x + 1 print("x ist %3d und y ist %3d" % (x, y)) # `if`-Verzweigungen erlauben, Codeblöcke nur unter bestimmten Bedingungen auszuführen. # Das Wort `else` kann optional dazu verwendet werden, einen Codeblock bei nichterfüllung der Bedingung auszuführen. # In[14]: k = -4 if k >= 0: print("k ist positiv") else: print("k ist negativ") # Eine `for`-Schleife mit einer darin enthaltenen `if`-Bedingung. # Sie summiert alle Zahlen bis 100, die durch 3 und 7 teilbar sind, auf: # In[15]: summe = 0 for i in range(100): if i % 3 == 0 and i % 7 == 0: summe += i print(summe) # Das `import` Statement dient dazu, Funktionalitäten aus diversen Programmbibliotheken zu importieren. # # Beispiel: Die Sinusfunktion `sin` aus der `math`-Bibliothek importieren und mit Standardgenauigkeit berechnen. # In[16]: from math import sin sin(3.1415926535) # Hier wird die `sin`-Funktion mit 100 Stellen Genauigkeit durch dessen Version in der `mpmath`-Bibliothek in Sympy berechnet. # Beachte, dass `mpm` vorangestellt wird, um Vermischungen mit der schon importieren `sin` zu vermeiden. # In[17]: import sympy.mpmath as mpm mpm.mp.dps = 100 mpm.sin(mpm.mpf("3.1415926535")) # ## Symbolische Ausdrücke, Funktionen, Differenzieren # # Symbolische Ausdrücke können mit der Programmbibliothek `SymPy` erzeugt werden. # Hierfür importieren wir z.B. in einem ersten Schritt die Variable $x$ und den Operator $\sin$, # mit der die Ausdrücke aufgebaut werden. # In[18]: from sympy import sin, pi from sympy.abc import x # $f(x) := \frac{2 x}{x - \sin(x)}$ # In[19]: f = 2 * x / (x - sin(x)) f # Differenzieren nach $x$ mit `.diff(x)` und anschließendes Vereinfachen des Ausdrucks durch `.simplify()`. # In[20]: f_prime = f.diff(x).simplify() f_prime # ## Auswertung von symbolischen Ausdrücken # Hier wird das `x` in dem zuvor definierten symbolischen Ausdruck `f` mittels der Methode `.subs(, )` ersetzt. # $f(x)\Big\rvert_{x=1}=\dots$ # In[21]: f.subs(x, 1) # pi wurde weiter oben via `from sympy import pi` definiert. # # $f(x)\Big\rvert_{x=\pi}=\dots$ # In[22]: f.subs(x, pi) # Numerische Auswertung nach der Substitution durch `.evalf()` # In[23]: f.subs(x, 1).evalf() # In[24]: f.subs(x, 1).evalf(100) # ## $\LaTeX{}$-Formatierung mittels SymPy: # In[25]: from IPython.display import Math from sympy import latex # In[26]: Math(latex(f)) # In[27]: Math(latex(f_prime)) # ## Listen und Listenverarbeitung # Eine "Liste" ist eine geordnete Sammlung von Objekten. # Sie ist so ziemlich die zentralste *Datenstruktur* überhaupt. # In[28]: l1 = ["Haus", 99] l1 # In[29]: l2 = ["a", 0, "x"] l2 # In[30]: l1 + l2 # Verarbeiten von Listen mittels # # `[ for in ]` # # (genannt "list-comprehension") # In[31]: ll = [2., 2.5, 3., 5., 8.1, 10., 22.] k1 = [2*i-2 for i in ll] k1 # In[32]: [k**2 + 2*k + 1 for k in range(10)] # Zugriff auf Elemente in einer Liste -- achtung, wie schon erwähnt wird ab `0` indiziert. # In[33]: p = ["P", "y", "t", "h", "o", "n"] p[3] # Das zweit-letzte Element mittels `-2` # In[34]: p[-2] # ## Grafische Darstellungen # # Dies geschieht mittels der `matplotlib`-Bibliothek. Sie muss zur Ausgabe von Grafiken aktiviert werden: # In[35]: get_ipython().run_line_magic('matplotlib', 'inline') import matplotlib.pyplot as plt plt.rcParams["figure.figsize"] = (10,6) # ### Plotten paarweiser Punkte # # `xx` und `yy` beinhalten jeweils die x- und y-Koordinaten. # In[36]: xx = [20, 15, 11, 7.57, 9.6, 13, 21, 24, 28, 23, 20] yy = [3, 2.5, 2.3, 2.66, 3, 3.1, 2.3, 2.5, 2.8, 3, 3] plt.plot(xx, yy, "o-") plt.xlim(5, 30) plt.ylim(2, 3.3) # ### Funktionen und deren Graph # Definieren einer Funktionen mit `SymPy` und zeichnen ihres Graphen: # In[37]: from sympy import sin from sympy.abc import x sin_square = sin(x) * x**2 # In[38]: sin_square.subs(x, -2).evalf() # In[39]: sin_square.subs(x, 15).evalf() # In[40]: from sympy.plotting import plot plot(sin_square, (x, -3, 15)) # ### Interaktive Funktionen # # `@interact` führt eine Funktion mit interaktiven Argumenten (`a` und `b`) aus. # `a = (0, 20, .1)` definiert, dass der Slider von `0` bis `20` mit Schrittweite `0.1` gehen soll. # Das `a = 10` in der Funktion `damped_oscillation` selbst ist der initiale default Wert, # den der Slider am Anfang bekommen soll. # In[41]: from IPython.html.widgets import interact from sympy.abc import x from sympy import exp, cos from sympy.plotting import plot @interact(a = (0, 20, .1), b = (0, 3, .1)) def damped_oscillation(a = 10, b = .5): f2 = a * exp(-b * x) * cos(a * x) / a plot(f2, (x, 0, 10), ylim=(-1, 1)) # ### Parametrischer Plot # Die Matrix $\bigl(\begin{smallmatrix}a&b\\ c&d\end{smallmatrix} \bigr)$ beinhaltet die Parameter, # und wird mit dem von $\phi$ abhängigen Vektor multipliziert. # $$f(\phi) := # \begin{pmatrix} # a & b \\ c & d # \end{pmatrix} # \cdot \log(1+\phi) # \begin{pmatrix} # \sin(\phi) \\ \cos(\phi) # \end{pmatrix} # \qquad \phi \in [0,\,8 \pi]$$ # In[42]: from IPython.html.widgets import interact import numpy as np @interact(a=(-2, 2, .1), b =(-2, 2, .1), c=(-2, 2, .1), d=(-2, 2, .1)) def elliptic_plot(a = 1., b = 0, c = 0, d = -1): phi = np.linspace(0, 8 * np.pi, 1000) m = np.array([[a, b], [c, d]]) v = np.c_[np.sin(phi), np.cos(phi)].T r = np.log1p(phi) xx, yy = m.dot(r * v) plt.plot(xx, yy) plt.grid() plt.ylim(-4, 4) plt.xlim(-4, 4) # ### Histogram # [Gauss](https://docs.python.org/2/library/random.html#random.gauss)-Glocke für $\mu = 2$ und $\sigma = .5$ # In[43]: from random import gauss data = [gauss(2, .5) for i in range(10000)] # In[44]: _ = plt.hist(data, 20, color="grey")