Zum Inhalt springen

Ing Mathematik: Python

Aus Wikibooks


Hallo Welt und allgemeine Hinweise

[Bearbeiten]

Was ist Python

[Bearbeiten]
  • Python ist eine universelle höhere Programmiersprache.
  • Python ist objektorientiert.
  • Python ist Open-Source (Python Software Foundation License).
  • Python ist für viele Betriebssysteme erhältlich (z.B. für Linux, MS Windows, macOS).
  • Python ist ein Interpreter.
  • Python ist durch Module fast beliebig erweiterbar.
  • Python als Programmiersprache ist case-sensitive - d.h. Groß- und Kleinschreibung ist relevant bei der Eingabe von Befehlen.
Wikipedia hat einen Artikel zum Thema:

.

Python installieren

[Bearbeiten]

MS Windows

[Bearbeiten]

Laden Sie das aktuelle Python-Paket von der Webseite [1] herunter. Weiter geht es wie bei jedem anderen größeren zu installierenden Programm. Einfach das Installationsprogramm im Explorer doppelklicken und den Anweisungen des Setup-Programmes folgen.

Linux

[Bearbeiten]

Entweder ist Python bereits standardmäßig installiert, ansonsten ist die Installation mittels Paketmanagementsystem einfach möglich.

Python starten

[Bearbeiten]

MS Windows

[Bearbeiten]

Das Icon für das Python-Programm doppelklicken. Und schon startet das Programm.

Python im interaktiven Modus präsentiert sich dann so:

Alternativ kann das Programm auch über die Eingabeaufforderung oder die PowerShell gestartet werden.

Linux

[Bearbeiten]

Tippen Sie einfach das Wort „python“ in einem Linux-Terminal ein, schließen den Befehl mit der RETURN-Taste ab, und schon startet Python im interaktiven Modus.

Es gibt auch noch andere Möglichkeiten Python zwecks Programmausführung zu starten, z. B. den Shebang (#!/usr/bin/python) am Beginn eines Python-Scripts. Dann kann das Script mit ./Script.py ausgeführt werden. Oder es wird in einen Pfad verschoben, in dem sich ausführbare Programme generell befinden (echo $PATH). Das Script kann dann wie ein normales Programm ohne weitere Angaben mit Script.py gestartet werden (die Berechtigungen zum Ausführen der Datei müssen natürlich noch richtig gesetzt werden).

Ein paar Worte zur Erklärung

[Bearbeiten]

Getestet wurden die Beispiele unter dem Betriebssystem MS Windows 10 mit der Python-Version 3.12.0, teilweise auch mit 3.12.2. An Beliebtheit rangiert Python mit Stand November 2024 mit einem Rating von 22,85% an 1. Stelle (lt. TPCI - TIOBE Programming Community Index). Der Name "Python" rührt von der Komikertruppe  Monty Python her. Die Icons für Python (z.B. Python selbst, Eric IDE, IDLE) sind aber durch die Python-Schlangenart symbolisiert.

Ein erstes Programm

[Bearbeiten]

Kommentare werden in Python mit der Raute (#) eingeleitet. Sie werden vom Python-Interpreter ignoriert. Text kann mit der print-Funktion ausgegeben werden. Starten Sie Python und geben sie folgende Anweisungen zeilenweise ein

>>> # Das ist ein Kommentar
>>> print("Hallo Welt!")

Als Ergebnis erhalten Sie

Hallo Welt!

Der Prompt (>>>) ist selbstverständlich nicht einzutippen, sondern wird vom Python-System geliefert.

Strings können in Python entweder in Anführungszeichen (") gesetzt werden oder in Hochkommatas('). In diesem Text wird die erste Variante bevorzugt eingesetzt.

Im Gegensatz zu Julia ist es hier egal, ob zwischen print und der öffnenden Klammer Leerzeichen stehen.

Python als Taschenrechner

[Bearbeiten]

Allgemeines

[Bearbeiten]

Wir wollen 3 * 5 berechnen. Dazu starten wir Python im interaktiven Modus. Geben Sie dann die Formel

>>> 3 * 5

ein, drücken die Taste ENTER/RETURN und erhalten als Ergebnis

15

Auch kompliziertere Ausdrücke sind möglich. Beispielsweise mit Winkelfunktionen, Quadratwurzeln etc. Wir wollen nun den Ausdruck berechnen :

>>> import math
>>> math.sin(math.sqrt(15))
-0.6679052983383519

Als erstes wird das math-Modul importiert. Dann wird der mathematische Ausdruck berechnet.

Beenden lässt sich das Python-Programm durch Eingabe von exit() (und natürlich ist zur Bestätigung die RETURN-Taste zu drücken).

Die Hilfefunktion von Python

[Bearbeiten]

Bei Eingabe der Anweisung help() springt Python in den Hilfemodus.

Eingabe:

>>> help()

Eingabe:

help> math.sin

Ausgabe:

Help on built-in function sin in math:

math.sin = sin(x, /)
    Return the sine of x (measured in radians).

Für die komplette Python-Dokumentation siehe [2]. Verlassen kann man den Hilfemodus durch das Drücken von STRG-C.

Aufgaben

[Bearbeiten]
  • Erkunden Sie die Tangensfunktion "tan" mittels Python-Hilfe (vergessen Sie nicht das math-Modul zu importieren und das math. vor tan)
  • Berechnen Sie mit Python den Ausdruck . Siehe für die Exponentialfunktion im Python-Hilfesystem auch den Befehl math.exp. Alternativ kann auch die Konstante math.e eingesetzt werden. Potenzieren kann man bei Python mit dem **-Operator (z.B. 2**3 = 8). Für gibt es math.pi.

Python als Scriptsprache

[Bearbeiten]

Häufig wird man aber kompliziertere Anweisungsfolgen verarbeiten müssen. Diese will man normalerweise nicht jedesmal neu eingeben, sondern in einer Datei speichern und diese Datei dann zur Ausführung bringen. Speichern Sie dazu folgenden Code in einer Textdatei, z.B. unter MS Windows als c:\tmp\test1.py

# Das ist ein Kommentar
print("Hallo Welt!")

Python-Dateien werden mit der Dateiendung .py versehen. Achten Sie darauf, dass vor dem print keine Leerzeichen vorhanden sind. Das ist eine Python-Eigenheit. Wie wir später sehen werden, nutzt Python Einrückungen als syntaktisches Mittel, z.B. um bei Schleifen den Schleifenkörper zu kennzeichnen.

Danach bringen Sie die Skriptdatei test1.py (sozusagen das Hauptprogramm) folgendermaßen zur Ausführung:

1) Starten Sie unter MS Windows die Eingabeaufforderung (oder alternativ auch die Windows PowerShell). Das sieht dann etwa so aus:

Microsoft Windows [Version 10.0.19045.3693]
(c) Microsoft Corporation. Alle Rechte vorbehalten.

C:\Users\xyz>
Falls jemand nicht weiß, wie man die Eingabeaufforderung startet: Eine Möglichkeit ist, einfach in der Taskleiste von Windows das "Start"-Symbol  ()  mit der rechten Maustaste anklicken. "Ausführen" auswählen (oder alternativ für die PowerShell den Eintrag "Windows PowerShell"). Im sich öffnenden Dialogfenster gibt man in die "Öffnen"-Zeile das Wort cmd ein und mit "OK" wird das Ganze bestätigt.

2) Wechseln Sie mittels cd c:\tmp in das Verzeichnis c:\tmp

3) Angenommen, Sie haben Python unter dem Pfad c:\devel\Python\ installiert. Starten Sie das Programm so (der Prompt c:\tmp>ist natürlich nicht mit einzutippen):

c:\tmp>c:\devel\Python\python.exe test1.py

4) Wie erwartet ergibt sich folgende Ausgabe am Bildschirm

Hallo Welt!

Variablen

[Bearbeiten]

Variablenbezeichner können aus Buchstaben (A-Za-z), Ziffern (0-9) und Underscores (_) bestehen, dürfen aber nicht mit einer Zahl beginnen. Führende Underscores haben u.a. im Kontext mit der Objektorientierten Programmierung eine spezielle Bedeutung und sollten nicht für "normale" Variablenbezeichner verwendet werden.

Gültige Variablenbezeichner wären also:

xyz
x1
_wert
name_anzahl

Es gibt in Python etliche Schlüsselwörter (z.B. for, if oder return). Diese dürfen nicht als eigene Variablenbezeichner verwendet werden. Eine Liste aller Schlüsselwörter liefert das Script

import keyword
print(keyword.kwlist)

Übung: Speichern Sie dieses Script in eine Datei, z.B. in c:\tmp\test1.py. Führen Sie diese Datei aus, um die Liste der Schlüsselwörter auszugeben.

Da Python case-sensitiv ist, repräsentieren folgende Bezeichner verschiedene Variablen:

xyz
XYZ
xYz

