Grundlagen¶

Beim Erlernen einer neuen Programmiersprache wird immer mit Code begonnen, der "Hello, world!“ schreibt. Im Vergleich zu anderen Sprachen ist dies in Python eher einfach. Wir verwenden die Funktion print und lassen sie den String „Hello, world!“ drucken. Wir werden Strings später besprechen.

In [1]:
print("Hello, world!")
Hello, world!

Eine Funktion ist ein Codeblock, den wir aufrufen können, um basierend auf einer Liste von Argumenten, die wir an die Funktion übergeben, etwas zu tun. Wir werden später sehen, wie wir eigene Funktionen schreiben. Es gibt einige integrierte Funktionen in Python, z. B. max.

In [2]:
max(1, 3, 2)
Out[2]:
3

Ein Operator ähnelt einer Funktion, aber die Syntax ähnelt der, die wir in der Mathematik oder in natürlicher Sprache erwarten würden.

In [3]:
3 + 5
Out[3]:
8

Operatoren werden als Funktionen implementiert, wir werden diese Funktionen jedoch zur Veranschaulichung nur hier direkt aufrufen.

In [4]:
import operator 
# operator ist ein Module das Operatoren implementiert
operator.add(3, 5)
Out[4]:
8

Einer Variable in Python und allgemeiner in der Programmierung kann ein Wert (wie in der Mathematik) oder ein Objekt zugewiesen werden. Der Zuweisungsoperator in Python ist =. Python ist eine dynamisch typisierte Sprache, d. h. wir müssen den Typ einer Variablen nicht angeben. Wenn einer neuen Variablen ein Wert zuweisen wird, wird die Variable erstellt: Variablenname = Wert. Variablennamen müssen mit einem Buchstaben oder einem Unterstrich _ beginnen, sie können jedoch Zahlen enthalten.

In [5]:
my_variable = 3.5
my_variable2 = 5
In [6]:
type(my_variable), type(my_variable2)
Out[6]:
(float, int)

Datentypen¶

Integers sind ganze Zahlen.

In [7]:
x = 5
type(x)
Out[7]:
int

Floats sind reelle Zahlen, welche keine Integers sind.

In [8]:
x = 5.0
type(x)
Out[8]:
float

Boolesche Variablen sind solche die True oder False annehmen.

In [9]:
a = True
b = False
type(b)
Out[9]:
bool

Strings beinhaltet Text. Es können doppelte oder einfache Anführungszeichen verwendet werden, um den Anfang und das Ende eines Strings anzuzeigen.

In [10]:
s = "Hello, world!"
type(s)
Out[10]:
str

Mathematische Operatoren¶

In [11]:
a = 5 + 10 # Addition
b = 5 - 12 # Subtraktion
c = 5 * 15 # Multiplikation
d = 5 / 15 # Division
e = 5 // 15 # ganzzahlige Division
f = 2 ** 5 # hoch

a, b, c, d, e, f 
Out[11]:
(15, -7, 75, 0.3333333333333333, 0, 32)

Logik¶

In [12]:
True and False
Out[12]:
False
In [13]:
not True
Out[13]:
False
In [14]:
True or False
Out[14]:
True
In [15]:
True or True
Out[15]:
True

Vergleichsoperatoren¶

In [16]:
1.5 > 0.5, 2.5 < 0.5, 1 != 1
Out[16]:
(True, False, False)

Objekte können dieselben Werte enthalten, aber an unterschiedlichen Orten im Speicher des Computers gespeichert sein. Dann sind sie nicht identisch.

In [17]:
l1 = [1,2]
l2 = l1
l3 = [1,2]

l1 is l2, l1 is l3, l1 is not l3
Out[17]:
(True, False, True)

Slicing¶

Wir können Teilstrings über ihren Index extrahieren, also die Start- und Endposition innerhalb des Strings. Die Indexierung in Python beginnt bei 0. Mit der Syntax [start:stop] erhalten wir die Zeichen zwischen start und stop-1, also das Zeichen bei Index Stop ist ausgeschlossen.

In [18]:
s = 'Hello, world!'
s[3:9]
Out[18]:
'lo, wo'
In [19]:
s[:]
Out[19]:
'Hello, world!'

Wenn wir negative Zahlen verwenden, beginnt Python mit dem Zählen am Ende der Zeichenfolge.

In [20]:
s[:-2]
Out[20]:
'Hello, worl'

Wir können den String auch schrittweise durchlaufen und beispielsweise nur jedes zweite Zeichen berücksichtigen, indem wir die Syntax [start:stop:step] verwenden.

In [21]:
s[4:12:2]
Out[21]:
'o ol'

Ein negativer step kehrt die Reihenfolge um.

In [22]:
s[::-1]
Out[22]:
'!dlrow ,olleH'

Grundlegende Datenstrukturen¶

Tuple¶

Tupel enthalten Elementen, die nicht unbedingt vom gleichen Typ sein müssen. In Python werden Tupel mit der Syntax (..., ..., ...), oder auch ..., ..., ... erstellt.

