Erste Schritte
Contents
1. Erste Schritte¶
Wir wollen uns zunächst mit den Grundprinzipien der Programmiersprache Python vertraut machen. Insbesondere wollen wir lernen, welche Datentypen von Haus aus bereitgestellt werden, und wie wir mit diesen Arbeiten. Ferner wollen wir uns schon ein bisschen an die Syntax dieser Programmiersprache gewöhnen.
1.1. Variablen und Datentypen¶
1.1.1. Python als Taschenrechner verwenden¶
Python lässt sich wie ein Taschenrechner verwenden. Zwischenergebnisse können mit dem Zuweisungsoperator =
ganz einfach in Variablen abgespeichert werden:
3+5
8
a = 3+5
b = a/2
b
4.0
Mit der type
-Funktion lässt sich der Datentyp der Variable ermitteln:
print("a ist ein", type(a))
print("2 ist ein", type(2))
print("2. ist ein", type(2.))
print("b ist ein", type (b))
a ist ein <class 'int'>
2 ist ein <class 'int'>
2. ist ein <class 'float'>
b ist ein <class 'float'>
Weitere mathematische Funktionen sind im Modul math
enthalten, welches zunächst in das Python-Skript eingebunden werden muss:
import math
print("Die Wurzel aus 9 ist", math.sqrt(9))
print("2 hoch 3 ist", 2**3)
print("Der natürliche Logarithmus aus 3 ist", math.log(3))
Die Wurzel aus 9 ist 3.0
2 hoch 3 ist 8
Der natürliche Logarithmus aus 3 ist 1.0986122886681098
Um zu erfahren welche Funktionen die math
-Bibliothek noch bereitstellt kann man
math.<TAB>
eingeben
Übungsaufgabe
Ermitteln Sie die Werte von \(\sin(x)\) für \(x\in \{0,\pi/2, \pi, 3\pi/2, 2\pi\}\).
In diesem Beispiel haben wir auch gesehen, wie zusätzliche Module eingebunden und verwendet werden. Funktionen aus dem Modul math
müssen hier mit math.sin(...)
angesprochen werden. Alternativ kann man alle Funktionen einer Bibliothek mittels
from math import *
einbinden und alle Funktionen und Variablen ohne Angabe des Bibliotheksnamens ansprechen.
Achtung: Hierbei können Namenskonflikte mit Funktionen und Variablen anderer Bibliotheken entstehen.
from math import *
print("Der Sinus von pi/2 ist", sin(pi/2))
Der Sinus von pi/2 ist 1.0
1.1.2. Numerische Datentypen¶
Wir haben im vorherigen Abschnitt bereits die type
-Funktion kennengelernt und haben 2 verschiedene Datentypen bei unseren Berechnungen beobachtet. Die numerischen Datentypen sind in folgender Tabelle zusammengefasst:
Datentyp |
Beschreibung |
Beispiele |
---|---|---|
|
Ganze Zahlen |
|
|
Fließkommazahlen |
|
|
Bool’scher Wert |
|
|
Komplexe Zahlen |
|
Boolsche Variablen nehmen lediglich die Werte wahr (True
) oder falsch (False
) an. Sie sind unter Anderem das Ergebnis von Vergleichsoperationen:
a = 1 < 3
print("a ist eine Variable vom Typ", type(a), "und hat den Wert", a)
b = 1==0
print("b ist eine Variable vom Typ", type(b), "und hat den Wert", b)
a ist eine Variable vom Typ <class 'bool'> und hat den Wert True
b ist eine Variable vom Typ <class 'bool'> und hat den Wert False
Für komplexe Zahlen sind entsprechende Rechenoperationen in der Bibliothek cmath
definiert, die wir über
import cmath
einbinden können. Eine kurze Dokumentation zu einer Bibliothek bekommt man übrigens mit
cmath?
Hier ein kleines Beispiel:
import cmath
a = cmath.sqrt(-9)
print("Die Wurzel aus -9 ist", a)
b = 1+2j
c = a/b
print("Der Quotient aus a und b ist", c, "und ist wieder vom Typ", type(c))
print("Es gilt Re(c) =", c.real,
", Im(c) =", c.imag,
"und die konjugiert Komplexe ist =", c.conjugate())
Die Wurzel aus -9 ist 3j
Der Quotient aus a und b ist (1.2+0.6j) und ist wieder vom Typ <class 'complex'>
Es gilt Re(c) = 1.2 , Im(c) = 0.6 und die konjugiert Komplexe ist = (1.2-0.6j)
Übungsaufgabe
Berechne den Betrag und das Argument der Zahl 1+i.
Hinweis: Schaue dir zunächst an, welche Funktionen cmath
bereitstellt.
1.1.3. Strings¶
Datentyp |
Beschreibung |
Beispiel |
---|---|---|
|
Eine beliebig lange Zeichenkette |
|
Ein Objekt vom Typ string
ist eine Zeichenkette, wie wir Sie bei den Konsolenausgaben vorher schon verwendet haben. Strings werden durch Apostrophen oder Gänsefüßchen begrenzt.
a = "Ich bin ein String." # String erzeugen
a+= "\nEin sehr langer String." # Einen weiteren String anhängen
a+= "\nNun schon "+str(3)+" Zeilen lang" # Integer in String verwandeln und anhängen
print(a)
Ich bin ein String.
Ein sehr langer String.
Nun schon 3 Zeilen lang
Das Sonderzeichen '\n'
steht dabei für einen Zeilenumbruch. Um Objekte anderer Typen in einen string
umzuwandeln, nutzen wir die Funktion str()
. Der Additionsoperator +
verknüpft 2 Strings miteinander und der Operator +=
hängt einen String an einen anderen an.
Geben wir a.<TAB>
ein, bekommen wir wieder eine Liste mit nützlichen Funktionen, die wir auf Strings anwenden können. Alternativ lassen sich alle für Strings definierten Methoden wie folgt auflisten:
dir(a)
['__add__',
'__class__',
'__contains__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__getnewargs__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mod__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__rmod__',
'__rmul__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'capitalize',
'casefold',
'center',
'count',
'encode',
'endswith',
'expandtabs',
'find',
'format',
'format_map',
'index',
'isalnum',
'isalpha',
'isascii',
'isdecimal',
'isdigit',
'isidentifier',
'islower',
'isnumeric',
'isprintable',
'isspace',
'istitle',
'isupper',
'join',
'ljust',
'lower',
'lstrip',
'maketrans',
'partition',
'removeprefix',
'removesuffix',
'replace',
'rfind',
'rindex',
'rjust',
'rpartition',
'rsplit',
'rstrip',
'split',
'splitlines',
'startswith',
'strip',
'swapcase',
'title',
'translate',
'upper',
'zfill']
Die Methoden, welche mit 2 Unterstrichen beginnen sind private Methoden und sollten vom Programmierer nicht verwendet werden. Einige dieser Methoden dienen zur Überladung von Operatoren, beispielsweise realisiert die Methode __eq__
den Vergleichsoperator ==
, oder __add__
den Additionsoperator +
. Wir dieskutieren dies noch einmal genauer im Abschnitt Spezielle Methoden.
In folgendem Beispiel wenden wir einige der für Strings definierten Methoden an:
# Buchstaben zählen
print("Unser String enthält", a.count('e'), "mal den Buchstaben 'e'.")
# Nach Zeichenfolgen suchen
print("An Position", a.find("String"), "finden wir das Wort 'String'.")
# Bestimmte Zeichenfolgen ersetzen
a = a.replace("Ich", "I")
a = a.replace("bin", "bims")
a = a.replace("ein", "1")
print(a)
a = a.replace("\n"," ") # Zeilenumbruch durch Leerzeichen ersetzen
a = a.replace(".", "") # Satzzeichen entfernen
L = a.split(" ") # String an Leerzeichen zerschneiden
print(L)
Unser String enthält 5 mal den Buchstaben 'e'.
An Position 12 finden wir das Wort 'String'.
I bims 1 String.
Ein sehr langer String.
Nun schon 3 Zeilen lang
['I', 'bims', '1', 'String', 'Ein', 'sehr', 'langer', 'String', 'Nun', 'schon', '3', 'Zeilen', 'lang']
Die Funktion string.split()
erzeugt ein Objekt vom Typ list
, welche wir im folgenden Abschnitt genauer diskutieren.
1.1.4. Containerklassen¶
Weitere wichtige Datentypen sind Listen und n-Tupel:
Datentyp |
Beschreibung |
Beispiele |
---|---|---|
|
Liste beliebig vieler Elemente beliebigen Typs |
|
|
Ansammlung einer fixen Anzahl an Elementen |
|
Weitere Containerklassen sind set
und dictionary
, welche wir hier noch nicht behandeln möchten.
list
ist ein Datentyp, welcher es erlaubt mehrere Objekte beliebigen Typs in einem Objekt zusammenzufassen. Ferner werden nützliche Funktionen bereitgestellt um auf die Liste zuzugreifen oder diese zu manipulieren. Mit list.<TAB>
bekommen wir einen Überblick. Hier einige elementare Beispiele:
L = [1,3,5] # Liste erzeugen [1,3,5]
L.append(2) # Element anhängen [1,3,5,2]
L = L + [4,6] # Eine weitere Liste anhängen [1,3,5,2,4,6]
L.sort() # Liste sortieren [1,2,3,4,5,6]
L.pop() # Letztes Element entfernen [1,2,3,4,5]
L # Konsolenausgabe
[1, 2, 3, 4, 5]
Interessant ist die Beobachtung, dass der Additionsoperator +
auch für 2 Objekte vom Typ list
definiert ist. Das Ergebnis ist offensichtlich die Konkatenation beider Listen.
Auch um Listen zu erstellen gibt es mehrere Möglichkeiten. Nützlich ist hierbei die Klasse range
(siehe range?
für eine genaue Beschreibung). Einige Beispiele:
L1 = list(range(10)) # Äquivalent zu L1 = [0,1,2,...,9]
print("L1 =", L1, ": enthält", len(L1), "Elemente")
L1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] : enthält 10 Elemente
L2 = list(range(1,11,2)) # Ungerade Zahlen von 1 bis 10
print("L2 =", L2, ": enthält", len(L2), "Elemente")
L2 = [1, 3, 5, 7, 9] : enthält 5 Elemente
Mit einer for
-Schleife können wir über eine Liste iterieren und auf einzelne Elemente zugreifen. Die Syntax einer solchen Schleife lautet
for [elem] in [liste]:
[do something]
Ein einfaches Beispiel:
for a in L:
print("Die Liste enthält", a)
Die Liste enthält 1
Die Liste enthält 2
Die Liste enthält 3
Die Liste enthält 4
Die Liste enthält 5
Übungsaufgabe
Berechne die Summe der Zahlen 1 bis 10. Nutze entweder eine for
-Schleife oder die Funktion sum(...)
.
Um ein einzelnes Element einer Liste zu lesen oder zu schreiben nutzt man den Zugriffsoperator []
. Beachte, dass das erste Element den Index 0 besitzt, das zweite den Index 1, etc..
import random # Zufallszahlengenerator
farben = ['rot', 'blau', 'grün', 'schwarz', 'gelb']
for i in range(3):
index = random.randint(0, len(farben)-1) # Erzeuge Zufallszahl zwischen 0 und 4
farbe = farben[index] # Wähle die entsprechende Farbe
print("Ich seh' etwas, was du nicht siehst, und das ist", farbe)
Ich seh' etwas, was du nicht siehst, und das ist gelb
Ich seh' etwas, was du nicht siehst, und das ist grün
Ich seh' etwas, was du nicht siehst, und das ist grün
Zuletzt untersuchen wir die Klasse tuple
. Diesen Container verwendet man für geordnete Listen einer festen Größe. Diese finden beispielsweise Einsatz bei Funktionen, welche 2 oder mehrere Werte zurückgeben. Diese Werte werden dann als n-Tupel zurückgegeben. Ein Beispiel ist der Betrag \(r\) und das Argument \(\varphi\) von komplexen Zahlen \(z = a+i\,b = r\,e^{i\,\varphi}\):
a = 1+3j
res = cmath.polar(a)
print("Der Rückgabewert", res, "der Funktion 'cmath.polar' ist vom Typ", type(res))
Der Rückgabewert (3.1622776601683795, 1.2490457723982544) der Funktion 'cmath.polar' ist vom Typ <class 'tuple'>
print("Betrag :", res[0])
print("Argument :", res[1])
Betrag : 3.1622776601683795
Argument : 1.2490457723982544
Der Zugriff auf ein Element des Tupels erfolg wieder mit dem Operator []
.
Noch eleganter ist allerdings folgende Schreibweise:
(a_abs, a_arg) = cmath.polar(a)
print("Betrag :", a_abs)
print("Argument :", a_arg)
Betrag : 3.1622776601683795
Argument : 1.2490457723982544
1.2. Klassen und Funktionen¶
In den letzten Abschnitten haben wir schon einige wichtige Konzepte der Programmiersprache Python kennengelernt. Diese wollen wir hier nochmal zusammenfassen.
Klassen
Jedes Objekt, auch Instanz genannt, gehört einer Klasse an, beispielsweise gehört 3.0
zur Klasse float
, "Hallo"
zur Klasse string
und [1,2,3]
zur Klasse list
. Zu welcher Klasse eine Instanz gehört erfahren wir dabei mit der Funktion type(...)
. Wir werden im Laufe dieser Vorlesung noch unzählige weitere Klassen kennenlernen. Wichtig ist an dieser Stelle zu wissen, dass Klassen spezifische Attribute und Operationen für Instanzen dieser Klasse zusammenfassen. Beispielsweise speichert die Klasse complex
den Real- und Imaginärteil einer komplexen Zahl, auf die wir mit
a.real
1.0
zugreifen. Ferner bietet die Klasse aber auch Operationen an um beispielsweise die konjugiert Komplexe zu berechnen (siehe Methoden).
Methoden
Methoden sind Funktionen, welche an Instanzen einer Klasse gekoppelt sind. Diese lassen sich mit
<instance>.<method>(<param1>, <param2> [...])
aufrufen. Ein Beispiel ist die Funktion conjugate()
, welche für Objekte der Klasse complex
definiert ist. Um zu erfahren welche Methoden eine Klasse anbietet, erzeugen wir eine Instanz a
dieser Klasse und tippen a.<TAB>
ins Notebook ein, oder führen die Funktion dir(a)
aus. Die Dokumentation zu einer Methode erhalten wir mit
<instance>.<method>?
Freie Funktionen
Freie Funktionen hingegen sind nicht an eine Klasse gekoppelt, sondern lassen sich ohne Angabe der Instanz aufrufen. Ein Beispiel ist die Funktion sum(...)
. Oft lassen sich diese Funktionen auf Objekte von unterschiedlichen Klassen anwenden. So funktioniert die Funktion sum(...)
für Listen
sum([1,2,3])
6
als auch für Tupel
sum((1,2,3))
6