Werte werden an Variablen mittels Gleich-Zeichen (=) zugewiesen. Im Folgenden wird der Code immer in der Datei c:\tmp\test1.py gespeichert.

x = 5
y = 10
z = x*y
print(z)

Bringen Sie die Datei test1.py zur Ausführung so erhalten Sie folgende Bildschirmausgabe

50

Sie können auch mehrere Anweisungen in einer Zeile durch Semikolon getrennt schreiben. Dies führt aber zu unübersichtlichem Code.

x = 5; y = 10; z = x*y; print(z)

Ausgabe:

50

Auch aus der Programmiersprache C/C++ oder Java bekannte Konstrukte können Sie verwenden, z.B.

x = 5
# x = x - 2
x -= 2
print(x)

Bildschirmausgabe:

3

Beachten Sie, dass mit dem =-Zeichen eine Wertezuweisung durchgeführt wird. Dies ist nicht äquivalent zum mathematischen =-Zeichen, wie am vorigen Beispiel zu ersehen ist.

Variablen sind nicht an einen bestimmten Datentyp gebunden, folgendes ist mit Python problemlos möglich:

import math
wert = 10
print(wert)
wert = 35.5
print(wert)
wert = "Hallo"
print(wert)
wert = math.pi
print(wert)

Ausgabe:

10
35.5
Hallo
3.141592653589793

Physische und logische Zeilen

[Bearbeiten]

In Python muss eine Anweisung in einer logischen Zeile Platz finden. Wird eine Anweisung aber zu lang für eine Zeile, dann kann sie in mehrere physische Zeilen unterteilt werden. Dies kann einerseits durch einen Backslash am Ende einer Zeile geschehen, z.B.

a = 2 + \
5

Dies stellt eine logische Zeile dar, die in zwei physische Zeilen unterbrochen ist.

Geklammerte Ausdrücke werden automatisch zu einer logischen Zeile verbunden, z.B.

a = (2 + 
5)

Achtung: Im ersten Beispiel darf nach dem Backslash nichts mehr stehen, auch kein Kommentar. Dies trifft im zweiten Bespiel nicht zu, hier könnte noch ein Kommentar folgen, z.B.

a = (2 +    # Kommentar 
5)

Auch für Strings gibt es Möglichkeiten, diese auf mehrere Zeilen aufzuspalten.

# Kurzer String
str1 = "ABC"

# Langer String
str2 = """Hallo Welt,
Grüetzi Schwyzer,
Servus an alle"""

# Backslash
str3 = "UVW\
XYZ"

print(str1)
print(str2)
print(str3)

Ausgabe:

ABC
Hallo Welt,
Grüetzi Schwyzer,
Servus an alle
UVWXYZ

Hexadezimale, oktale, binäre und andere Zahlen

[Bearbeiten]
d = 1050         # Dezimalzahl
h = 0xAA2        # Hexadezimalzahl
o = 0o12         # Oktalzahl
b = 0b100001101  # Binärzahl

print(d)
print(h)
print(o)
print(b)

Ausgabe:

1050
2722
10
269

Sie können auch dezimale in hexadezimale Zahlen umwandeln, usw.:

h = hex(1050)    # Dezimalzahl -> Hexadezimalzahl
b = bin(1050)    # Dezimalzahl -> Binärzahl
o = oct(1050)    # Dezimalzahl -> Oktalzahl
print(h)
print(b)
print(o)

Ausgabe:

0x41a
0b10000011010
0o2032

Gegeben sei die Zahl 121 zur Basis 3. Diese soll in eine Dezimalzahl umgewandelt werden. Das kann so geschehen:

z = int("121", 3)
print(z)

Ausgabe:

16

Dass dies richtig ist, davon kann man sich folgendermaßen überzeugen:


Unicode

[Bearbeiten]

Neben den bekannten ASCII-Zeichen lassen sich Zeichen auch mittels Unicode beschreiben. Griechische Buchstaben oder komplexere mathematische Operatoren - all das sollte kein Problem sein. Siehe auch  Unicode,  Liste der Unicodeblöcke und  Unicodeblock Mathematische Operatoren. Im Folgenden werden ein paar Zeichen (Allquantor, Nabla-Operator, Existenzquantor), die man aus der Mathematik kennt, erzeugt.

ch1 = "\N{FOR ALL}"
ch2 = "\N{NABLA}"
ch3 = "\u2203"
print(ch1, ch2, ch3)

Ausgabe:

∀ ∇ ∃

Diese Ausgabe ergibt sich z.B. mit der IDLE-Shell oder mit Cygwin. Beim Ausführen über die Windows-Eingabeaufforderung oder Windows PowerShell erfolgt keine korrekte Darstellung. IDLE ist die mit Python mitgelieferte IDE (Integrated Development Environment, Integrierte Entwicklungsumgebung). Gegen Ende dieses Textes wird IDLE kurz beschrieben. Das Problem mit der Windows Eingabeaufforderung lässt sich aber umgehen. Man muss nur eine Schriftart auswählen, die die Zeichen kennt, z.B. "DejaVu Sans Mono". Dazu klicken Sie einfach bei der Eingabeaufforderung mit der rechten Maustaste oben auf die weiße Leiste und wählen im aufpoppenden Fenster den Menüpunkt "Eigenschaften". Es öffnet sich ein Dialogfenster. Über den Reiter "Schriftart" lässt sich nun die Schriftart einstellen.

Verzweigungen

[Bearbeiten]

Die IF-Verzweigung ist aus anderen Programmiersprachen bereits bekannt. In Pseudocode lässt sie sich folgendermaßen darstellen:

WENN bedingung TRUE
  führe block1 aus
SONST
  führe block2 aus
ENDE 

In Python gibt es keinen expliziten ENDE-Kennzeichner. Stattdessen wird der Code durch Einrückungen strukturiert. Alles mit der gleichen Einrückungstiefe gehört zum selben Block. Dies zeichnet Python vor anderen Programmiersprachen aus.

Die test1.py-Datei laute also wie folgt:

x = 5

if x < 4:
  print("x ist kleiner als 4")
else:
  print("Der else-Zweig wird ausgefuehrt")
  print("x ist groesser oder gleich 4")  

Ausgabe:

Der else-Zweig wird ausgefuehrt
x ist groesser oder gleich 4

Man achte auch auf die Doppelpunkte in der if- und else-Zeile. Darauf vergisst man gerne, wenn man von anderen Programmiersprachen kommt.

Folgendes wäre in Python ein Fehler (genauer gesagt ein IndentationError).

x = 5

if x < 4:
  print("x ist kleiner als 4")
else:
  print("Der else-Zweig wird ausgefuehrt")
    print("x ist groesser oder gleich 4")  

Auch Nachstehendes würde nicht zum gewünschten Ergebnis führen (löst aber keine Fehlermeldung aus). Der letzte print-Befehl ist schon außerhalb der IF-ELSE-Verzweigung.

x = 3

if x < 4:
  print("x ist kleiner als 4")
else:
  print("Der else-Zweig wird ausgefuehrt")
print("x ist groesser oder gleich 4")

Ausgabe:

x ist kleiner als 4
x ist groesser oder gleich 4

Python kennt eine Reihe von Vergleichs- und Verknüpfungsoperatoren:

   <, <= ... kleiner (gleich)
   >, >= ... größer (gleich)
   == ... gleich
   != ... ungleich
   is ... identisch
   is not ... nicht identisch
   and ... AND
   or ... OR
   not ... NOT

Beispielsweise:

a = 5
b = 9

if a<=10 and b!=7:
  print("OK")
else
  print("Nicht OK")

Ausgabe:

OK

Der else-Block kann übrigens auch ersatzlos entfallen.

Mehrfache Verzweigungen werden durch das elif-Konstrukt erstellt.

a = 14

if a<=10:   
  print("<=5")
elif a>11 and a<15:
  print("11 bis 15")
elif a>16 and a<20:
  print("16 bis 20")
else:
  print(">=20")

Ausgabe:

11 bis 15

In Python gibt es auch die Schlüsselwörter True (für wahr) und False (für falsch). Man beachte, dass sie mit Großbuchstaben beginnen. Andere Schreibweisen wären ein Fehler. Sie gehören zum Datentyp bool. Ihnen sind auch die Zahlen 1 und 0 zugewiesen.

match

[Bearbeiten]

Ab Python 3.10 gibt es auch die match-Anweisung. Dies ist das Python-Pendant für die switch-Anweisung in anderen Programmiersprachen.

x = "Hello"

match x:
    case "Servus" | "Ciao":         # or
        print("Servus an alle")
    case "Grüetzi":
        print("Grüetzi Schwyzer")  
    case _:                         # other
        print("Hallo Welt")

Ausgabe:

Hallo Welt

Für nähere Details siehe z.B. [3], [4] oder [5].

Schleifen

[Bearbeiten]

while

[Bearbeiten]