In [23]:
t = (True, 2, 'data', 2)
type(t)
Out[23]:
tuple
In [24]:
t = True, 2, 'data', 2
type(t)
Out[24]:
tuple

Wir können auf ein Element dieses Tuples mithilfe des Index zugreifen.

In [25]:
z = t[2]
z
Out[25]:
'data'

Wir können abzählen, wie oft etwas vorkommt.

In [26]:
t.count(2)
Out[26]:
2
In [27]:
t.count(1)
Out[27]:
1

Listen¶

Listen enthalten Elemente beliebigen Typs. Listen sind mutable, d.h. wir können die Liste ändern, ohne eine komplett neue erstellen zu müssen. Die Syntax zum Erstellen von Listen in Python lautet [...].

In [28]:
my_list = [3,2,5,4]

print(type(my_list))
print(my_list)
<class 'list'>
[3, 2, 5, 4]
In [29]:
print(my_list)
print(my_list[1:3])
print(my_list[::2])
[3, 2, 5, 4]
[2, 5]
[3, 5]

range ist nützlich, um einfache Sequenzen zu definieren, die wir dann zum Erstellen einer neuen Liste verwenden können.

In [30]:
start = 10
stop = 30
step = 2

list(range(start, stop, step))
Out[30]:
[10, 12, 14, 16, 18, 20, 22, 24, 26, 28]

Wir können Listen auch modifizieren.

In [31]:
my_list.sort()
print(my_list)
[2, 3, 4, 5]

Wir können auch eine leere Liste erstellen und dieser anschließend Elemente hinzufügen.

In [32]:
w = []
w.append("A")
w.append("d")
w.append("d")

print(w)
['A', 'd', 'd']

Wir können diese Einträge auch verändern.

In [33]:
w[1] = "u"
w[2] = "a"

print(w)
['A', 'u', 'a']

Wir können zwei Listen zusammenfügen.

In [34]:
y = my_list + w
print(y)
[2, 3, 4, 5, 'A', 'u', 'a']

Sets¶

Sets (Mengen) enthalten Elemente, die nicht sortiert sind und zudem kommen keine doppelten Elemente vor. Die Typen der Elemente können unterschliedlich sein.

In [35]:
s = set(['a', 'b', 'c', 'd', 'e', 'f'])
s
Out[35]:
{'a', 'b', 'c', 'd', 'e', 'f'}
In [36]:
t = set(['d', 'e', 'f', 'g'])
t
Out[36]:
{'d', 'e', 'f', 'g'}

Wir können folgende Set-Operationen anwenden:

  • union: Vereinigung zweier Mengen, bestehend aus allen Elementen, die in mindestens einer der beiden Mengen enthalten sind.
  • intersection: Schnitt zweier Mengen, bestehend aus allen Elementen, die in beide Mengen enthalten sind.
  • difference: Differenz zwischen zwei Mengen s und t, bestehend aus allen Elementen, die in s, aber nicht in t enthalten sind.
  • symmetric_difference: Symmetrische_Differenz zwischen zwei Mengen s und t, bestehend aus allen Elementen, die in s, aber nicht in t oder in t, aber nicht in s enthalten sind.
In [37]:
s.union(t)  
Out[37]:
{'a', 'b', 'c', 'd', 'e', 'f', 'g'}
In [38]:
s.intersection(t)  
Out[38]:
{'d', 'e', 'f'}
In [39]:
t.difference(s)  
Out[39]:
{'g'}
In [40]:
s.symmetric_difference(t)  
Out[40]:
{'a', 'b', 'c', 'g'}

Dictionaries¶

Dictionaries ähneln Listen, mit der Ausnahme, dass jedes Element einen Schlüssel hat. Die Syntax für Dictionaries lautet {key1 : value1, ...}.

In [41]:
dict_ = {"Markus" : 1, "Sandra" : 2, "Bob" : 3}

print(type(dict_))
print(dict_)
print(dict_['Bob'])
<class 'dict'>
{'Markus': 1, 'Sandra': 2, 'Bob': 3}
3
In [42]:
print(list(dict_.keys()))
print(list(dict_.values()))
['Markus', 'Sandra', 'Bob']
[1, 2, 3]

Typecasting¶

Dies bezeichnet die Typumwandlung.

In [43]:
n = "9"
n = int(n)
n += 1       # Abkürzung für n = n + 1
print(n)
10

Conditional Statements¶

Conditional Statements ermöglichen es uns, die Ausführung von Code von Bedingungen abhängig zu machen.

In [44]:
condition1 = False
condition2 = False

if condition1:
    print("condition1 is true")
    
elif condition2:
    print("condition2 is true")
    
else:
    print("both condition1 and condition2 are false")
both condition1 and condition2 are false
In [45]:
condition1 = True
condition2 = True

if condition1:
    if condition2:
        print("both condition1 and condition2 are true")
both condition1 and condition2 are true
In [46]:
condition1 = False 

if condition1:
    print("printed if condition1 is true")
    
    print("inside the if block")
print("outside the if block")
outside the if block