Die WHILE-Schleife ist kopfgesteuert. Sie funktioniert wie aus anderen Programmiersprachen bekannt.

In Pseudocode:

SOLANGE bedingung TRUE
  führe block aus
ENDE

In Python:

x = 0

while x <= 10:
  print(x)
  x += 1

Ausgabe:

0
1
2
3
4
5
6
7
8
9
10
for x in range(6):
  print(x*2)

Ausgabe:

0
2
4
6
8
10

Die Schleife lauft von 0 bis 5. Ausgegeben wird jeweils der Wert x*2. Aquivalent kann diese Schleife auch so geschrieben werden:

for x in range(0, 11, 2):
  print(x)

Die Ausgabe ist wie oben. Der Startwert sei 0, der Endwert ist 11-1 und die Schrittweite ist 2.

Ein anderes Beispiel sei

for x in "text":
  print(x)

Ausgabe:

t
e
x
t

Schleifen abbrechen

[Bearbeiten]

break

[Bearbeiten]

break bricht die Schleife ab und setzt mit dem nächsten Befehl außerhalb der Schleife fort.

for var in range(100):
  print(var) 
  if var == 5:
    break

Ausgabe:

0
1
2
3
4
5

continue

[Bearbeiten]

continue bricht den aktuellen Schleifendurchlauf ab und setzt mit dem nächsten Schleifendurchlauf fort.

for var in range (11):
  if var == 5:
    continue
  print(var)

Ausgabe:

0
1
2 
3
4
6
7
8
9
10

try - except

[Bearbeiten]
try:
    z1 = 12 / 0
    print(z1)
except ZeroDivisionError:
    print("Das Ergebnis ist unendlich")
except:
    print("Kann nicht berechnet werden!")
    print("Bitte die Formel korrigieren!")

Ausgabe:

Das Ergebnis ist unendlich

Es wird versucht, eine Zahl durch Null zu dividieren. Das ist nicht möglich, es wird eine Ausnahme ausgelöst. Das Programm springt daher in den except-ZeroDivisionError-Block und führt die dort gelisteten Anweisungen aus (in unserem Fall eine print-Anweisung). Würden wir dieses Programm ohne try-except ausführen, so ergibt sich aus

z1 = 12 / 0
print(z1)

folgende Fehlermeldung und ein unmittelbarer Programmabbruch

Traceback (most recent call last):
  File "C:\tmp\test1.py", line 1, in <module>
    z1 = 12 / 0
ZeroDivisionError: division by zero

Mit dem try-except-Mechanismus können also Ausnahmen oder Fehler aufgefangen und behandelt werden. In unserem Beispiel ist das eher trivial, aber bei größeren Programmen kann das durchaus Sinn machen.

Funktionen

[Bearbeiten]

Aufrufen von Funktionen

[Bearbeiten]

Funktionen sind uns im Rahmen dieses Kurses schon zuhauf begegnet. Sei es die print()-, die math.sin()- oder die hex()-Funktion. All diese Funktionen werden von Python zur Verfügung gestellt, ohne dass man sie explizit programmieren müsste. Aufgerufen werden diese Funktionen, indem man ihren Namen eintippt, gefolgt von runden Klammern. In diesen Klammern können noch Argumente übergeben werden. Auch Rückgabewerte sind möglich.

Funktionen selber schreiben

[Bearbeiten]

Funktionen werden mit dem def-Schlüsselwort (man definiert die Funktion) eingeleitet, danach folgt der Funktionsname, danach wiederum runde Klammern, in denen formale Argumente stehen können. Abgeschlossen wird die def-Zeile mit einem Doppelpunkt. Danach folgt der Funktionskörper. Dieser Funktionskörper muss wiederum eingerückt werden (wie von den Verzweigungen und Schleifen bekannt). Aufgerufen wird diese Funktion, indem man ihren Funktionsnamen eingibt, gefolgt von runden Klammern (ggf. mit den aktuellen Parametern). Z.B.

# Funktion definieren
def halloWelt(i):
    # i ... beliebige Ganzzahl
    print("Hallo " * i, end="")
    print("Welt!")
   
# Funktion aufrufen
halloWelt(3)

Ausgabe:

Hallo Hallo Hallo Welt!

Unterschied zwischen formalen und aktuellen Parametern:

Aktuelle Parameter werden auch Argumente genannt.

Rückgabe von Funktionswerten:

# Funktion definieren
def mathFunc(a, b):
    r1 = a + b
    r2 = a * b
    return r1, r2
   
# Funktion aufrufen
a, b = mathFunc(3, 5)

# Ausgabe der zurückgegebenen Werte
print(a)
print(b)

Ausgabe:

8
15

Vorgabeparameter, z.B.:

def mathFunc(a=10, b=20):
    r1 = a + b
    r2 = a * b
    return r1, r2
   
a, b = mathFunc(3, 5)
print(a)
print(b)

a, b = mathFunc(5)
print(a)
print(b)

a, b = mathFunc(b=6)
print(a)
print(b)

Ausgabe:

8
15
25
100
16
60

Lambda-Funktionen

[Bearbeiten]
print((lambda a, b: a*b) (3, 5))

Ausgabe:

15

Eingeleitet wird eine Lambda-Funktion (auch Lambda-Form, Lambda-Operator oder anonyme Funktion genannt) mit dem Schlüsselwort lambda. Es folgen die formalen Argumente, danach ein Doppelpunkt, die Berechnungsvorschrift und ggf. abschliessend in Klammern die aktuellen Parameter.

Man kann einer Lambda-Funktion auch einen Funktionsnamen geben und die Funktion über diesen Namen aufrufen, z.B.

prod = lambda a, b: a*b
print(prod(3, 5))

Als Ausgabe wird wieder die Zahl 15 geliefert.

Rekursive Funktionen

[Bearbeiten]

Funktionen können wiederum andere Funktionen aufrufen. Von einem rekursiven Funktionsaufruf spricht man, wenn die aufgerufene Funktion gleich der aufrufenden ist.

def printFunc(i):
    if (i >= 5):
        return 
    else:
        print("Hallo Welt")
        printFunc(i+1)
        
printFunc(1)

Ausgabe:

Hallo Welt
Hallo Welt
Hallo Welt
Hallo Welt

Funktionsannotationen

[Bearbeiten]

Python ist sehr flexibel, was Typen angeht. Im Vorhergehenden haben wir generell keine Typangaben gemacht. Will man Typen angeben, so bietet Python das Konzept der Funktionsannotation.

def calcFunc(a:int, b:int) -> int:
   return a+b, a*b
       
r1 = calcFunc(8, 9)
r2 = calcFunc(8.0, 9.0)
print(r1)
print(r2)

Ausgabe:

(17, 72)
(17.0, 72.0)

Jetzt sieht man auf den ersten Blick, welche Typen der Programmierer im Sinn hatte, als er die Funktion erstellte. Das Problem dabei ist nur, dass es Python ziemlich egal ist, welche Typen man in Endeffekt eingibt. Im obigen Beispiel können statt Integer-Typen auch Float-Typen eingegeben werden.

Tupel, Listen und andere

[Bearbeiten]
Datentypen und Strukturen

Tupel, Listen und einige andere sind Datenstrukturen oder Sequenzen.

Listen (z.B. eine Einkaufsliste) sind veränderbar (mutable). Ein Tupel kann dagegen nicht verändert werden (immutable). Listen werden beim Anlegen in eckige Klammern eingeschlossen, Tupel in runde Klammern. Beim Tupel können die Klammern auch weggelassen werden. Ein Tupel mit nur einem Element muss mit einem Beistrich abgeschlossen werden. Der Grund ist, dass Python sonst nicht entscheiden kann, ob ein Tupel angelegt werden soll, oder nur ein geklammerter Wert. Nachfolgend werden einige Operationen mit Listen und Tupel dargestellt.

# Liste und Tupel
liste = [1, 2, "Hallo"]
tupel = (1, 2, "Hallo") 

# Ausgabe von liste und tupel
print(liste)
print(tupel)

# Ausgabe von Einzelelementen
print(liste[1])
print(tupel[2])

# Element an Liste anhängen und einfügen 
liste.append(55)
liste.insert(4, "Welt")
print(liste)

# Element aus Liste entfernen
liste.remove(1)
print(liste)

# einige weitere Beispiele
liste2 = [1,]
tupel2 = 1, 2
tupel3 = (1,) 
print(liste2)
print(tupel2)
print(tupel3)

Ausgabe:

[1, 2, 'Hallo']
(1, 2, 'Hallo')
2
Hallo
[1, 2, 'Hallo', 55, 'Welt']
[2, 'Hallo', 55, 'Welt']
[1]
(1, 2)
(1,)

Zu den Datenstrukturen gehören weiters auch Mengen und Dictionaries. Mengen sind von der Mathematik bekannt, sie sind ungeordnet und es kommen keine mehrfachen Elemente vor. Dictionaries sind durch Schlüssel :Wert-Paare gekennzeichnet. Mengen werden beim Anlegen wie Dictionaries in geschweifte Klammern eingeschlossen.

dict = {"vorname":"Hugo", "nachname":"Meister" }
menge = {1, 1, 3, 4, 4, 4, "Hallo"}

print(dict)
print(menge)
print(dict["vorname"])

Ausgabe:

{'vorname': 'Hugo', 'nachname': 'Meister'}
{1, 3, 4, 'Hallo'}
Hugo

Objektorientierte Programmierung

[Bearbeiten]

Eine einfache Klasse

[Bearbeiten]

class Fahrzeug:
    raeder = 4
   
    def __init__(self, geschwindigkeit, leistung):
        self.__geschwind = geschwindigkeit
        self.__leistung = leistung
        
    def setGeschwindigkeit(self, geschwindigkeit): # geschwindigkeit in km/h
        self.__geschwind = geschwindigkeit
        
    def setLeistung(self, leistung):
        self.__leistung = leistung
        
    def convertGeschw(self):
        # geschwindigkeit in m/s rueckgeben
        return self.__geschwind / 3.6
       

fahr = Fahrzeug(150, 90)

print(fahr.convertGeschw())

Ausgabe:

41.666666666666664

Die Klasse Fahrzeug wird durch das class-Schlüsselwort eingeleitet. raeder ist ein Klassenattribut und public. __init__ wird bei der Objekterzeugung automatisch aufgerufen. Man achte darauf, dass diese Methode immer mit zwei Unterstrichen eingeleitet und abgeschlossen wird. Instanzattributen wird das Wort self vorangestellt. Wir sehen uns z.B. das Attribut self.__geschwind an. Auch hier werden zwei Unterstriche verwendet. Das bedeutet, dass dieses Attribut private ist. Bei den Methoden wird immer self als erster Parameter angegeben. Beim Aufruf der entsprechenden Funktion wird das self aber nicht berücksichtigt.

Klassen importieren

[Bearbeiten]

Häufig ist es sinnvoll und übersichtlicher Klassen in eigenen Dateien zu speichern. Das sind dann eigene Module. Abgespeichert werden Sie mit der Endung py, wie bisher auch praktiziert. Aufgerufen werden Sie mit der import-Anweisung. Dann ist aber nur der Dateiname ohne Endung py zu verwenden. Klarer wird das mit einem Beispiel.

Datei c:\tmp\fahrzeug.py

class Fahrzeug:
    raeder = 4
   
    def __init__(self, geschwindigkeit, leistung):
        self.__geschwind = geschwindigkeit
        self.__leistung = leistung
        
    def setGeschwindigkeit(self, geschwindigkeit): # geschwindigkeit in km/h
        self.__geschwind = geschwindigkeit
        
    def setLeistung(self, leistung):
        self.__leistung = leistung
        
    def convertGeschw(self):
        # geschwindigkeit in m/s rueckgeben
        return self.__geschwind / 3.6

Datei c:\tmp\test1.py

import fahrzeug
fahr = fahrzeug.Fahrzeug(150, 90)
print(fahr.convertGeschw())

Ausgabe:

41.666666666666664

Die üblichen import-Anweisungen lauten wie folgt:

import-Befehl Instanz
import xyz xyz.Klasse
import xyz as x x.Klasse
from xyz import Klasse Klasse
from xyz import * Klasse

Der Vorteil der ersten beiden import-Anweisungen ist, dass es kaum zu Namenskollisionen kommen kann. Dafür hat man bei den letzten beiden Varianten weniger Tipparbeit.

Vererbung

[Bearbeiten]

Datei fahrzeug.py:

class Fahrzeug:
    raeder = 4
   
    def __init__(self, geschwindigkeit, leistung):
        self.__geschwind = geschwindigkeit
        self.__leistung = leistung
        
    def setGeschwindigkeit(self, geschwindigkeit): # geschwindigkeit in km/h
        self.__geschwind = geschwindigkeit
       
    def setLeistung(self, leistung):
        self.__leistung = leistung
       
    def convertGeschw(self):
        # geschwindigkeit in m/s rueckgeben
        return self.__geschwind / 3.6
       
       
class Luftfahrzeug(Fahrzeug):
    def __init__(self, geschwindigkeit, leistung, fluegel):
        super().__init__(geschwindigkeit, leistung)
        self.__flueg = fluegel
    
    def getFlueg(self):
        return self.__flueg

Datei test1.py:

import fahrzeug
fahr = fahrzeug.Luftfahrzeug(150, 90, 4)
print(fahr.getFlueg())

Ausgabe:

4

Grafiken zeichnen

[Bearbeiten]

Für das Zeichnen von Grafiken wird hier das Modul matplotlib verwendet. matplotlib ist ein externes Modul und muss vor der ersten Verwendung installiert werden. Das geht so:

  1. Starten Sie ein Terminal (bei Windows die Eingabeaufforderung).
  2. Führen Sie darin folgenden Befehl aus c:\devel\Python\Scripts\pip.exe install matplotlib

pip ist übrigens der Paketmanager von Python ( Pip_(Python)).

Optimalerweise installieren wir auch gleich das Modul numpy (Numerical Python). Wir werden es im Folgenden oft benötigen (nicht nur bei den Grafiken). Das funktioniert vom Prinzip her genauso, wie für matplotlib gezeigt.

Graph einer Funktion

[Bearbeiten]

Es soll die cosh-Funktion im Intervall gezeichnet werden. Der Programmcode lautet in der einfachsten Form:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(-3., 3.1, .1)
y = np.cosh(x)

plt.plot(x,y)
plt.grid()
plt.show()

Ausgabe:

Der Code ist quasi selbsterklärend. Das Untermodul pyplot des matplotlib-Moduls und das numpy-Modul werden importiert. x läuft von -3 bis +3. y wird für jeden x-Wert per Formel ausgerechnet. "plt.plot()" ist der Zeichenbefehl. "plt.show" ist notwendig, um das Fenster mit der Grafik anzuzeigen. Die Schrittweite 0.1 wurde so gewählt, um einen ausreichend glatten Verlauf des Graphen zu gewährleisten. Das ist immer ein Kompromiss zwischen Berechnungszeit und Ansehnlichkeit. Testen Sie einfach ein paar verschiedene Werte, um ein Gefühl dafür zu zu bekommen. "plt.grid()" zeichnet ein Gitter in die Grafik (kann auch weggelassen werden). Die Bezeichnungen plt und np könnten auch anders gewählt werden. Es ist aber Konvention, diese so wie hier gezeigt zu wählen.

Mit der im obigen Bild gezeigten Menüleiste kann die dargestellte Grafik nachträglich noch geändert werden (Zoom, Pan, Achsenparameter, Kurvenparameter etc.). Natürlich kann man das alles auch direkt programmieren. Wie das funktioniert wird ansatzweise etwas später gezeigt.

Ein etwas komplexeres Beispiel ist Folgendes:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(-3., 3.1, .1)
y = np.cosh(x) + 2**x

plt.plot(x,y)
plt.grid()
plt.show()

Ausgabe:

Man beachte, dass im Gegensatz zu Octave und Julia der ominöse Punkt (.) bei 2**x mit Python nicht benötigt wird. Das macht das Programmiererleben etwas einfacher.

Graphen mehrerer Funktionen und weiteres

[Bearbeiten]
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(-3., 3.1, .1)
y1 = np.cosh(x) + 2**x
y2 = np.sin(x) * np.cos(x)

plt.plot(x, y1, label = "cosh(x) + 2**x")
plt.plot(x, y2, label = "sin(x) * cos(x)")
plt.grid()
plt.title("Funktionsgraphen")
plt.xlabel("x")
plt.ylabel("y")
plt.legend(loc="best")

plt.show()

Um die Linienstile etwas individueller zu gestalten, ist folgender Programmcode gedacht:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(-3., 3.1, .1)
y1 = np.cosh(x) + 2**x
y2 = np.sin(x) * np.cos(x)

plt.plot(x, y1, label = "cosh(x) + 2**x", lw=5, ls="dotted")
plt.plot(x, y2, label = "sin(x) * cos(x)", lw=3, ls="--")
plt.grid()
plt.title("Funktionsgraphen")
plt.xlabel("x")
plt.ylabel("y")
plt.legend(loc="best")

plt.show()

Funktion in Parameterdarstellung

[Bearbeiten]

Es soll die archimedische Spirale im Intervall gezeichnet werden.

import matplotlib.pyplot as plt
import numpy as np

t = np.arange(0., 6*np.pi, .1)
x = t * np.cos(t)
y = t * np.sin(t)

plt.plot(x, y)
plt.grid()
plt.title("Archimedische Spirale")
 
plt.show()

Diese Darstellung erscheint verzerrt. Will man gleiche Achsenskalierungen, so kann man den plt.axis()-Befehl verwenden.

import matplotlib.pyplot as plt
import numpy as np