Schleifen¶

Schleifen werden verwendet, um Code öfter auszuführen. In Python können Schleifen mit der for- oder der while-Schleife programmiert werden.

In [47]:
for x in [0,1,2]:
    print(x)
0
1
2
In [48]:
for x in range(3): # per default range startet bei 0; range(3) inkludiert keine 3
    print(x)
0
1
2
In [49]:
for key, value in dict_.items():
    print(key + " = " + str(value))
Markus = 1
Sandra = 2
Bob = 3
In [50]:
title = ["Statistik", "Wahrscheinlichkeit"]

i = 0

while i < len(title):
    print(title[i])
    
    i = i + 1
Statistik
Wahrscheinlichkeit

Funktionen¶

Funktionen werden in der Programmierung für wiederverwendbaren Code verwendet, der eine Aufgabe kapselt. Eine Funktion in Python wird mit dem Schlüsselwort def definiert, gefolgt von einem Funktionsnamen, Klammern mit Input der Funktion (input) und einem Doppelpunkt :. Der folgende Code, der eingerückt werden muss, ist der Funktionskörper.

In [51]:
def nothing():   
    print("This is a function doing nothing.")
       
nothing()
This is a function doing nothing.
In [52]:
def half(x):
    """
    Return the half of x.
    """
    return x/2

half(4)
Out[52]:
2.0

Es können auch mehrere Werte zurückgegeben werden.

In [53]:
def fractions(x):
    """
    Return one-half, one-third, and one-quarter of x.
    """
    return x/2, x/3, x/4

fractions(15)
Out[53]:
(7.5, 5.0, 3.75)

In einer Funktion können wir auch Default-Werte definieren.

In [54]:
def power(x, p=2):
    return x**p

power(4)
Out[54]:
16
In [55]:
power(p=2, x=3)
Out[55]:
9

Lokale Variablen¶

Variablen, die in einer Funktion definiert werden, sind lokale Variablen.

In [56]:
def times_two(x):
    y = 2
    return y * x

y = 10
z = 2
times_two(z)
    
Out[56]:
4

NumPy¶

NumPy ist eine geläufige Bibliothek in Python und eignet sich für den Umgang mit Vektoren und Matrizen. array und ndarray sind die geläufigen Datenstrukturen in NumPy.

NumPy wird wie folgt geladen:

In [57]:
import numpy as np

Ein array wird mit np.array([...]) erzeugt.

In [58]:
list_ = [1.9, 1.6, 1.4, 3.5, 3.5]
x = np.array(list_)
x
Out[58]:
array([1.9, 1.6, 1.4, 3.5, 3.5])
In [59]:
type(x)
Out[59]:
numpy.ndarray
In [60]:
y = np.array([[1, 2], [3, 4]])
y
Out[60]:
array([[1, 2],
       [3, 4]])

Die Anzahl an Dimensionen erhalten wir mit ndim.

In [61]:
x.ndim
Out[61]:
1
In [62]:
y.ndim
Out[62]:
2
In [63]:
y.shape
Out[63]:
(2, 2)

Die Funktion size gibt die Anzahl an Elementen im array an.

In [64]:
y.size
Out[64]:
4

Die Funktion linspace hat die Inputs start, stop und num. Der letzte Input gibt die Anzahl an Elementen an, welche gleichmäßig zwischen start und stop aufgeteilt sind.

In [65]:
ls = np.linspace(1,5,6)
ls
Out[65]:
array([1. , 1.8, 2.6, 3.4, 4.2, 5. ])

In NumPy gibt es eine max und min Funktion.

In [66]:
y.min()
Out[66]:
1
In [67]:
y.max()
Out[67]:
4

NumPy hat auch eine Funktion cumsum oder cumprod, die die kumulierte Summe bzw. Produkt ausgeben.

In [68]:
ls.cumsum()
Out[68]:
array([ 1. ,  2.8,  5.4,  8.8, 13. , 18. ])

Pandas¶

Die Pandas-Bibliothek bietet nützliche Datenstrukturen und Tools für die Datenanalyse. Die wichtigsten von Pandas angebotenen Datenstrukturen sind Series und DataFrame.

In [69]:
import pandas as pd

y = pd.DataFrame(y)
y
Out[69]:
0 1
0 1 2
1 3 4

Den Index erhälten wir mit index.

In [70]:
y.index
Out[70]:
RangeIndex(start=0, stop=2, step=1)
In [71]:
y.index = ["a", "b"]
y
Out[71]:
0 1
a 1 2
b 3 4

Die Spalten können mit rename umbenannt werden.

In [72]:
y.rename(columns={0: "x", 1: "y"}, inplace=True)
y
Out[72]:
x y
a 1 2
b 3 4

Auch in Pandas gibt es unterschiedliche Funktionen, die auf einem DataFrame angewendet werden können. Z.B. die max Funktion.

In [73]:
y.max()
Out[73]:
x    3
y    4
dtype: int64
In [74]:
y.max(axis=1)
Out[74]:
a    2
b    4
dtype: int64