t = np.arange(0., 6*np.pi, .1)
x = t * np.cos(t)
y = t * np.sin(t)

plt.plot(x, y)
plt.grid()
plt.title("Archimedische Spirale")
plt.axis("equal")

plt.show()

Funktion in Polardarstellung

[Bearbeiten]
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(projection="polar")
r = np.arange(0, 1, 0.01)
theta = r**3
line = ax.plot(theta, r)

plt.show()

Logarithmische Achsenskalierung

[Bearbeiten]

Semilog

[Bearbeiten]
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0., 10, .1)
y = 10**x

plt.plot(x, y)
plt.grid()
plt.semilogy()
plt.show()

Ausgabe:

LogLog

[Bearbeiten]
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0., 10, .1)
y = 10**x

plt.plot(x, y)
plt.grid()
plt.loglog()
plt.show()

Gefüllte Fläche

[Bearbeiten]
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 3, 0.1)

y1 = 3*x - 1
y2 = x**2

plt.plot(x, y1, x, y2, color='black')
plt.fill_between(x, y1, y2, where=y1>=y2)

plt.show()

Linien, Pfeile, Rechtecke, Kreise und Texte

[Bearbeiten]
import matplotlib as mpl
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

r = mpl.patches.Rectangle((0, 0), 3, 3, angle=30, fill=False)
c = mpl.patches.Circle((4, 4), 2, fill=False)

ax.add_patch(r)
ax.add_patch(c)
ax.plot([-2, 7], [-2, 0], color="black")
ax.arrow(0, 7, 5, 0, length_includes_head=True, head_width=0.5, head_length=1.5,
         color="black")

ax.set_aspect("equal")

plt.axis([-3, 8, -3, 8])
plt.show() 

Text kann mit ax.text(x, y, "Text") hinzugefügt werden, bspw.

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

ax.text(0.1, 0.1, "Hallo")
ax.text(0.5, 0.5, "Welt", size="40", family="cursive", style="italic",
        rotation=30.0)

plt.show() 

Oder einfacher auch ohne subplots

import matplotlib.pyplot as plt

plt.text(0.1, 0.1, "Hallo")
plt.text(0.5, 0.5, "Welt", size="40", family="cursive", style="italic",
        rotation=30.0)

plt.show() 

Auch Sonderzeichen (griechische Buchstaben etc.) können verwendet werden (siehe dazu auch [6]).

import matplotlib.pyplot as plt

plt.text(.3, .5,
         r'$\Omega\ \psi\ \oint\ \nabla\ \dot a\ \frac{a}{b}\ a_b$',
         size="20")
plt.show() 

Jetzt wird noch gezeigt, wofür subplots sinnvoll eingesetzt werden können.

import matplotlib.pyplot as plt

fig, ax = plt.subplots(nrows=1, ncols=2)

ax[0].text(0.1, 0.1, "Hallo")
ax[1].text(0.1, 0.5, "Welt", size="40", family="cursive", style="italic",
           rotation=30.0)

plt.show()

Aufgaben

[Bearbeiten]
  • Zeichnen Sie die Strophoide . Das Ganze sollte in etwa so aussehen wie folgende Grafik:

  • Zeichnen Sie die verschlungene Hypozykloide . Das Ganze sollte in etwa so aussehen wie folgende Grafik:

  • Testen Sie bei den obigen Übungsaufgaben verschiedene Linienstile und Farben. Farben können mit dem plt.plot()-Parameter color gewählt werden.
  • Testen Sie bei den obigen Übungsaufgaben verschiedene Werte für a, c, r und R.

Räumliche Kurven

[Bearbeiten]
import matplotlib.pyplot as plt
import numpy as np

t = np.arange(0, 6*np.pi, 0.1)
x = t * np.cos(t)
y = t * np.sin(t)
z = t

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.plot(x, y, z)

plt.show()

Flächen

[Bearbeiten]
import matplotlib.pyplot as plt
import numpy as np 

x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
x, y = np.meshgrid(x, y)
z = np.sin(x) + 3 * np.cos(y)

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.plot_surface(x, y, z)

plt.show()

Das Ganze in Netzdarstellung läßt sich so programmieren:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 10, 0.5)
y = np.arange(0, 10, 0.5)
x, y = np.meshgrid(x, y)
z = np.sin(x) + 3 * np.cos(y)

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.plot_wireframe(x, y, z)

plt.show()

Ein etwas komplexeres Beispiel:

import matplotlib.pyplot as plt
import numpy as np 

x = np.arange(0.1, 10, 0.1)
y = np.arange(0.1, 10, 0.1)
x, y = np.meshgrid(x, y)
z1 = np.sin(x) + 3 * np.cos(y)
z2 = np.sin(x) + np.log(y)
z3 = x + np.cos(y)
z4 = x**2 - y
 
fig, ax = plt.subplots(subplot_kw={"projection": "3d"}, nrows=2, ncols=2)

ax[0][0].plot_surface(x, y, z1)
ax[0][1].plot_surface(x, y, z2)
ax[1][0].plot_surface(x, y, z3)
ax[1][1].plot_surface(x, y, z4)

plt.show()

Man beachte, dass man die Unterbilder im Bild nach dem Ausführen des Scripts z.B. mit der mittleren Maustaste einzeln drehen, oder über die Einträge in der Menüzeile einzeln bearbeiten kann. Mit ein paar Zeilen Programmtext lässt sich also eine Menge an Funktionalität generieren.

Die Farbgebung lässt sich über colormaps variieren.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm

x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
x, y = np.meshgrid(x, y)
z = np.sin(x) + 3 * np.cos(y)

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.plot_surface(x, y, z, cmap = cm.coolwarm)

plt.show()

Es gibt eine Menge an Colormaps, z.B. plasma, Greys, Dark2, ocean. Zwecks detaillierterer Infos siehe die matplotlib-Dokumentation. Verwendet man die IDE namens IDLE, so gibt es dort auch die automatische Codevervollständigung. D.h. es werden alle Möglichkeiten (in unserem Fall nach dem Eintippen von cm. alle verfügbaren Colormaps) angezeigt.

Die "edgecolor" und Linienbreite können auch frei gewählt werden:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm

x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
x, y = np.meshgrid(x, y)
z = np.sin(x) + 3 * np.cos(y)

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.plot_surface(x, y, z, cmap = cm.coolwarm, edgecolor="black", linewidth=1.0)

plt.show()

Höhenlinien

[Bearbeiten]
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
x, y = np.meshgrid(x, y)
z = np.sin(x) + 3 * np.cos(y)

fig, ax = plt.subplots()
ax.contour(x, y, z)

plt.show()

Etwas abgewandelt sieht das so aus:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
x, y = np.meshgrid(x, y)
z = np.sin(x) + 3 * np.cos(y)

fig, ax = plt.subplots()
hl = ax.contour(x, y, z)
ax.clabel(hl, inline = True)

plt.show()

Und noch eine Variante sei gezeigt.

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
x, y = np.meshgrid(x, y)
z = np.sin(x) + 3 * np.cos(y)

fig, ax = plt.subplots()
ax.contourf(x, y, z)

plt.show()

Aufgaben

[Bearbeiten]
  • Zeichnen Sie die räumliche Kurve , , , .
  • Zeichnen Sie die Fläche .

Animationen

[Bearbeiten]

Mit matplotlib

[Bearbeiten]

Auch mit matplotlib sind Animationen möglich. Das ist ein bisschen komplizierter und wird deshalb hier nur mit einem sehr einfachen Beispiel dargestellt (bei Interesse siehe z.B. auch das Animations using Matplotlib-Tutorial.

import matplotlib.pyplot as plt
import matplotlib.animation as ani
import matplotlib
import numpy as np

def update(frame):
    line.set_xdata(x[:frame])
    line.set_ydata(y[:frame])
    return (line)

fig, ax = plt.subplots()

x = np.arange(0, 10, .1)
y = np.sin(x)

line, = ax.plot(x[0], y[0])
ax.set(xlim=[0, 10], ylim=[-1, 1])

a = ani.FuncAnimation(fig=fig, func=update, frames=100, interval=20)
plt.show()

# Speichere die Animation in einem animierten GIF (optional)
a.save(filename="c:/tmp/PythonIng_anim5.gif", writer="pillow")

Es wird eine Sinuskurve auf den Bildschirm gezeichnet. In der letzten Zeile wird diese Animation in ein animiertes GIF gespeichert. Das ist natürlich optional und kann auch weggelassen werden.

Mit VPython

[Bearbeiten]

Aber auch mit dem Modul VPython lassen sich einfache 3D-Animationen erstellen. VPython ist ein externes Modul, das vorab installiert werden muss (die prinzipielle Vorgehensweise wurde oben bereits gezeigt und sei hier nicht wiederholt). Ein Beispiel zu solch einer einfachen Animation wird nachfolgend geliefert.

from vpython import *

scene.width = 1200
scene.height = 600
scene.center = vector(20,0,0)
scene.background = color.white

cylinder(pos=vector(0,0,0), axis=vector(20,0,0), radius=5, 
        color=color.blue)
cone(pos=vector(0,0,0), axis=vector(-10,0,0), radius=5, 
        color=color.blue)
helix(pos=vector(20,0,0), axis=vector(40,0,0), radius=2, 
        coils=10, thickness=0.5, color=color.blue)

ball = sphere(pos=vector(20,0,0), color = color.green, radius = 1)
ball.p = vector(0.15, 0, 0)

toc = True

while True:
    rate(200)
    if(ball.pos.x <= 60 and toc == True):
        ball.pos += ball.p
    else:
        toc = False
        ball.pos -= ball.p
        if(ball.pos.x <= 20 and toc == False):
            toc = True

Vektoren und Matrizen

[Bearbeiten]

Zahlenfolgen

[Bearbeiten]
from numpy import *

start = 0
stop = 10
step = 2
num = 10

r = arange(start, stop, step)
l = linspace(start, stop, num)

print("r = ", r)
print("l = ", l)

Ausgabe:

r =  [0 2 4 6 8]
l =  [ 0.          1.11111111  2.22222222  3.33333333  4.44444444  5.55555556
  6.66666667  7.77777778  8.88888889 10.        ]

Vektoren

[Bearbeiten]

Vektoren sollten jedem aus der Linearen Algebra bekannt sein.

Arrays

[Bearbeiten]

In Python mit NumPy kann man Vektoren durch die Funktion array erzeugen.

import numpy as np

l1 = (-5, 3, 2)
l2 = (1, 1, 4)

a1 = np.array(l1)
a2 = np.array(l2)

a3 = a1 + a2
a4 = 2 * a2

print(a1)
print(a2)
print(a3)
print(a3[2])
print(a4)

Ausgabe:

[-5  3  2]
[1 1 4]
[-4  4  6]
6
[2 2 8]

Zeilen- und Spaltenvektoren

[Bearbeiten]
import numpy as np

# Zeilenvektor
z = np.array([ [-5, 3, 2] ])
# Spaltenvektor
s = np.array([[1], [1], [4]])

print(z)
print(s)

Ausgabe:

[ [-5  3  2] ]
[[1]
 [1]
 [4]]

Skalarprodukt

[Bearbeiten]
import numpy as np

a1 = np.array((-5, 3, 2))
a2 = np.array((1, 1, 4))

skalarprodukt = np.dot(a1, a2)  

print(skalarprodukt)

Ausgabe:

6

Vektorprodukt

[Bearbeiten]

Python-Code:

import numpy as np

a1 = np.array((-5, 3, 2))
a2 = np.array((1, 1, 4)) 

vektorprodukt = np.cross(a1, a2) 

print(vektorprodukt)

Ausgabe:

[10 22 -8]

Transponierter Vektor

[Bearbeiten]
import numpy as np

# Zeilenvektor
z = np.array([ [-5, 3, 2] ])
# Spaltenvektor
s = np.array([[1], [1], [4]])

# transponierter Vektor
z_tp = np.transpose(z)
# transponierter Vektor
s_tp = np.transpose(s)

print(z_tp)
print(s_tp)

Ausgabe:

[[-5]
 [ 3]
 [ 2]]
[ [1 1 4] ]

Vektorfelder visualisieren

[Bearbeiten]
import matplotlib.pyplot as plt
import numpy as np

# Daten generieren
x = np.arange(0, 10, 1)
y = np.arange(0, 10, 1)
X, Y = np.meshgrid(x, y)
U = X * Y
V = Y + X

# Plotten
fig, ax = plt.subplots()

ax.quiver(X, Y, U, V, angles='xy')

plt.show()

Ausgabe:

Matrizen

[Bearbeiten]
import numpy as np
m1 = np.matrix([[1, 2, 3], [4, 5, 6]])
print(m1)

Ausgabe:

[[1 2 3]
 [4 5 6]]

Zugriff auf Matrizenelemente

[Bearbeiten]
import numpy as np

m1 = np.matrix([[1, 2, 3], [4, 5, 6]])

# Element aus Zeile 2 und Spalte 3 (Achtung! Index startet bei Null)
print(m1[1,2])

Ausgabe:

6

Addition und Subtraktion von Matrizen

[Bearbeiten]
import numpy as np

m1 = np.matrix([[1, 2, 3], [4, 5, 6]])
m2 = np.matrix([[0, 0, 2], [1, 3, 2]])

print(m1 + m2)
print(m1 - m2)

Ausgabe:

[[1 2 5]
 [5 8 8]]
[[1 2 1]
 [3 2 4]]

Transponierte Matrix

[Bearbeiten]
import numpy as np

m = np.matrix([[1, 2, 3], [4, 5, 6]])
mt = np.transpose(m) 

print(m)
print(mt)

Ausgabe:

[[1 2 3]
 [4 5 6]]
[[1 4]
 [2 5]
 [3 6]]

Rang einer Matrix

[Bearbeiten]
import numpy as np

m = np.matrix([[1, 3],  [0, -5]])
rg = np.linalg.matrix_rank(m)

print(rg)

Ausgabe:

2

Inverse Matrix

[Bearbeiten]
import numpy as np

m = np.matrix([[1, 3],  [0, -5]])
mi = np.linalg.inv(m)

print(mi)

Ausgabe:

[[ 1.   0.6]
 [-0.  -0.2]]

Multiplikation von Matrizen (falksches Schema)

[Bearbeiten]
import numpy as np

m1 = np.matrix([[1, 3, 4],  [0, -5, 1]])
m2 = np.matrix([[1, 2], [2, 3], [0, 2]])

print(m1 @ m2)

Ausgabe:

[[  7  19]
 [-10 -13]]

Eigenwerte und Eigenvektoren

[Bearbeiten]
import numpy as np

m = np.matrix([[5, 8],  [1, 3]])
D,V = np.linalg.eig(m)

# Eigenwerte
print(D)
# Eigenvektoren
print(V)

Ausgabe:

[7. 1.]
[[ 0.9701425  -0.89442719]
 [ 0.24253563  0.4472136 ]]

Teilmatrizen

[Bearbeiten]
import numpy as np
m = np.matrix([[1, 3, 4],  [0, -5, 1]])
print("m = ", m)

# Erste Zeile extrahieren
m1 = m[0,:]
print("m1 = ", m1)

# Das Element aus der 1. Zeile und der 2. Spalte extrahieren
m2 = m[0,1]
print("m2 = ", m2)

# Zweite Spalte extrahieren
m3 = m[:, 1]
print("m3 = ", m3)

Ausgabe:

m =  [[ 1  3  4]
 [ 0 -5  1]]
m1 =  [ [1 3 4] ]
m2 =  3
m3 =  [[ 3]
 [-5]]

Spezielle Matrizen

[Bearbeiten]

Nullmatrix:

import numpy as np
z = np.zeros((3, 2))
print(z)

Ausgabe:

[[0. 0.]
 [0. 0.]
 [0. 0.]]

Einheitsmatrix:

import numpy as np
z = np.eye(3)
print(z)

Ausgabe:

[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

Matrix mit lauter Einsen:

import numpy as np
z = np.ones((3, 2))
print(z)

Ausgabe:

[[1. 1.]
 [1. 1.]
 [1. 1.]]

Spärlich besetzte Matrizen

[Bearbeiten]

Das Thema spärlich besetzter Matrizen wird hier nur kurz angerissen. Nähere Details siehe unter dem Weblink [7].

import numpy as np
import scipy

A = scipy.sparse.csr_array(np.eye(5))

print(A)

Ausgabe:

 (0, 0)        1.0
 (1, 1)        1.0
 (2, 2)        1.0
 (3, 3)        1.0
 (4, 4)        1.0

Lineare Gleichungssysteme

[Bearbeiten]

Sei ein lineares Gleichungssystem. sei die Koeffizientenmatrix, der Lösungsvektor und ein bekannter Vektor.

Beispiel:

import numpy as np

A = np.array([[5, 1], [0, 2]])
b = np.array([1, 2])

x = np.linalg.solve(A, b)

print(x)

Ausgabe:

[0. 1.]

Aufgabe

[Bearbeiten]
  • Lösen Sie folgendes Gleichungssystem mittels Python (und zur Kontrolle auch händisch):
5x + 6y - 2z = 12
3x - y  - 3z = 6
2x + 2y + 4z = 5

Polynome

[Bearbeiten]

Ein erstes einfaches Beispiel

[Bearbeiten]

Gegeben sei das Polynom . In Python:

import numpy as np

p = np.poly1d([7, 5, 0, 1])
print(p)

Ausgabe:

   3     2
7 x + 5 x + 1

Einzelne Polynomwerte berechnen

[Bearbeiten]
import numpy as np

p = np.poly1d([7, 5, 0, 1])
print(p(1.5))

Ausgabe:

35.875

Polynome integrieren und differenzieren

[Bearbeiten]
import numpy as np

p = np.poly1d([7, 5, 0, 1])

# 1. Ableitung
p1 = p.deriv()
p2 = p.deriv(1)

# 2. Ableitung
p3 = p.deriv(2)

# Integral
p4 = p.integ()

print(p1)
print(p2)
print(p3)
print(p4)

Ausgabe:

    2
21 x + 10 x
    2
21 x + 10 x

42 x + 10
      4         3
1.75 x + 1.667 x + 1 x

Nullstellen bestimmen

[Bearbeiten]
import numpy as np

p = np.poly1d([2, 5, 0, 4])
r = np.roots(p)

print(r)

Ausgabe:

[-2.7621427 +0.j          0.13107135+0.84077099j  0.13107135-0.84077099j]

Aufgaben

[Bearbeiten]
  • Berechnen Sie den Wert für x = 3 des Polynoms .
  • Differenzieren und integrieren Sie das Polynom .
  • Berechnen Sie die Nullstellen von .

Nichtlineare Gleichungen und Gleichungssysteme

[Bearbeiten]

Nullstellenbestimmung

[Bearbeiten]

Löse eine beliebige Gleichung f(x) = 0, z.B. :

import scipy
import numpy as np

def f(x):
    return x**2 - 5*np.cos(x) - 10
   
xstart = [-1, 1]        # Startwerte
xn = scipy.optimize.root(f, xstart)

print(xn.x)

Ausgabe:

[-2.46813009  2.46813009]

Funktionsgraph:

Gleichungssysteme

[Bearbeiten]

Folgende Aufgabe ist dem Buch "Knorrenschild: Numerische Mathematik, Hanser, 2017, Seite 72" entnommen. Zu lösen ist das nichtlineare Gleichungssystem

Mit Python ist das so möglich:

import sympy

x1, x2 = sympy.symbols("x1 x2") 

f1 = 2*x1 + 4*x2
f2 = 4*x1 + 8*x2**3

s = sympy.solve((f1, f2), x1, x2) 

print(s[1])
print(s[2])

Ausgabe:

(0, 0)
(2, -1)

Komplexe Zahlen

[Bearbeiten]

Die imaginäre Einheit wird in Python durch den Buchstaben j symbolisiert. Darstellen kann man eine komplexe Zahl bekannterweise in mehreren Formen:

  • Kartesische Darstellung
  • Polardarstellungen

Die konjugiert komplexe Zahl ist

Nachfolgend einige mathematische Operationen mit Python und NumPy.

import numpy as np

z1 = 2 + 5j           # kartesische Darstellung
z2 = 3 * np.exp(3j)   # Polardarstellung
 
# Addition
res = z1 + z2
print("z1 + z2 = ", res)

# Multiplikation
res = z1 * z2
print("z1 * z2 = ", res)

# Realteil
res = np.real(z2)
print("Realteil von z2 = ", res)

# Imaginärteil
res = np.imag(z2)
print("Imaginaerteil von z2 = ", res)

# Betrag
res = np.abs(z1)
print("Betrag von z1 = ", res)

# Argument
res = np.angle(z1)
print("Argument von z1 = ", res)

# Konjugiert komplexe Zahl
res = np.conj(z1)
print("Konjugiert komplexe Zahl von z1 = ", res)

Ausgabe:

z1 + z2 =  (-0.9699774898013365+5.423360024179601j)
z1 * z2 =  (-8.05675510050068-14.003167400647481j)
Realteil von z2 =  -2.9699774898013365
Imaginaerteil von z2 =  0.4233600241796016
Betrag von z1 =  5.385164807134504
Argument von z1 =  1.1902899496825317
Konjugiert komplexe Zahl von z1 =  (2-5j)

Interpolation

[Bearbeiten]
import numpy as np
import scipy
import matplotlib.pyplot as plt

# Stützpunkte
xp = np.arange(1, 6)
yp = (0, -5, 2, 7, 6)

ti = np.arange(1, 5, 0.01)

i1 = scipy.interpolate.interp1d(xp, yp, kind = "linear")
i2 = scipy.interpolate.interp1d(xp, yp, kind = "cubic") 

plt.plot(xp, yp, "rx")
plt.plot(xp, i1(xp))
plt.plot(ti, i2(ti))
plt.show()

Ausgabe:

Differenzialrechnung

[Bearbeiten]

Numerisches Differenzieren

[Bearbeiten]

Als Beispiel differenzieren wir und stellen das Ganze grafisch dar.

import findiff
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 1000)
f = 5 * x * np.sin(x);

dx = x[1] - x[0]

# Ableitung
d_dx = findiff.FinDiff(0, dx)
df_dx = d_dx(f) 

# Grafik
plt.plot(x, f, label = "y")
plt.plot(x, df_dx, label = "y'")
plt.grid()
plt.legend(loc="best")

plt.show()

Ausgabe:

findiff ist ein externes Modul. Dieses muss installiert werden (z.B. so: ...\Python\Scripts\pip.exe install --upgrade findiff). Das im Buch "Steinkamp: Der Python-Kurs für Ingenieure und Naturwissenschaftler, Rheinwerk" verwendete Modul "scipy.misc" ist veraltet (deprecated ... missbilligt) und wird in einer kommenden SciPy-Version entfernt werden.

Symbolisches Differenzieren

[Bearbeiten]
import sympy

x = sympy.symbols("x")

f1 = x**2;
f2 = sympy.sin(x) * sympy.cos(x/2.)   

d1 = sympy.diff(f1, x)
d2 = sympy.diff(f2, x)

print(d1)
print(d2)

Ausgabe:

2*x
-0.5*sin(0.5*x)*sin(x) + cos(0.5*x)*cos(x)

Aufgaben

[Bearbeiten]
  • Differenzieren Sie die Funktion und stellen Sie y, sowie y' grafisch am Bildschirm dar.
  • Differenzieren Sie die Funktion und stellen Sie y, sowie y' grafisch am Bildschirm dar.

Integralrechnung

[Bearbeiten]

Numerisches Integrieren

[Bearbeiten]

Berechnen Sie das Integral

import scipy

def f(x):
    return x**2;
   
i = scipy.integrate.quad(f, 0, 3)
print(i)

Ausgabe:

(9.000000000000002, 9.992007221626411e-14)

Das trifft den exakten Wert 9.0 ziemlich genau.

Symbolisches Integrieren

[Bearbeiten]
import sympy

x = sympy.symbols("x")

f1 = x**2;
f2 = sympy.sin(x) * sympy.cos(x/2.)   

i1 = sympy.integrate(f1, x)
i2 = sympy.integrate(f2, x)

print(i1)
print(i2)

Ausgabe:

x**3/3
-0.666666666666667*sin(0.5*x)*sin(x) - 1.33333333333333*cos(0.5*x)*cos(x)

Aufgaben

[Bearbeiten]
  • Integrieren Sie die Funktion von -5 bis 5.
  • Integrieren Sie die Funktion von 0 bis 4. Verwenden Sie hierzu das Verfahren von Romberg (scipy.integrate.romberg()).

Gewöhnliche Differenzialgleichungen

[Bearbeiten]

DGL numerisch lösen

[Bearbeiten]

Für die Lösung von Differenzialgleichungen steht u.a. die Funktion scipy.integrate.solve_ivp() zur Verfügung. Diese Funktion implementiert auch das Runge-Kutta-Verfahren (RK45).

Wikipedia hat einen Artikel zum Thema:


Beispiel :

import scipy
import numpy as np
import matplotlib.pyplot as plt

def dy_dx(x, y):
    return x**2 + y**3

y0 = [1]
xi = [0, 1]
x = np.arange(0, 1, 0.01)

z = scipy.integrate.solve_ivp(dy_dx, xi, y0, method="RK45", dense_output=True)
y = z.sol(x)

plt.plot(x, y.T)
plt.grid()
plt.show()

DGL symbolisch lösen

[Bearbeiten]

Beispiel :

import sympy

x = sympy.symbols("x")
y = sympy.Function("f")(x)

dgl = x**2 + y**3 

lsg = sympy.dsolve(dgl, y)

print(lsg)

Ausgabe:

[Eq(f(x), (-x**2)**(1/3)), Eq(f(x), (-x**2)**(1/3)*(-1 - sqrt(3)*I)/2), Eq(f(x), (-x**2)**(1/3)*(-1 + sqrt(3)*I)/2)]

Aufgaben

[Bearbeiten]
  • Lösen Sie die Differenzialgleichung mit Python. Kontrollieren Sie das Ergebnis, indem Sie die DGl händisch lösen.
  • Lösen Sie die Differenzialgleichung . Kontrollieren Sie das Ergebnis, indem Sie die DGl händisch lösen.
  • Lösen Sie die Differenzialgleichung .

Stochastik

[Bearbeiten]

Die Stochastik ist ein sehr weites Feld. Hier werden nur einige wenige sehr einfache, aber wichtige Themen angerissen. Python stellt mit den Moduln math und statistics Software zu diesem Zwecke bereit. math und statistics sind bereits im Lieferumfang von Python enthalten. Aber auch mit den externen Modulen NumPy, SciPy und pandas kann man Stochastik in Python betreiben. Dies wird hier aber nicht gemacht.

Lageparameter

[Bearbeiten]
import statistics

werte = [1, 3, 4, 4, 1, 7, 9, 1, 2, 3]

m1 = statistics.mean(werte)
m2 = statistics.mode(werte)
m3 = statistics.median(werte)

print("Arithmetischer Mittelwert = ", m1)
print("Modalwert = ", m2)
print("Median = ", m3)

Ausgabe:
 Arithmetischer Mittelwert =  3.5
 Modalwert =  1
 Median =  3.0

Streuungsparameter

[Bearbeiten]
import statistics
werte = [1, 3, 4, 4, 1, 7, 9, 1, 2, 3]
s = statistics.stdev(werte)
print("Standardabweichung = ", s)

Ausgabe:

Standardabweichung =  2.6770630673681683

Kombinatorik

[Bearbeiten]
import math

n = 7
k = 5

print("n! = ", math.factorial(n))
print("Kombinationen (n über k) = ", math.comb(n, k))

Ausgabe:

n! =  5040
Kombinationen (n über k) =  21

Ein- und Ausgabe

[Bearbeiten]

print

[Bearbeiten]

Die Anweisung print haben wir schon oft verwendet. Hier soll anhand von Beispielen kurz beschrieben werden, was der Befehl print leisten kann.

print("Hallo", "Welt", 1, sep="-")
print("Hallo", end=" ")
print("Welt")

Ausgabe:

Hallo-Welt-1
Hallo Welt

input

[Bearbeiten]
a = int(input("Zahl 1: "))
b = int(input("Zahl 2: "))

print("a + b = ", a+b)

Ausgabe (nach Eingabe der beiden Ganzzahlen):

Zahl 1: 4
Zahl 2: 5
a + b =  9

Aus Dateien lesen

[Bearbeiten]

Es seinen die datei.txt

Hallo Welt.
Wie geht es dir?
...

und test1.py

dat = open("datei.txt", mode = "r")
print(dat.read())
dat.close()

Ausgabe

Hallo Welt.
Wie geht es dir?
...

Mit dem open()-Befehl wird die Datei datei.txt im Lesemodus geöffnet (r ... read). Mit dem read()-Befehl wird die Datei eingelesen und mittels print ausgegeben.

In Dateien schreiben

[Bearbeiten]
dat = open("datei.txt", mode = "a", encoding = "utf-8")
dat.write("Hänge Zeile an")
dat.close()

Die Datei datei.txt sieht nach Abarbeitung des obigen Skripts nun so aus

Hallo Welt.
Wie geht es dir?
...
Hänge Zeile an

Es wird die Datei im Schreibmodus geöffnet (a ... append (anhängend), w ... write (überschreibend)). write() fügt eine Zeile Text am Dateiende ein. close() schließt die Datei wieder.

Benutzeroberflächen erstellen

[Bearbeiten]

Python bietet standardmäßig das Modul tkinter zur Programmierung von Benutzeroberflächen. Es müssen also bei der Verwendung von tkinter keine externen Module installiert werden. Hier wird eine (sehr) kurze Einführung in das Erstellen von grafischen Oberflächen mittels tkinter gegeben.

import tkinter as tk

win = tk.Tk()
win.title("Hallo Welt!")
win.minsize(300, 50)
but = tk.Button(win, text = "Push the button")
but.pack()
win.mainloop()

Ausgabe:

Ein etwas komplizierteres Beispiel sei nachfolgend gezeigt. Es sollen zwei Strings miteinander verknüpft und ausgegeben werden.

import tkinter as tk

win = tk.Tk()
win.title("Hallo Welt!")

def on_button_clicked():
    str = ent1.get() + ent2.get()
    lab2["text"] = str
 
ent1 = tk.Entry(win)
ent2 = tk.Entry(win)
lab1 = tk.Label(win, text="verknuepfen mit")
lab2 = tk.Label(win, text="") 
but = tk.Button(win, text = "=", command=on_button_clicked)

ent1.pack(side="left")
lab1.pack(side="left")
ent2.pack(side="left")
but.pack(side="left")
ent2.pack(side="left")
lab2.pack(side="left")

win.mainloop()

Ausgabe (vor der Eingabe der Teilstrings):

Ausgabe (nach der Eingabe der Teilstrings und dem Drücken des =-Buttons):

Einige Integrierte Entwicklungsumgebungen (IDEs)

[Bearbeiten]

Werden Programmtexte größer und umfangreicher, so ist das Arbeiten mit der interaktiven Programmierumgebung bzw. das direkte Ausführen von Python-Skripten mühsam. Man wünscht sich z.B. Hilfen zum Debuggen oder die automatische Code-Vervollständigung. Zu diesem Zweck wurden IDEs (Integrated Development Environments) geschaffen. Von diesen seinen nachfolgend auszugsweise einige kurz beschrieben. Testen Sie einfach aus, welche davon für Sie bzw. für Ihr Python-Projekt geeignet sind.

IDLE ist die mit dem Python-Programmpaket mitgelieferte IDE. Der Name leitet sich einerseits ab vom Monty-Python-Mitglied Eric Idle, andererseits steht es als Abkürzung für "Integrated Development and Learning Environment. IDLE ist einfach zu bedienen, bietet aber schon einen beachtlichen Leistungsumfang. Nachfolgend wird ein Screenshot zu IDLE geliefert. Rechts ist das Editor-Fenster zu sehen, links die interaktive Programmierumgebung. Um das Beispiel selbst nachvollziehen zu können, starten Sie IDLE. Das geht ähnlich, wie Sie die interaktive Programmierumgebung von Python starten (nur, dass Sie eben das IDLE-Icon doppelklicken und nicht das Python-Icon). Weiter geht es mit "File - Open - ..." Die auszuführende Datei auswählen. Es erscheint das rechte Fenster . Dort "Run - Run Module" auswählen. Und schon wird im linken Fenster " Hallo Welt!" ausgegeben.

PyCharm

[Bearbeiten]

PyCharm ist ein kommerzielles Produkt. Es gibt aber auch eine kostenlose Community Edition. Diese steht unter der Apache Lizenz. Zu beziehen ist sie unter dem Weblink [8]. Nachfolgend ein etwas abgewandeltes "Hallo Welt"-Programm, editiert und ausgeführt mit PyCharm.

Auch eric ist Open Source und steht unter der GNU General Public License Version 3 oder später. Zu beziehen ist diese Software unter [9].

PyScripter

[Bearbeiten]

Vom Funktionsumfang vergleichbar mit den vorherigen IDEs ist PyScripter. Auch PyScripter ist Open Source. Die Projekt-Homepage findet sich auf [10].

Sonstige

[Bearbeiten]

Die genannten IDEs sind nicht die Einzigen. Es gibt, um dem Image Pythons als beliebteste Programmiersprache gerecht zu werden, noch einige andere. Sowohl Open Source-Programme als auch kommerzielle Programme sind im Web zu finden, z.B. Thonny,  Spyder IDE oder  Visual Studio Code. Braucht man den Umfang von ausgewachsenen IDEs nicht, so kann man auch normale Texteditoren verwenden (z.B.  Geany).

Ausblick

[Bearbeiten]

Dies war eine kurze Einführung in die Berechnungs- und Darstellungsmöglichkeiten mit Python. Es sollten etliche relevante Themen behandelt, oder zumindest kurz angesprochen worden sein. Wem dieser Text nicht ausreichend ist, der sei auf die entsprechenden weiterführenden Weblinks, Bücher und die Python-Hilfefunktion verwiesen. Python kennt noch viel mehr Befehle, als hier dargestellt wurden. Das Themenspektrum ist auch durch die Einbindung externer Module fast beliebig erweiterbar.

Weblinks

[Bearbeiten]

Bücher

[Bearbeiten]
  • Diverse: c't Python Lernen, Verstehen, Anwenden; Heise, 2022
  • Ernesti, Kaiser: Python3 - das umfassende Handbuch; 5. Aufl., Rheinwerk, OpenBook
  • Inden: Python Challenge; dpunkt, 2021, ISBN 978-3-86490-809-5
  • Steinkamp: Der Python-Kurs für Ingenieure und Naturwissenschaftler; Rheinwerk, 2021, ISBN 978-3-8362-7316-9
  • Weigend: Python 3 - Das umfassende Praxisbuch; 9. Aufl., mitp, 2022, ISBN 978-3-7475-0544-1
  • Woyand: Python für Ingenieure und Naturwissenschaftler; 4. Aufl., Hanser, 2021, ISBN 978-3-446-46483-4