*Dieses Buch ist immer noch "Work in Progress", aber eines Tages soll es das "perfekte Python Buch für blutige Anfänger" werden, die Textanalyse lernen wollen.*

Dieses Buch ist für all diejenigen, die blutige Anfänger in Programmierung oder Data Science sind. Bis zum Ende des Buches werden dir all diese Punkte näher gebracht:

  • Programmierung
  • Verschiedene Methoden der Analyse von schriftlichen Werken
  • Erstellung von hübschen und einfach verständlichen Statistiken
  • 3D Grafen und Statistiken mit Animationen

Falls du ein blutiger Anfänger in Python sein solltest, dann lohnt es sich über das Kapitel Grundlagen zu gehen, sonst nutze dieses Buch gerne als Nachschlagewerk und springe zu den Kapitel, die dich interessieren.

Ziel dieses Buches ist es, das Verständnis dafür zu entwickeln, wie wir mit Python Texte analysieren, um wertvolle Erkenntnisse aus großen Textmengen zu extrahieren.

Was ist Python?

Python ist eine general-purpose language, oder Allzwecksprache auf Deutsch.

Das heißt wir können Python für so ziemlich alles verwenden. Zudem ist Python auch high level. "High level" kann man auch als "einfach" übersetzen. Programmierer kategorisieren Computersprachen in zwei Kategorieren: "high level" und "low level". "low level" bedeutet, dass etwas sehr nah an der "Maschine" ist. Sprich wenn ich "low level code" schreibe, dann könnte das bedeuten, dass ich mir mehr Gedanken machen muss, über Syscalls (Exekutionen die das Betriebssystem macht) oder ob etwas im "Stack" oder "Heap" vom RAM (Random Access Memory) gespeicher wird. Wenn du gerade nichts verstanden hast, dann ist das vollkommen ok, weil wir Python Code schreiben werden und weil Python "high level" ist, müssen wir nichts von diesen Sachen beachten und können, ohne komplette Computernerds zu sein, Code schreiben!

In anderen Worten: Low level = schwierig und High level = einfach.

Im Laufe des Buches werden wir uns auf Textanalyse, ein kleiner Teil von Datascience, konzentrieren, aber wir können mit Python auch Mobileapps, Videospiele, usw., so ziemlich alles, sogar Webseiten programmieren. Alle Skills, die du in diesem Buch lernen wirst, kannst du somit auch auf andere Bereiche anwenden und somit dein Horizont "ganz einfach" erweiteren und vielleicht sogar eine Karriere aufbauen.

Weil es nicht schaden kann, hier noch ein paar Fakten zu Python von Wikipedia:

  • Python wurde 1980 von Guido van Rossum erfunden.
  • Python ist Open Source, sprich komplett kostenlos
  • Python ist die beliebteste Sprache für Datascience und Machine Learning

Ein großer Vorteil von Python ist, dass der Code sehr an der normalen englischen Sprache erinnert und somit einfach verständlich ist, auch für diejenigen, die noch nie programmiert haben.

# Eine Liste von Zahlen erstellen
numbers = [1, 2, 3, 4, 5]

# Gesamtwert initialisieren
sum = 0

# Schleife durch jede Zahl in der Liste
for number in numbers:
    # Hinzufügen der Zahl zur Summe
    sum += number

# Ausgabe der Gesamtsumme
print("Die Summe der Zahlen ist:", sum)

In diesem Codebeispiel rechnen wir das Ergebnis aller Zahlen zusammen und geben das Ergebnis in einer Konsole aus.
Hier ist der Output des Codes:

Die Summe der Zahlen ist: 15

Vielleicht verstehst du nicht alles sofort von diesem Codebeispiel. Darum geht es auch gar nicht. Das werden wir in den nächsten Kapiteln noch lernen. Mit dem Codebeispiel wollte ich dir nur mal zeigen wie leicht verständlich Pythoncode auch für totale Programmieranfänger sein kann.

Inhaltsverzeichnis


Python

Installiere Python

Um in Python programmieren zu können, sollte Python auch auf deinem System installiert sein. Glücklicherweise kann man Python so ziemlich auf alles installieren, vorallem auf Windows, macOS oder Linux.

Hier habe ich jeweils Anleitungen für die drei meist vebreiteten Betriebsystemen:

Windows

Downloade den latest Python Installierer für Windows von python.org und führe die .exe Datei aus.

Momentan gibt es mit ein paar Packages, die wir in späteren Kapitel für die programmatische Textanalyse brauchen, die neurere Version als 3.12 von Python nicht mehr supporten. Dies kann sich jederzeit, von einem Tag zum anderen ändern. Also wenn du Probleme haben solltest, dann probiere Python 3.12 zu installieren!

Wenn du die gedownloadete ".exe" Datei ausführst, dann siehst du dieses Fenster:

Hier kannst du, so wie ich, einfach alles ankreuzen. Aber gehe sicher, dass "Add python.exe to PATH" angekreuzt ist, damit können wir nach der Installation Python in der "cmd"-Konsole ausführen.

Und das wars auch schon!

Wenn du "Setup was successfull" siehst, dann hat alles geklappt. Vielleicht siehst du noch im selben Fenster, wie ich hier, einen Text mit "Disable path length limit". Klicke einmal drauf, und die Meldung sollte dann auch von selber verschwinden.

Jetzt öffne "cmd" Konsole und gebe python --version ein. Genauso wie ich hier:

Wenn du Python <irgendeine version> sehen kannst, dann hast auch wirklich alles geklappt. Alternativ kannst du auch Python schon vom Windows Startmenü öffnen, aber dies öffnet dann die "REPL". Was das ist werden wir noch lenern!

Jetzt wo Python erfolgreich installiert wurde, können wir im nächsten Kapitel uns darum kümmern einen Texteditor zu installieren.

macOS

Auf macOS sollte Python schon vorinstalliert sein, also musste hier nichts machen. Um zu schauen, ob es auch wirklich auf deinem Mac installiert ist, gebe diesen Befehl ein:

python3 --version

Um Python Skripte, die wir hier schreiben, auf einen Mac auszuführen, musst du immer python3 anstelle python eingeben!

Oder du kannst einen "alias" erstellen, dass wenn du immer "python" eingibst, automatisch "python3" ausgeführt wird, dazu musst du nur diesen Befehl hier im Terminal ausführen:

echo 'alias python="python3"' >> ~/.zshrc

homebrew

Aber falls du eine neuerer Version von Python brauchst, dann kannst du diese ganze einfach mit dem "homebrew" Package Manager installieren. Dafür müssen wir erstmal homebrew installieren.

Öffne den Terminal und tippe diesen Befehl in die Konsole:

xcode-select --install

Dies installiert alle "basic tools", die du brauchst fürs Programmieren.

Danach gehe auf die brew.sh Website und kopiere den Befehl unter Install Homebrew. Der müsste ungefähr so aussehen:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Achtung! Dieser Befehl downloadet ein Installations-skript und führt es auf deinem Computer aus, um homebrew auf deinen Mac zu installieren. Obwohl es relativ sicher ist, ist dies theoretisch sehr gefährlich einfach so Skripts zu downloaden und auszuführen. Also gehe sicher, dass du diesen Befehl von der originalen brew.sh Website kopierst!

Wenn homebrew erfolgreich installiert wurde, siehst du im Terminal die nächsten Schritte, die du machen musst, damit du auch homebrew benutzen kannst. In meinem Fall es drei Befehle:

echo >> /Users/marc/.zprofile
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/marc/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)

Achtung! Mein User hier heißt marc und deswegen sind deine drei Befehle wahrscheinlich ein bisschen anders!

Jetzt kannst du im Terminal brew doctor eingeben, um sicher zu gehen, dass alles richtig installiert wurde.

Nun kannst du mit nur einem Befehl Python installieren.

brew install python

Um sicher zu gehen ob Python auch funktioniert gebe python --version ein, um die installierte Version von Python ausgespuckt zu bekommen.

Ubuntu

Auf Ubuntu und wahrscheinlich jedem anderen Linux basierten Betriebsystem sollte Python vorinstalliert sein. Wenn nicht, dann kannst du es auf Ubuntu-basierten Systemen mit diesem Befehl hier installieren:

sudo apt install python

Fertig! Zum Testen gebe python --version ein, um zu schauen ob es auch richtig installiert wurde.

Einführung in python

python

Schreibe Code in REPL

exit()

unter macOs und Windows einfach, aber windows?

erstelle main.py mit print("Hello World")

$ python main.py

VScode

Installation

Installiere VScode, indem du auf dieser Webseite den richtigen Installer für dein Betriebssystem downloadest und die Installations Datei ausführst.

Windows

macOS

Ubuntu

Windows

macOS

Ubuntu

Einführung in

Öffne VScode

erstelle einen Projektordner

erstelle main.py

print("Hello World")

führe die main.py aus

So jetzt müsste alles richtig eingerichtet sein und wir können uns darauf konzentrieren Python und die Basics der Programmierung zu lernen.
Also Let's go!

Grundlagen

Jetzt können wir anfangen coden zu lernen! Im diesen Kapitel lernen wir die ganzen Basics, die man kennen sollte, bevor wir mit den ersten realen, praktischen Anwendungsbeispiel anfangen: der programmatischen Textanalyse. Aber "gut Ding braucht gut Weile". Fangen wir erstmal mit Variablen an.

Variablen

Variablen, den Begriff kennen wir schon von der Mathematik. Es bedeutet, dass ein Wert variabel ist, also sich verändern kann. Zum Beispiel die Variable x in y = x + 2 ist ein Platzhalter für beliebig vielen Werten.

Auch so in der Programmierung sind Variablen als eine Art "Platzhalter" oder viel mehr "Zwischenspeicher" für einen Wert, zu verstehen.

Aber durch Theorie allein kann man nur schwer lernen oder etwas verstehen, also lass uns eine Variable erstellen, die mein jetziges Alter "zwischenspeichert".

my_age = 25

Ich habe hier eine Variable mit den Namen my_age erstellt (in Programmierfachchinesisch nennt man das auch "deklarieren").

my_age bekommt den Wert 25 zugewiesen. Um in Python eine Variable zu deklarieren, dürfen wir das = nicht vergessen, dadurch weiß Python überhaupt erst, dass my_age eine Variable ist. Ohne das = könnte Python unser Code nicht verstehen und wir würden einen Error bekommen.

Wenn ich jetzt mein Alter wissen möchte (weil ich es wieder einmal vergessen habe, was mir oft passiert...), dann kann ich darauf zugreifen, indem ich in einer späteren Zeile im Skript einfach nur my_age schreibe.

Mit dem print Befehl können wir die my_age Variable in der Konsole ausgeben. Machen wir das einmal:

my_age = 25
print(my_age)

Wenn wir unser Skript ausfüheren, dann sehen wir folgendes in der Konsole:

25

Überall wo wir jetzt my_age brauchen, können wir, anstelle immer wieder 25 zu schreiben, my_age schreiben. Der Vorteil ist, wenn wir unser Code für einen anderen User anpassen möchten, dann müssen wir nur die Zeile, in der wir my_age deklariert haben, anpassen.

Datentypen

Neben Zahlen können wir auch Variablen für Text, Listen und viele, viele anderen Dinge erstellen.

In diesen Kapitel gehen wir Schritt für Schritt über die wichtigsten Datentypen von Python und wie man mit diesen arbeiten kann.

Hier schonmal eine kleine Übersicht von all den Datentypen, die ich dir näher bringen werde:

DatentypEin-Wort-Erklärung
NumberZahl
BooleanWahr oder Falsch
StringText
ListListe an Werten
TupleUnveränderbarde Liste an Werten
DictionaryKey und Value Liste

Den Typ einer Variable können wir mit dem type Befehl heraus bekommen. Zum Beispiel hier einmal der Datentyp von der Variabel my_age, die wir im letzten Kapitel erstellt haben.

print(type(my_age))
<class 'int'>

Mit dem print Befehl um type(my_age) gehe ich auch sicher, dass der Typ in der Konsole ausgespuckt wird.

Number

Einer der wohl wichtigsten und offensichtlichsten Datentypen einer Programmiersprache ist die Nummer oder auch Zahl.

In Python, sowie auch in vielen verschiedenen Programmiersprachen, gibt es zwei verschiedene Arten von Zahlen.

  • Integer sind Ganzzahlen, z.B. 420 oder -69 und so weiter...
  • Float sind Gleitkommazahlen, z.B. 24.7 oder -4.2069

Beachte: Python benutzt . für die Gleitkommazahlen, wie in der englischen Sprache.

Egal ob integer oder float mit beiden Zahlentypen können wir ganz normal rechnen:

Plus +

x = 5
y = 3.5
z = x + y
print(z)
8.5

Minus -

x = 5
y = 3.5
z = x - y
print(z)
1.5

Mal *

x = 5
y = 3.5
z = x * y
print(z)
17.5

Geteilt /

x = 5
y = 3.5
z = x / y
print(z)
1.4285714285714286

Hoch **

x = 5
y = 3.5
z = x ** y
print(z)
279.5084971874737

Modulus %

Der Modulus % wird verwendet, um den Rest einer Division zu berechnen.

Kannst du dich vielleicht noch erinnern, wie du in der Grundschule geteilt rechnen gelernt hast und am Ende der Rechnung den Rest angegeben hast, z.b. 5 / 2 = 2 Rest 1.

Der Modulus funktioniert genau so, aber dass wir nur den Rest bekommen! Also 5 % 2 gibt uns die Zahl 1 oder 11 % 3 ergibt 2.

Zum Beispiel können wir den Modulus verwenden, um zu erkennen ob eine Zahl gerade oder ungerade ist, denn wenn x % 2 null ergibt, dann ist die Zahl durch zwei teilbar und wenn es eins ergibt, dann eben offensichtlicher Weise nicht.

print(5 % 2)
print(8 % 2)
1
0

Noch mehr Mathe mit dem math Modul

Falls man aber noch mehr Mathe machen möchte als nur Plus, Minus oder Geteilt, dann lohnt sich ein Blick in das "Math" Modul.

Zu aller erst müssen wir "math" importieren. Schreibe dafür dies hier ganz oben als erste Zeile in der .py Skript Datei.

import math

math.ceil()

Mit math.ceil() können wir eine Zahl, die wir innerhalb der () Klammern packen, aufrunden.

x = math.ceil(9.3)
print(x)
10

math.floor()

Oder mit math.floor() können wir eine Zahl abrunden:

x = math.floor(9.3)
print(x)
9

math.trunc()

math.trunc() schneidet alles nach der Kommastelle weg, damit wir eine Ganzzahl bekommen.

x = math.trunc(9.3)
print(x)
9

math.exp()

math.exp() gibt uns das Ergebnis von "e hoch x":

x = math.exp(9)
print(x)
8103.083927575384

math.sqrt()

Ziehe die Wurzel von einer Zahl:

x = math.sqrt(9)
print(x)
3.0

math.cos()

Berechne den Kosinus von einer Zahl:

x = math.cos(0)
print(x)
1.0

Noch mehr Information zum "Math" Modul findest du hier.

Übungsaufgaben

Hier ein paar Übungsaufgaben, die du nun lösen kannst, um deine Programmierskills auf die Probe zustellen!

  1. Berechne die gesamte Anzahl an Tagen anhand des Alters einer Person.
Zeige Lösung
  1. Berechne wie viele Sekunden X Stunden hat, wo X eine beliebige Zahl ist.
Zeige Lösung
  1. Ermittle anhand des Geburtsjahres wie alt eine Person ist
Zeige Lösung
  1. Ermittle den Rest einer Division von zwei Zahlen
Zeige Lösung
  1. Berechne den Flächeninhalt eines Dreiecks (a: 5cm, b: 5cm, c: 10cm)
Zeige Lösung

Boolean

Den nächsten Datentyp, den wir lernen werden, ist der Boolean.

Ein Boolean kann nur zwei mögliche Werte haben kann: "wahr" also True oder "falsch" also False.

Stelle dir einen Boolean wie einen Lichtschalter vor, der entweder ein- oder ausgeschaltet sein kann. In diesem Fall ist "eingeschaltet" True und "ausgeschaltet" False.

In der Programmierung sind Booleans nützlich, um Entscheidungen zu treffen oder den Ablauf eines Programms zu steuern. Zum Beispiel kann man Booleans verwendet, um zu bestimmen, ob ein Kunde erlaubt ist von einem Onlineshop Alkohol zu kaufen oder ob der User sein Programm in Light oder Dark Theme eingestellt hat.

is_light_theme = True
user_can_buy_alcohol = False

Die bool Funktion

Mit der bool können wir so ziemlich fast alles und auch Variablen zu einem boolean umkonvertieren.

x = 42
x_as_bool = bool(x) 

print(x_as_bool)
True

Warum 42 zu True wird, werden wir im nächsten Kapitel lernen!

Logische Operatoren

Logische Operatoren sind spezielle Symbole, die in der Programmierung verwendet werden, um logische Vergleiche zwischen zwei oder mehreren Ausdrücke zu machen.

In anderen, einfacheren Worten: ein Logischer Operator ist wie eine Behauptung, die entweder wahr oder falsch sein kann. Wenn ich behaupte, dass die Corona Impfung ein Versuch von Bill Gates sei, die Menschheit zu unterjochen, dann ist die Aussage entweder True oder False. :P

Hier eine Tabelle von allen Logischen Operatoren, die es in Python gibt. Einige sollten dir vom Mathe Unterricht bekannt sein:

OperatorBedeutung
andund
oroder
==gleich
!=nicht gleich
notnicht
<kleiner als
>größer als
<=kleiner gleich
>=größer gleich

Aber keine Sorge, ich gehe über jeden Operator und gebe dir ein Beispiel, wie man es benutzt.

and

print(True and False)
False

Der "und"-Operator überprüft ob die beiden Werte, links und rechts, True sind.

Zum Beispiel wir wollen überprüfen ob ein Kunde, der Alkohol kaufen möchte, über 18 ist und einen Ausweis mit sich trägt. Nur wenn beides der Fall ist, können wir ihm guten Gewissens Alkohol verkaufen:

is_adult = True
has_passport = False

print(is_adult and has_passport)
False

Aber erst wenn ein Kunde unseren Onlineshop besucht und beides erfüllt, können wir endlich Profit mit unserem Alk machen.

is_adult = True
has_passport = True

print(is_adult and has_passport)
True

or

print(True or False)
True

Der "oder"-Operator überprüft ob links oder rechts True ist. Nur eine der beiden Seiten muss True sein, damit die Aussage als True gilt.

Zum Beispiel in einer Dating App möchte ich mit Personen gematched werden, die entweder Hunde oder Katzen mögen.

likes_cats = True
likes_dogs = False

print(likes_cats or likes_dogs)
True

==

print(True == False)
False

Der "gleich"-Operator überprüft ob die linke Seite identisch mit der rechten Seite ist. Wir können auch Zahlen und alle anderen Datentypen, die wir noch lernen werden, damit vergleichen.

my_age = 25
your_age = 28

print(my_age == your_age)

your_age = 25 ## Überschreibe your_age mit 25

print(my_age == your_age)
False
True

!=

print(True != False)
True

Das selbe wie beim "gleich" können wir auch hier machen, aber umgedreht mit dem "nicht-gleich"-Operator. Dieser checkt ob die linke Seite nicht gleich mit der rechten Seite ist.

my_age = 25
your_age = 28

print(my_age != your_age)

your_age = 25 ## Überschreibe your_age mit 25

print(my_age != your_age)
True
False

not

print(not True)
False

Der "nicht"-Operator tut einen "boolischen" Wert (True oder False) umdrehen. So wie wir es oben im Beispiel sehen können, wo True mit not zu False umkonvertiert wird. Schauen wir uns weitere Beispiel des "nicht"-Operator an!

not True  ## -> False
not False ## -> True
not 42    ## -> False
not 0     ## -> True
not -42   ## -> False

Du fragst dich jetzt bestimmt warum not 0 True ist und warum not 42 sowie not -42 False ist. In vielen Programmiersprachen wird die Zahl 0 als False behandelt, während alle anderen Zahlen (sowohl positive als auch negative) als True behandelt werden.

Nun, da alle anderen Zahlen (außer 0) als True gelten, sind sowohl 42 als auch -42 wahr. Wenn wir den "nicht"-Operator auf 42 und -42 anwenden, kehren wir ihre Werte um, daher werden sowohl not 42 als auch not -42 zu False.

Wir können auch sebstverständlich den "nicht"-Operator an Variablen verwenden.

is_r_cool = False
print(not is_r_cool)
True

<

print(42 < 24)
False

Das "kleiner als"-Symbol wird verwendet, um zwei Zahlen miteinander zu vergleichen. Wenn die Zahl auf der linken Seite des Symbols kleiner ist als die Zahl auf der rechten Seite, dann ist die Aussage True oder andernfalls False.

>

print(42 > 24)
True

Das selbe auch beim "größer als"-Symbol.

<=

print(42 <= 24)
False

Das "kleiner gleich"-Symbol tut nicht nur True geben, wenn die linke Seite kleiner ist als die rechte, sondern auch wenn die linke Seite gleich der rechten Seite ist.

print(42 <= 43)
print(42 <= 42)
print(42 <= 41)
True
True
False

>=

print(42 >= 24)
True

Das selbe auch beim "größer gleich"-Symbol.

print(42 >= 43)
print(42 >= 42)
print(42 >= 41)
False
True
True

Im nächsten Kapitel werden wir all diese Operatoren verwenden, um mit Hilfe von if und else in unserem Programm Entscheidungen treffen zu können.

if und else

Mit if und else können wir innerhalb unseres Programmes Entscheidungen treffen, um eine Aktion auszuführen, wenn eine bestimmte Bedingung erfüllt ist und eine andere Aktion, wenn die Bedingung nicht erfüllt sein sollte.

number = 5

if number % 2 == 0:
    print("number is even")
else:
    print("number is odd")

Nach dem if-Schlüsselwort folgt ein Aussage, die sich entweder zu True oder False auflöst. In der nächsten Zeile ist, der Code, der ausgeführt werden soll, wenn die Aussage True ist, indentiert mit einem Tab. Wenn aber die Aussage False ist, wird der else Block ausgeführt.

Also nochmal einfacher erklärt mit einem Pseudocode-Beispiel:

if this_is_true:
    do_this()
else:
    do_that()

Im Beispiel von ganz oben wird "number is even" in der Console ausgegeben, wenn der Rest von number geteilt durch zwei null ist, also die Zahl gerade ist und wenn dies nicht der Fall ist, dann wird "number is odd" ausgegeben.

Wir können auch mehrere if's hintereinander reihen um mehrere Bedingungen Schritt für Schritt zu überprüfen.

if this_is_true:
    do_x()
elif or_this_is_true:
    do_y()
else:
    do_z()

elif steht hierbei für else if, oder auch "oder wenn" auf Deutsch.

Lass uns ein Beispiel schreiben, bei dem in der Console eine Nachricht geschrieben wird, wenn die Zahl positiv, negativ oder null ist.

number = -7

if number < 0:
  print("Number is negative.")
elif number > 0:
  print("Number is positive.")
else:
  print("Number is null.")

Als erstes checken wir ob die Zahl kleiner als null ist, dann printen wir "Number is negative" und wenn die Zahl größer als null ist, dann printen wir "Number is positive". Wenn beides nicht der Fall ist, also beide Aussagen False sind dann wird der else Block ausgeführt und logisch können wir ab diesen Punkt ab an davon ausgehen, dass die Zahl 0 sein muss!

Wir sind aber nicht verpflichtet ein else zu verwenden am Ende einer if-Kette.

do_x()

if this_is_true:
    do_y()

do_z()

So können wir zum Beispiel erst x machen und wenn die if-Aussage True ist, dann machen wir auch y, aber wenn es False ist, naja, dann machen wir halt y nicht und ungeachtet der if Aussage, machen wir z als nächstes.

Übungsaufgaben

Hier ein paar Übungsaufgaben mit if und else:

  1. Überprüfe, ob eine Zahl positiv, negativ oder null ist und gib eine entsprechende Meldung aus.
Zeige Lösung
user_input = input("Gebe bitte eine ganze Zahl ein: ")
number = int(float(user_input))

if number > 0:
    print("Zahl ist positiv")
elif number < 0:
    print("Zahl ist negativ")
else:
    print("Zahl ist null")
  1. Überprüfe, ob eine Zahl gerade oder ungerade ist
Zeige Lösung
user_input = input("Gebe bitte eine Zahl ein: ")
number = float(user_input)

if number % 2 == 0:
    print("Zahl ist gerade")
else:
    print("Zahl ist ungerade")
  1. Vergleiche zwei Zahlen und gib an, welche größer ist.
Zeige Lösung
number_one = float(input("Gebe bitte die erste Zahl ein: "))
number_two = float(input("Gebe bitte die zweite Zahl ein: "))

if number_one > number_two:
    print(number_one, "ist groesser als", number_two)
else:
    print(number_two, "ist groesser als", number_one)
  1. Überprüfe, ob eine Zahl in einem bestimmten Bereich liegt (z.B. zwischen 10 und 20).
Zeige Lösung
number = int(input("Gebe bitte eine ganze Zahl ein: "))

if number >= 10 and number <= 20:
  print(number, "liegt zwischen 10 und 20")
else:
  print(number, "liegt nicht zwischen 10 und 20")
  1. Schreibe eine Bedingung, die prüft, ob eine Zahl durch eine andere ohne Rest teilbar ist, also ein ganzzahliges Vielfaches der anderen ist.
Zeige Lösung
number_one = float(input("Gebe bitte die erste Zahl ein: "))
number_two = float(input("Gebe bitte die zweite Zahl ein: "))

if number_one % number_two == 0:
    print(number_one, "ist ein Vielfaches von", number_two)
elif number_two % number_one == 0:
    print(number_two, "ist ein Vielfaches von", number_one)
else:
    print(number_one, "und", number_two, "sind keine Vielfache von sich")
  1. Erkenne aus 3 Zahlen welche davon die größte ist und welche davon die kleinste ist
Zeige Lösung
  1. Empfehle aufgrund des Alters einer Person einen Film
Zeige Lösung

match

Normal

match x:
    case 10:
        # ...
    case 20:
        # ...
    case _:
        # ...

String

match greeting:
    case "hi":
        # ...
    case "hello":
        # ...
    case _:
        # ...

Grouping

match x:
    case 10 | 20 | 30:
        # ...
    case _:
        # ...

Mit if statement

match x:
    case x_even if x % 2 == 0:
        # ...
    case _:
        # ...

Listen und Dictionaries lernen wir erst in den folgenden Kapiteln. TODO: Verschiebe es und erkläre Patternmatching hier

Mit Listen

match my_list:
    case [a, b, c]:
        # ...
    case [a, b, c, d]:
        # ...
    case _:
        # ...

Mit Dictionaries

match my_dict:
    case { "name": name, "age": age }:
        # ...
    case _:
        # ...

String

Ein String, auf Deutsch Zeichenkette, ist einfach nur Text... Damit Python Text auch als string erkennen kann, müssen wir den Text mit " oder ' einkapseln.

Beispieltext mit ":

name = "Marc"

oder mit ':

name = 'Marc'

aber, wenn wir die " oder ' vergessen, dann bekommen einen Error:

name = Marc
Traceback (most recent call last):
  File "/home/marc/main.py", line 1, in <module>
    name = Marc
           ^^^^
NameError: name 'Marc' is not defined
make: *** [Makefile:8: start] Error 1

Python denkt, dass Marc eine Variable ist, aber natürlich gibt es Marc als Variable nicht, weswegen wir den Error 'Marc' is not defined bekommen.

Ein string kann auch ein Satz sein, ergo Leerzeichen innerhalb der " oder ' sind erlaubt!

name = "Marc Mäurer"

Wie dir vielleicht aufgefallen ist, haben wir die " Syntax auch schon beim print Befehl benutzt.

Wir können auch "multi-line strings" mit drei """ erstellen:

lorem_ipsum = """Lorem ipsum.
Soluta aut quo tempore quisquam corrupti cum velit deserunt. 
Sint ea fugiat eaque aut. 
Autem ea suscipit voluptas omnis est. 
Et sit id sit aperiam aut ut. 
Fuga rerum qui consequatur reiciendis.
"""

in

Mit den in Operator kann man schauen ob ein "Substring" in einem "String" ist, zum Beispiel ob "Hello" in "Hello World" ist.

Sprich "Hello" in "Hello World" ist True und "Justice" in "Hello World" wäre dementsprechend False.

x = "Hello World"
is_world_in_x = "World" in x
print(is_world_in_x)
True

List

Stell dir eine Liste wie eine stink-normale Einkaufsliste vor. In dieser Liste können viele verschiedene Sachen drinne stehen, wie z.B. "Ketchup" "Tomaten" "Paprika" etc...

Um eine Liste in Python zu erstellen benutzen wir den [] Klammern und innerhalb der [] Klammer kommen mit einem Komma getrennt alle Werte rein.

einkaufsliste = ["Ketchup", "Tomaten", "Paprika", "Banane"]
print(einkaufsliste)
["Ketchup", "Tomaten", "Paprika", "Banane"]

In einer Liste kann alles rein, Zahlen, Strings, Booleans, komplett egal was. Hier zum ein Beispiel eine Liste an Zahlen:

numbers = [23, 63, 39, 35, 84, 58]
print(numbers)
[23, 63, 39, 35, 84, 58]

Oder hier eine "gemischte" Liste von verschiedenen Datentypen:

numbers = ["Python", True, 42, False, -10]
print(numbers)
["Python", True, 42, False, -10]

Mit der len Funktion können wir herausfinden wie lang eine Liste ist. Hier zum Beispiel die Länge unserer einkaufsliste

len(einkaufsliste)
4

Indexing

Wenn wir jetzt wissen wollten was an einer bestimmten Stelle in unserer Einkaufsliste steht, dann brauchen wir die [] Klammern. Innerhalb der [] Klammern kommt dann die Zahl für welchen Index wir den Wert haben wollen. Dabei fangen wir bei 0 and zu zählen, sprich 0 ist der erste Wert, 1 ist der zweite und so weiter.

print(einkaufsliste[0])
print(einkaufsliste[1])
print(einkaufsliste[2])
print(einkaufsliste[3])
Ketchup
Tomaten
Paprika
Banane

Mit einer Minuszahl können wir rückwärts der Liste entlang gehen:

print(einkaufsliste[-1])
print(einkaufsliste[-2])
print(einkaufsliste[-3])
print(einkaufsliste[-4])
Banane
Paprika
Tomaten
Ketchup

Coole Funktionen mit Listen

Listen geben uns viele coole, hilfreiche Funktionen zur Verfügung. Als aller erstes lass uns eine neue Liste erstellen:

my_list = [1, 2, 3, 4]
.append(5)                ### Füge Value am Ende einer Liste hinzu
.pop(1)                   ### Entferne letztes Item wenn leer oder Item am Index
.remove("yeah")           ### Entferne erstes Vorkommnis eines Values
.clear()                  ### entferne alles
.copy()                   ### Clone Liste
.count(value)             ### zähle wie oft value vorkommt
.extend(list)             ### erweitere Liste mit einer weiteren Liste
.index(value)             ### Bekomme Index vom Value
.reverse()                ### Clone? und kehre Liste um
.sort()                   ### Clone? und sortiere Liste
.insert(index, value)     ### Schiebe Value in einer Liste an einem Index. Values am Index werden nach links verschoben.

Strings sind Listen von Characters

Strings in Python sind nichts als Listen aus Buchstaben. Sprich man kann auf jeden einzelnen Buchstaben eines Strings mit dem entsprechenden Index zugreifen.

my_str = "Hello World"

print(my_str[0])
print(my_str[1])
print(my_str[2])
print(my_str[3])
print(my_str[4])
H
e
l
l
o

Oder man kann auch die Länge eines Strings, wie als wäre es eine stink-normale Liste, mit der len Funktion ermitteln.

print(len(my_str))
11

Tuple

Tuples sind wie Listen, die man nicht verändern kann (in Programmierfachchinesisch nennt man das auch "immutable").

Lass uns verschiedene Tuples erstellen:

number_tuple = (1, 20, 3)
string_tuple = ("marc", "leon", "david")
mixed_tuple = (420, True, -5, "hallo", False)

All diese Tuples sind immutable. Wir können nichts mehr hinzufügen, entfernen oder bearbeiten. Aber sonst ist ein Tuple wie eine Liste, also können wir auf die einzelne Indexe wie gewohnt zugreifen:

a = (1, 20, 3)

print(a[1])
20

Nun wenn wir den Tuple ändern wollen, dann ist das einzige, was wir machen können, ein komplett neuen Tupel zu erstellen, um damit den alten Tupel zu überschreiben. Zum Beispiel so:

a = (1, 20, 3)
a = (1, 2, 3, 4)

print(a)
print(len(a))
(1, 2, 3, 4)
4

Oder wir können ein Tupel mit der list Funktion zu einer Liste konvertieren, dieser Liste einen weiteren Wert hinzufügen, diese wieder mit der tuple Funktion zu einem Tupel konvertieren, um dann damit den alten Tupelwert zu überschreiben. Aber du merkst auch schon bestimmt selber, dass dies unnötig kompliziert ist. Ab diesen Punkt sollte man vielleicht eher eine Liste von Anfang an benutzen, aber für Lernzwecke zeige ich dir hier den Code, wie man Tupel im nachhinein verändern kann bzw. bearbeiten kann:

a = (1, 2, 3)
a_list = list(a)

a_list.append(4)
a_list[1] = 20

a = tuple(a_list)

print(a)
print(len(a))
(1, 20, 3, 4)
4

Oder hier ähnlicher Code, aber "cleaner":

a = (1, 2, 3)

print(a)

a = (*a, 4)
print(a)
(1, 2, 3)
(1, 2, 3, 4)

* ist der "unpacking"-Operator. *a ist das selbe wie als würde ich a[0], a[1], a[2], ..., bis zum Ende des Tupels, schreiben. Apropos den unpacking-Operator kannst du auch mit Listen verwenden!

Dictionary

Dictionaries, oder auch "Dicts" genannt, sind ziemlich cool. Du kannst es dir sprichwörtlich wie ein Wörterbuch vorstellen. In einem Wörterbuch gibt es zu jedem Wort einen Eintrag. Naja in Python wäre ein Wort ein "key" und die Definition zu dem Wort das zugehörige "value". So wie es in einem Wörterbuch mehrer verschiedene Wörter gibt, so kann man in einem Dictionary mehrere verschiedene Keys haben. ABER so wie es in einem Wörterbuch jedes Wort nur einmal gibt, so können wir in einem Dictionary keinen Key zweimal verwenden!

Zum Beispiel lass uns mal einen "Dict" erstellen:

ages = {
    "marc": 27,
    "leon": 25,
    "david": 29,
    }
    
print(ages)
print(type(ages))
print(len(ages))
{'marc': 27, 'leon': 25, 'david': 29}
<class 'dict'>
3

Im Gegensatz zu einem Tupel, ist ein Dict "mutable", heißt veränderbar. Sprich wir können Values von Keys verändern oder neue Keys hinzufügen.

ages["marc"] = 28
ages["rina"] = 22
print(ages)
{'marc': 28, 'leon': 25, 'david': 29, 'rina': 22}

Wenn wir einen Key wieder entfernen wollen, dann machen wir dies mit del:

del ages["rina"]
print(ages)
{'marc': 28, 'leon': 25, 'david': 29}

Schleifen

In so ziemlich jeder Programmiersprache gibt es Schleifen oder auch "Loops" auf Englisch genannt.

Schleifen ermöglichen es dir, bestimmte Aktionen mehrmals wiederholen zu lassen (in Programmierfachchinesisch wird ein solche Wiederholung einer Schleife auch "Iteration" genannt). Dies ist besonders nützlich, wenn du Code hast, der viele Male hintereinander durchgeführt werden soll und du nicht unbedingt 100-mal hintereinander den selben Code copy-pasten willst.

In Python gibt es zwei verschiedene Arten von Schleifen, die für verschiedene Usecases verwendet werden:

for

Die for Schleife gibt es so ziemlich in jeder Programmiersprache. Kurzgesagt funktioniert sie so: Für die Variable x in einer Sequenz führe Code aus. In Python-Code sieht es ungefähr so aus:

for x in sequence:
    ## ...code

Um die for Schleife besser verstehen zu können, müssen wir uns ein Beispiel anschauen:

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

range(1, 10) erstellt uns eine Liste [1, 2, 3, 4, 5, 6, 7, 8, 9].
Japp, bis 9 und nicht bis 10!! Warum?? Keine Ahnung, es ist einfach so 🤷

x ist die Variable, die jeden Wert innerhalb dieser Liste animmt. In diesem Beispiel ist x beim ersten mal durchlaufen der Schleife 1 und dann beim zweiten Mal 2 und so weiter bis 9. x nimmt dabei pro Durchlauf jeden einzelnen Wert der Sequenz von 1 bis 9 an.

Wir sind nicht gezwungen unsere Schleifen-Variable x zu nennen. Wir können unsere Schleifenvariable so benennen, wie es gerade am besten zu unserem Code passt.

Für jeden Durchlauf wird der indentierte Code darunter ausgeführt, deswegen sehen wir in der Konsole 1 bis 9 je in einer Zeile. Der Code darunter kann so lang sein, wie wir wollen, solange er die gleichte Indentierung hat. Lass uns zum Beispiel eine for Schleife schreiben, die von 1-12, für die Monate in einem Jahr, geht und in die Konsole schreibt, ob es ein Sommer oder Winter Monat ist:

for month in range(1, 13):
    if month >= 6:
        print("Summer, month", month)
    else:
        print("Winter, month", month)
Winter, month 1
Winter, month 2
Winter, month 3
Winter, month 4
Winter, month 5
Summer, month 6
Summer, month 7
Summer, month 8
Summer, month 9
Summer, month 10
Summer, month 11
Summer, month 12

continue und break

Innerhalb einer Schleife können wir auch continue und break benutzen.

continue tut jeden weiteren Code, der kommen würde, überspringen und geht direkt in die nächste Schleifeniteration.

## Schleife von 1 bis 10
for x in range(1, 11):
    ## Wenn es durch 3 teilbar ist, dann überspringe
    if i % 3 == 0:
        continue
    ## Sonst printe die Zahl in der Konsole
    print(i)
1
2
4
5
7
8
10

break bricht eine Schleife sofort ab und es wird keine weiter Iteration und kein weiterer Code der Schleife ausgeführt.

## Schleife von 1 bis 10
for i in range(1, 11):
    ## Wenn i gleich 5 ist, dann breche die Schleife ab
    if i == 5:
        break
    ## Sonst printe die Zahl in der Konsole
    print(i)
}
1
2
3
4

fizzbuzz

"fizzbuzz" wohl die berühmteste Programmieraufgabe auf der Welt. Jeder der Programmieren lernt oder studiert, wird früher oder später diese Aufgabe mal gestellt bekommen, denn fizzbuzz ist das perfekte Problem für Programmieranfänger, die Schleifen lernen. Dann lass uns mal anfangen!

Gehe von 1 bis 100

  • Wenn eine Zahl ohne Rest durch 3 teilbar ist, dann gebe "fizz" in die Konsole aus
  • Wenn eine Zahl ohne Rest durch 5 teilbar ist, dann gebe "buzz" in die Konsole aus
  • Sonst gebe die Zahl so wie sie ist in die Konsole aus

Beispielausgabe vom Ergebnis:

1
2
fizz
4
buzz
fizz
7
8
...
Zeige Lösung
for x in range(1, 101):
    if x % 3 == 0:
        print("fizz")
    elif x % 5 == 0:
        print("buzz")
    else:
        print(x)

Jetzt bearbeite dein Code und gebe "fizzbuzz" in die Konsole aus, wenn die Zahl ohne Rest durch 3 und 5 teilbar ist.

Beispielausgabe vom Ergebnis:

1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
...
Zeige Lösung
for x in range(1, 101):
    is_fizz = x % 3 == 0
    is_buzz = x % 5 == 0

    if is_fizz and is_buzz:
        print("fizzbuzz")
    elif is_fizz:
        print("fizz")
    elif is_buzz:
        print("buzz")
    else:
        print(x)

mit Listen

Wir haben schon gelernt, dass range(1, 10) eine Liste [1, 2, 3, 4, 5, 6, 7, 8, 9] erstellt, über diese sind wir dann drüber geschliefen.

Sprich dieser Coder hier:

for x in range(1, 10):
    print(x)

Ist genau das selbe wie:

for x in [1, 2, 3, 4, 5, 6, 7, 8 ,9]:
    print(x)

An der Stelle [1, 2, ..., 9] können wir auch irgendeine andere Liste einsetzen oder eine Variable, die eine Liste in sich trägt.

Hier ein paar Beispiele:

names = ["marc", "leon", "philipp"]

for name in names:
    print("Hello", name)
Hello marc
Hello leon
Hello philipp
ages = [27, 18, 14, 58]

for age in ages:
    print("Person is", age, "years old")
Person is 27 years old
Person is 18 years old
Person is 14 years old
Person is 58 years old

mit Tuples

Tuples verhalten sich eins-zu-eins genauso wie Listen. Also giblt es keinen Unterschied, wenn es um for-Schleifen geht.

names = ("marc", "leon", "philipp")

for name in names:
    print("Hello", name)
Hello marc
Hello leon
Hello philipp

mit Strings

Strings auf Detusch übersetzt, bedeutet Zeichenkette, ergo eine Kette an Schriftzeichen, ergo eine Liste an Schriftzeichen, ergo wir können wie als wäre es eine Liste über jedes einzelne Schriftzeichen drüber schleifen:

for char in "Hello World":
    print(char)
H
e
l
l
o
 
W
o
r
l
d

mit Dictonaries

Wir können auch ohne Problem über ein Dict schleifen. Aber wenn wir dies tun, dann schleifen wir nur über die Keys. Hier ein Biespiel:

ages = {
    "marc": 27,
    "leon": 25,
    "david": 29,
    }
    
for name in ages:
    print(name, "is", ages[name], "years old")
marc is 27 years old
leon is 25 years old
david is 29 years old

.values()

Mit der values Funktion bekommen, wir eine Liste von all den Values in einem Dict.

ages = {
    "marc": 27,
    "leon": 25,
    "david": 29,
    }
    
for age in ages.values():
    print("Person is", age, "years old")
Person is 27 years old
Person is 25 years old
Person is 29 years old

.keys()

Mit keys bekommen wir alle Keys von einem Dict als List.

ages = {
    "marc": 27,
    "leon": 25,
    "david": 29,
    }

print(ages.keys())
dict_keys(['marc', 'leon', 'david'])

.items()

items ist super, wenn wir Keys und Values gleichzeitig haben wollen. Vorallem ist dies sehr praktisch bei einer for-Schleife.

ages = {
    "marc": 27,
    "leon": 25,
    "david": 29,
    }

print(ages.items())
dict_items([('marc', 27), ('leon', 25), ('david', 29)])

Wie du sehen kannst, haben wir eine Liste an Tuples, über diese wir jetzt schleifen können.

Apropos das "dict_items" kannst du ignorieren, dass ist nur ein "Wrapper", der für uns jetzt unwichtig ist.
ages = {
    "marc": 27,
    "leon": 25,
    "david": 29,
    }

for entry in ages.items():
    print(entry[0], "is", entry[1], "years old")
marc is 27 years old
leon is 25 years old
david is 29 years old

Es geht aber noch viel einfacher, indem wir zwei Schleifenvariablen beim for-Statement definieren. Diese zwei Variablen werden dann den zwei Werten des Tuples innerhalb der Liste in der selben Reihenfolge zugewiesen. Schaue hier:

ages = {
    "marc": 27,
    "leon": 25,
    "david": 29,
    }

for name, age in ages.items():
    print(name, "is", age, "years old")
marc is 27 years old
leon is 25 years old
david is 29 years old

Übungsaufgaben

  1. Addiere alle ungeraden Zahlen zwischen 1 und 100 miteinander
Zeige Lösung
print("Hello World")
  1. Zähle wie oft ein Buchstabe in einem String vorkommmt
Zeige Lösung
print("Hello World")
  1. Lass den User eine Zahl eingeben und berechne den faktorialen Wert
Zeige Lösung
print("Hello World")
  1. Lass den User ein Text eingeben und zähle wie viele Konsanten und Vokale darin vorkommmen
Zeige Lösung
print("Hello World")
  1. Berechne Medium, Maximum und Minimum von einem Zahlenvektor
Zeige Lösung
print("Hello World")
  1. Lass den User eine Zahl eingeben und addiere alle Zahlen bis null darauf. Sprich wenn der User die Zahl 89 eingibt, dann addiere 88, 87, 86 ... bis 0 auf auf die ursprüngliche Zahl.
Zeige Lösung
print("Hello World")
  1. Tannenbaum
Zeige Lösung
print("Hello World")

while

while <Statement>:
    ...
    <code>
    ...

Eine while-Schleife wiederholt sich die ganze Zeit, solange das Statement True ist. Sobald das Statement False wird, wird die Schleife beendet.

Lass es mich mal anhand eines Beispiels erklären:

x = 0
while x < 10:
    print(x)
    x += 1
0
1
2
3
4
5
6
7
8
9

Zu Beginn definieren wir die Variable x mit 0, dann started auch schon die while-Schleife. Diese führt den indentieren Codeblock solange aus bis das Statement x < 10 False wird. Sprich im ersten Durchlauf, wo x immer noch 0 ist, wird kontrolliert, ob "x < 10" True ist, wenn ja, dann führe den Code der Schleife aus. In dem Schleifencode addieren wir eins zu x.

Apropos x +=1 ist das selbe wie x = x + 1.

Im zweiten Durchlauf ist x 1 und deswegen ist x > 10 immer noch true, solange bis dies nicht mehr der Fall ist. Sobald x 10 wird, ist das Statement x > 10 False geworden und die while-Schleife wird beendet.

Zum Beispiel, wenn wir das x += 1 vergessen hätten, dann wird unsere while-Schleife nie enden und dann hätten wir eine sogenannte "Endlosschleife", welche ich gleich genauer thematisieren werde.

continue und break

Auch bie einer while-Schleife können wir, genauso wie bei einer for-Schleife, continue und break verwenden.

x = 0
while x < 20:
    if x == 15:
        break
    if x % 2 == 0:
        x += 1
        continue
    print(x)
    x += 1
1
3
5
7
9
11
13

Endlosschleifen

Eine Endlosschleife oder auch "infinite loop" und "endless loop" auf Englisch genannt, sind while-Schleifen, die nie enden... 🤯

Ich weiß, hättest du jetzt nicht gedacht, oder?

Zum Beispiel hier eine Endlosschleife:

while True:
    print("are we there yet?")
    print("no!")
are we there yet?
no!
are we there yet?
no!
are we there yet?
no!
are we there yet?
no!
are we there yet?
no!
are we there yet?
no!
...

Das Statement dieser while-Schleife ist True und naja das ist immer True... offensichtlich, oder?

Apropos mit STR+C kannst du ein Programm in der Konsole oder CMD zum Beenden zwingen. 😉

Aber warum braucht man soetwas? Wir könnten eine Endlosschleife verwenden, um zum Beispiel nach dem Passwort eines Benutzers zu fragen und wenn wir ein falsches bekommen, dann fragen wir solange bis wir das richtige Passwort bekommen.

Du fragst dich jetzt bestimmt: "Eine Endlosschleife ist doch endlos? Wir können wir diese dann beenden, sobald wir das richtige Passwort bekommen haben?" Gute Frage! Vielen Dank.

In einer while-Schleife können wir break benutzen um diese, egal ob das Statement True oder False ist, zu beenden.

Dementsprechend hier der Code für dieses Beispiel:

Ratespiel

from random import *

x = randint(1, 100)
lives = 5

while True:
    ### Printing health bar
    print("[ ", end="")
    for _ in range(0, lives):
        print("❤️", end=" ")
    print("]")

    guess = None
    try:
        guess = int(input("📝 ️Errate die richtige Zahl: "))
    except Exception:
        print("❌ Bitte gebe eine reale ganze Zahl ein")
        continue

    if guess == x:
        print("🎉 Hurrah du hast die richtige Zahl erraten!!!")
        break
    else:
        if guess > x:
            print("Die zu erratende Zahl ist kleiner als", guess)
        else:
            print("Die zu erratende Zahl ist groesser als", guess)
        lives -= 1

    if lives == 0:
        print("💀💀💀 Game Over 💀💀💀")
        print("Die richtige Zahl ist: ", x)
        break
    else:
        print("❌ Leider falsch versuche es nochmal")

Funktionen

Funktionen sind wieder verwendbare Blöcke an Code, die du jederzeit nach Belieben oft ausführen kannst.

Wir haben bis jetzt schon sehr viele Funktionen von Python benutzt. Zum Beispiel die print Funktion, die eine Zeile in die Konsole ausgibt.

Hier ein Beispiel einer Funktion, die "hello world" in die Konsole ausgibt:

def hello():
    print("hello world")
    
hello()
hello world

Natürlich ist diese Funktion ziemlich sinnbefreit. Im nächsten Kapitel zeige ich dir Schritt für Schritt, wie wir eigene komplexe Funktionen schreiben können, um damit unseren Code besser in logische, wiederbenutzbare Blöcke einzuteilen.

Eigene Funktionen schreiben

def hello():
    print("hello marc")
    
hello()
hello marc

Mit def können wir eine komplett neue Funktion definieren. Nach dem "def" kommt der Name der Funktion. Du kannst dich für egal welchen Namen auch immer entscheiden. Vergesse die () Klammern nicht direkt nach dem Namen der Funktion. Diese sind nicht nur notwendig, damit wir keinen "SyntaxError" bekommen, sondern sie haben auch eine Zweck, auf den wir noch später zurück kommen werden.

Der indentierte Block and Code ist der Körper unserer Funktion. Dieser wird immer ausgeführt, wenn wir die Funktion aufrufen.

Wie du in der letzten Zeile sehen kannst, führen wir unsere Funktion mit den selben Namen und den () Klammern aus und deswegen sehen wir dann auch "hello marc" in der Konsole.

Probiere es einmal selber aus!

Ok soweit so gut, aber was wenn wir mehrere Leute begrüßen wollen, dann müssten wir entweder unsere Funktion erweitern oder mehrere verschiedene Funktionen schreiben. Zum Beispiel so:

def hello_marc():
    print("hello marc")

def hello_leon():
    print("hello leon")
    
    
hello_marc()
hello_leon()
hello marc
hello leon

Das ist aber zu viel copy-paste, meiner Meinung nach. Wir können innerhalb der () Klammern auch Variablen definieren, sogenannte Funktionsparameter, um bei jedem Aufruf, einen anderen Namen unserer "hello" Funktion zu übermitteln.

def hello(name):
    print("hello", name)
    
hello("marc")
hello("leon")
hello marc
hello leon

Jedoch wenn wir jezte beim Aufrufen unserer Funktion vergessen einen Namen in die () Klammern einzugeben, dann bekommen wir einen Error!

hello()
Traceback (most recent call last):
  File "/home/marc/main.py", line 1, in <module>
    hello()
    ~~~~~^^
TypeError: hello() missing 1 required positional argument: 'name'

Wie man am Error schon erkennen kann, fehlt der "argument" "name", beim Aufrufen der "hello" Funktion. Diesen Error können wir beheben, indem wir für "name" einen "default" definieren. Lass uns diesen mal schnell definieren:

def hello(name = "stranger"):
    print("hello", name)
    
hello("marc")
hello("leon")
hello()
hello marc
hello leon
hello stranger

Schon viel viel besser, aber was wenn wir auch noch die Begrüßung für ein paar Personen anpassen wollen? Lass uns dafür ein zweiten "greeting" Funktionsparameter mit einem Defaultwert definieren, sodass wir deisen bei belieben überschreiben können, wenn wir die "hello" Funktion aufrufen.

def hello(greeting = "hello", name = "stranger"):
    print(greeting, name)
    
hello("hi", "marc")
hello(name = "leon")
hello("what's up")
hi marc
hello leon
what's up stranger

Unsere "hello" Funktion ist jetzt fertig geschrieben.

In Python haben wir viele verschiedene Arten diese aufzurufen, wie du es schon am vorherigen Beispiel vielleicht erkennen konntest.

Wir können die Werte in der Reihenfolge der Parameter übergeben. Sprich der erste Wert wird zum ersten Funktionsparameter von "hello" weiter gegeben und der zweite zum zweiten der Funktion:

hello("hi", "marc")
hi marc

Statt sich auf die Reihenfolge zu verlassen, kannst du auch die Parameter explizit benennen:

hello(greeting = "hi", name = "marc")
hello(name = "marc", greeting = "hi")
hi marc
hi marc

Oder du kannst auch mischen und machen was auch immer du willst:

hello("hi", name = "marc")
hi marc

Private und globale Variablen

Bis jetzt war unsere "hello" Funktion sehr simpel und überschaubar. Wir können aber innerhalb des Funktionskörpers so viel Code reinschreiben wie wir wollen. Wir können while und for Schleifen darin ausführen oder auch Variablen erstellen. Aber alle Variablen, die wir innerhalb der Funktion erstellen, existieren nur innerhalb des Kontextes der Funktion. Man könnte diese Art von Variablen auch "private Variablen" nennen und alle die wir einfach so außerhalb der Funktion erstellen, wären dann "globale Variablen".

Hier ein Biespiel was ich genau meine:

global_var = "im global!!"

def my_func():
    private_var = "im private!! and only exist inside this function"

Da "global_var" im keinen Codeblock sondern ganz normal in unserer Scriptdatei erstellt worden ist, ist sie global überall verfügbar und wir könnten innerhalb der "my_func" Funktion darauf zugreifen.

Die "private_var" hingegen, existiert nur innerhalb des Funktionskörpers und würden wir außerhalb der Funktion darauf zugreifen, dann bekommen wir einen Error.

Hier nochmal ein anderes Beispiel mit unserer "hello" Funktion:

def hello():
    text = "hello world"
    print(text)
    
hello()
print(text)
hello world
Traceback (most recent call last):
  File "/home/marc/main.py", line 6, in <module>
    print(text)
          ^^^^
NameError: name 'text' is not defined. Did you mean: 'next'?

Wie du am Output erkennen kannst wird "hello" erst volkommen ohne Probleme ausgeführt. Erst die Zeile mit print(text) schmeißt einen Error, weil Python text nur im Kontext der Funktion kennt nicht global, so wie wir es hier versuchen.

Natürlich würde unser Script wieder funktionieren, wenn wir "text" einmal global erstellen würden. Und zwar so:

text = "hello global"

def hello():
    text = "hello world"
    print(text)
    
hello()
print(text)
hello world
hello global

Obwohl wir zwei Variablen namens "text" haben, sind beide voneinander getrennt und innerhalb der Funktion kennen wir nur "text" mit dem Wert "hello world", doch sobald wir außerhalb des Kontextes der Funktion sind, kennen wir ausschließlich "text" mit dem Wert "hello global".

Was wenn ich jetzt die Variable "text" innerhalb der Funktion wieder entferne, würde dann unser Script noch funktionieren? Lass uns das mal ausprobieren!

text = "hello global"

def hello():
    print(text)
    
hello()
hello global

Wie du siehst, ja! Also vom Kontext der Funktion aus, können wir auf globale Variablen zugreifen, aber nicht anders herum.

return

Funktionen können auch auch etwas zurückgeben, aber was bedeutet das überhaupt?

Stell dir eine Funktion als ein Helfer vor. Wenn Du eine Funktion aufrufst, dann schickst Du den Helfer los, um eine Aufgabe zu erledigen. Bis jetzt haben wir den Helfer immer nur los geschickt und gegebenfalls in die Konsole schreiben lassen. Nun kann man aber jetzt den Helfer los schicken und auf ihn warten bis er etwas zurück bringt.

Für das "Zurückbringen" benutzen wir return

def do_stuff():
    do_something()
    return some_value

Vorher sahen unsere Funktionen in etwa so aus:

def do_stuff():
    do_something()
    print_something_to_console()

Zum Beispiel hier eine add Funktion, die zwei Werte nimmt, miteinander addiert und in die Konsole ausgibt:

def add(a, b):
    print("a + b =", a + b)

add(5, 3)
"a + b = 8"

Aber wenn wir mit dem Ergebnis von add(5, 3) weiter rechnen wollen, dann funktioniert dies nicht, weil unsere add Funktion, nicht das Ergebnis zurückgibt, sondern es lediglich in die Konsole ausgibt.

Mit return a + b innerhalb des Funktionskörpers können wir das Ergebnis von a + b, wo auch immer die Funktion aufgerufen wird, zurückgeben, um damit weiterarbeiten zu können.

Lass zum Beispiel das Ergebnis von add mal 10 nehmen:

def add(a, b):
    return a + b

x = add(5, 3) * 10

print(x)
80

Unsere add Funktion tut jetzt das Ergebnis von a + b zurückgeben, dass bedeutet, dass das add(5, 3) von der Zeile, wo wir x deklarieren, evaluiert und mit dem Ergebnis ausgetauscht wird. Sprich Python macht aus x = add(5, 3) * 10 => x = 8 * 10.

return als Exitpoint

return dient ist auch ein Exitpoint einer Funktion. Sobald unsere Funktion eine Zeile erreicht hat die "return" in sich hat, werden alle folgenden Zeilen danach nicht mehr ausgeführt:

def can_drive(age):
    if (age < 18):
        return False
    else:
        return True
    print("This line will never be executed!")

print(can_drive(15))
print(can_drive(29))
False
True

return richtig zu verwenden, können deine Skills als Programmieranfänger verzehnfachen. Also wenn du es nicht auf Anhieb alles verstanden hast, sei nicht demotiviert. Manche Dinge brauchen einfach länger zum Verstehen. Les dir dieses Kapitel nochmal in Ruhe durch oder schau Youtube Videos, die genau dieses Thema versuchen zu erklären. Vetrau mir es wird sich für dich lohnen.

*args und **kwargs

def my_func(normal_arg, *args, **kwargs):
    print("Stinknormaler Funktionsparameter:", normal_arg)

    for arg in args:
        print("Funktionsparameter als Liste:", arg)
        
    for keyword, arg in kwargs.items():
        print("Funktionsparameter als Dictionary:", keyword, arg)
Output

Wichtig ist nicht der Name sondern die * & **

Übungsaufgaben

Um den Sinn von Funktionen und deren Anwendungsgebiet besser zu verstehen, habe ich hier ein paar Übungsaufgaben für dich. Stets nach dem Motto "Studieren geht über probieren" 😉

  1. Schreibe eine Funktion mit dem Namen "add", die zwei Zahlen als Eingabe bekommt. Die Funktion soll die beiden Zahlen addieren und das Ergebnis zurückgeben.

Beispiel: Wenn du 5 und 6 übergibst, soll die Funktion 11 zurückgeben.

Zeige Lösung
def add(a, b):
    return a + b

x = add(5, 6)
print(x)
11
  1. Schreibe eine "evens" Funktion, die eine Liste mit Zahlen bekommt. Die Funktion soll nur die geraden Zahlen aus dieser Liste nehmen und eine neue Liste mit diesen geraden Zahlen zurückgeben.

Sprich wir geben der Funktion diese Liste [1, 2, 3, 4, 5, 6] und zurück bekommen wir [2, 4, 6]

Zeige Lösung
numbers = range(1, 101)

def evens(numbers):
    even_numbers = []
    for number in numbers:
        if number % 2 == 0:
            even_numbers.append(number)
    return even_numbers

print(evens(numbers))
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100]
  1. Schreibe eine Funktion, die zwei Dinge als Eingabe bekommt:
  • einen Text (String) und
  • eine Zahl.

Die Funktion soll den Text so oft wiederholen, wie es die Zahl angibt, und das Ergebnis als einen einzigen String zurückgeben.

Beispiel: Wenn der Text "yes" ist und die Zahl 5, soll die Funktion diesen Text fünfmal hintereinander aneinanderreihen: "yesyesyesyesyes"

Zeige Lösung
def repeat_str(text, repeat):
    end_string = ""
    for _ in range(repeat):
        end_string += text
    return end_string
    
print(repeat("yes", 5))
yesyesyesyesyes
  1. Schreibe eine Funktion, die eine Temperatur in Celsius als Eingabe bekommt und sie in Fahrenheit umrechnet.

Verwende dafür die folgende Umrechnungsformel:

  • Fahrenheit = (Celsius × 1.8) + 32

Die Funktion soll das Ergebnis zurückgeben.

Beispiel: Wenn du 25 als Celsius-Temperatur übergibst, soll die Funktion 77.0 zurückgeben.

Zeige Lösung
def fahrenheit(celsius):
    f = (celsius * 1.8) + 32
    return f

print(fahrenheit(25))
77.0
  1. Schreibe eine "min_max" Funktion, die eine Liste mit Zahlen bekommt und sowohl das kleinste als auch das größte Element aus dieser Liste zurückgibt.

Die Funktion soll das Ergebnis als Liste mit zwei Werten zurückgeben:

  • zuerst das Minimum,
  • dann das Maximum.

Beispiel: Bei der Liste [234, 789, 23487, 1] soll die "min_max" Funktion [1, 23487] zurückgeben.

Zeige Lösung
numbers = [234, 789, 23487, 1]

def min_max(numbers):
    min = numbers[0] 
    max = numbers[0]

    for number in numbers:
        if number < min:
            min = number
        if number > max:
            max = number

    return [min, max]

print(min_max(numbers))
[1, 23487]

List comprehension

Class

Dieses Kapitel ist immer noch in WIP

class Person:
    name = ""
    def greeting():
        print("hello", name)

Der Unterschied zwischen is und ==

Der == Operator gibt True zurück, wenn beide Werte, die wir vergleichen wollen, gleich sind, während is kontrolliert ob beide Werte die selbe Memoryadresse haben.

Ok... Ich muss mehr ausholen. Jede Variable, die wir erstellen, und jeder Wert, den wir ihr zuweisen, werden im RAM vom Computer gespeichert. Zum Beispiel dieser Pythoncode hier:

my_age = 27

Der Wert von my_age wird im RAM gespeichert, damit unser Programm sich es auch merken kann und wir in späteren Zeilen darauf zugreifen können, um damit zu rechnen oder es in der Konsole auszugeben:

print(my_age)

Der ganze Prozess, im RAM abspeichern, den Ort, wo es abgespeichert wurde, und dies mit my_age zu verlinken, passiert komplett automagisch im Hintergrund umnd wir müssen uns keine Gedanken drüber machen. Der Ort, die Adresse, wo die Variable im RAM gespeichert wird, nennt man in Programmierfachchinesisch auch "Pointer". Der Pointer zeigt auf die Stelle im RAM, in der die Variable existiert.

Hier nochmal visualisiert:

a = 1000
b = "Hello"
c = 1000
d = a + c

Dieser Pythoncode sieht dann ganz abstrakt im RAM so aus:

Wie du sehen kannst, haben a und c, obwohl die den selben Wert haben, unterschiedliche Pointer. Das können wir auch sehen wenn wir is benutzen:

print(a == c)
print(a is c)
True
False

Das selbe, aber nur umgedreht, gilt natürlich auch für is not und !=.

print(a != c)
print(a is not c)
False
True

Python Projekt aufsetzen

Vorher haben wir bis jetzt nur eine .py Datei erstellt und darin unser Code reingeschrieben und mit dem Befehl python <Dateiname.py> konnten wir diesen Code ausführen. Obwohl dies in etwa 99,9% der Arbeit eines Programmierers entspricht, sind die restlichen 0.1% auch nicht zu vernachlässigen.

Die restlichen 0.1% sind Packages installieren und deinstallieren. Vielleicht brauchen wir eine bestimmte Python Version für unser Projekt etc. All dies macht das Programm poetry für uns mega einfach zu managen.

Installation

Als erstes müssen wir dafür poetry auf unseren Computer installieren. Je nach Plattform kann der Befehl ein bisschen anders sein.

Windows

Auf Windows öffne die CMD Konsole und führe diesen Befehl aus:

pip install poetry

macOS

Auf macOS führe diese beiden Befehle im Terminal aus:

pipx install poetry
poetry completions zsh > ~/.zfunc/_poetry

Ubuntu oder anderen Linux

Auf Linux führe diese beiden Befehle im Terminal aus:

pipx install poetry
poetry completions bash >> ~/.bash_completion

Neues Projekt erstellen

Um ein komplett neues Pythonprojekt zu erstellen, tippen wir einmal poetry new <name> in die Konsole ein. Für <name> kannst du hier, wie auch immer du dein Projekt nennen möchtest, eingeben.

Ich werde mal ein Projekt namens "poetry-demo" erstellen.

poetry new poetry-demo

Dies erstellt mir einen neuen Ordner mit dem Namen "poetry-demo". Mit folgender Dateien- und Ordnerstruktur:

poetry-demo/
├── pyproject.toml
├── README.md
├── src
│   └── poetry_demo
│       └── __init__.py
└── tests
    └── __init__.py

Gehen wir mal Schritt für Schritt über alles.

pyproject.toml

Die pyproject.toml hat alle Metadaten von unserem Projekt in sich. Die automatisch generierte pyproject.toml sieht bei mir so aus:

pyproject.toml:

[project]
name = "poetry-demo"
version = "0.1.0"
description = ""
authors = [
    {name = "Marc Mäurer",email = "marc.maeurer@pm.me"}
]
readme = "README.md"
requires-python = ">=3.13"
dependencies = []

[tool.poetry]
packages = [{include = "poetry_demo", from = "src"}]

[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

Der einzige Part, der für uns wichtig sind die ganzen Zeilen direkt unter [project]. Den Rest können wir ignorieren und brauchen wir nur in sehr spezifischen Situation zu editieren.

Das meißte sollte schon vom Namen her offensichtlich sein. Mit name definieren den Namen unserers Projektes, mit version welche Version unser Programm ist (wird erst wichtig, wenn wir unser Programm veröffentlichen wollen), bei description kommt eine Beschreibung unserers Programmes, authors sind alle Authoren des Projektes drinne, automatisch hat poetry meinen Namen und meine Emailadresse herausgefunden. requires-python sagt genau aus welche Version an Python unser Programm braucht. Poetry tut automatisch für uns eine Projekt-eigene Version von Python installieren und benutzten, falls wir eine andere Version hier reinschreiben sollten, als auf unserem Computer installiert ist. In dependencies müssen wir gar nichts editieren, weil hier kommen alle Packages rein, die wir mit poetry für unseren Projekt installieren, wie das geht zeige ich dir gleich noch, aber selber editieren müssen wir hier "goar nix."

README.md

In README.md können wir eine Einleitung oder Vorstellung unseres Projektes reinschreiben. Ist für uns jetzt komplett uninteressant, aber wenn wir unser Projekt veröffentlichen wollen, dann können wir diese Datei hier als Vorstellung benutzen.

src/

Der src Ordner ist wohl der wichtigste Ordner. Hier wirst du die meiste Zeit verbringen, weil hier kommt der ganze Sourcecode (Quellcode) unseres Projektes rein.

Wichtig zu beachten ist, dass poetry den Sourcecode in mehrer Module aufteilt. Was Module genau sind, werden wir noch lernen, aber fürs erste bedeutet, dass das all unser Code nicht direkt in src reinkommt, sondern in src/poetry_demo.

Die src/poetry_demo/__init__.py ist dabei eine spezielle py Datei, die automatisch vorm Ausführen des Programmes ausgeführt wird.

tests/

Der tests Ordner ist für uns komplett irrelevant und du kannst den auch gerne löschen. Was tests sind, werden wir in diesem Buch hier nicht lernen.

Hello World

Lass un mal in diesem Projekt weiter arbeiten.
Eine super Idee wäre es, wenn unser Projekt "Hello World" in der Konsole ausgeben könnte. Das hört sich doch mega spannend an, oder nicht?

Ein paar Hürden gibt es aber jetzt schon. Zum Beispiel, wo fangen wir an?

Wir könnten in der src/poetry_demo/__init__.py unser Code reinschreiben, aber dies ist eigentlich nicht, wie es poetry vorgesehen hatte, denn in der src/poetry_demo/__init__.py wird Code reingeschrieben, zum initialisiern unseres Programmes. Nun könnten wir dort auch stink normalen Code reinschreiben, aber dies wäre nicht so idiomatisch, oder findest du nicht? Besser wäre es, wenn wir eine neue Datei erstellen, von der unser Programm aus starten kann.

Dafür erstelle ich eine main.py Datei in src/poetry_demo/. Innerhalb der main.py kommt dann dieser Code hier:

src/poetry_demo/main.py:

def main():
    print("Hello World")

if __name__ == "__main__":
    main()

Du fragst dich jetzt bestimmt warum definiere ich eine main Funktion? Wir können poetry genau sagen, welche Funktion wir von einer Datei ausgeführt haben wollen. Die main Funktion der main.py Datei wird unser Entrypoint unseres Projektes sein und in der Zukunft zuständig dafür sein, unser Pythonprojekt zu starten, aber jetzt wird es erstmal nur "Hello World" in die Konsole ausgeben.

Unser Programm können wir jezt mit diesem Befehl ausführen:

poetry run python src/poetry_demo/main.py
Hello World

Mit poetry run python führen wir exakt die Version an Python aus, die in der pyproject.toml definiert ist. Weil diese von den Python, das auf unserem System installiert ist, abweichen könnte, ist es besser poetry run python zu verwenden, anstelle nur python.

Aber oh mein Gott ist der Befehl lang und kompliziert. Das geht auch noch besser und einfacher und zwar mit einem "Script".

Poetry erlaubt es uns eigene Scripts zu erstellen, dafür editieren wir einmal kurz unsere pyproject.toml Datei. Am Ende der Datei fügen wir diese zwei Zeilen hinzu:

pyproject.toml:

[tool.poetry.scripts]
start = "poetry_demo.main:main"

Dies bedeutet, dass wir einen neuen "run" Befehl erstellt haben, der vom src/poetry_demo dessen main.py Datei dessen main Funktion ausführt. Sprich mit poetry run start wird jetzt unsere main Funktion ausgeführt:

Wir haben einen neuen Befehl namens „run“ angelegt. Dieser startet direkt die Funktion main in der Datei src/poetry_demo/main.py. Wenn du jetzt

poetry run start

eingibst, wird also unsere main-Funktion ausgeführt.

Falls bei deinem neuen "run" Befehl einen Error bekommst, dann musst du wahrscheinlich einmal vorher poetry install eingeben.

poetry install

Und danach sollte poetry run start ohne Probleme ausgeführt werden und du solltest diesen Output in der Konsole sehen:

Hello World

Et voilà! Somti ist jetzt unser Projekt richtig aufgesetzt!

Du fragst dich jetzt vielleicht: "Warum so kompliziert? Man kann doch einfach weiterhin seinen Code in einer x-beliebigen Datei reinschreiben und mit python ausführen; ohne diesen ganzen Schnickschnack... Wozu braucht man poetry denn?"

In den nächsten Kapitel werden wir 3rd-Party Packages aus dem Internet runterladen müssen und poetry macht uns all das tausend-mal einfacher.

Zum Beispiel werde ich dir einmal schnell zeigen, wie man das Package "nltk", mit Hilfe poetry, installiert und wieder deinstalliert.

Packagemanagement

So installieren wir "ntlk":

poetry add nltk

Und so entfernen wir es wieder:

poetry remove nltk

Mega einfach oder nicht? "nltk" wurde dabei lokal in unserem Projekt installiert, sodass es keine Konflikte mit anderen Pythonprojekten geben kann, die zum Beispiel eine andere Version von "nltk" benötigen.

Poetry trackt dabei alle Packages, die wir geadded haben, in der pyproject.toml unter [dependencies].

pyproject.toml:

...
dependencies = [
    "nltk (>=3.9.1,<4.0.0)"
]
...

plotly

mehrere Plots in einem Plot

Legende im Plot

Plots speichern

Übungsaufgaben

Text Mining

License

Dieses Werk ist lizensiert unter GNU Free Documentation License Version 1.3, 3 November 2008

Contributors

Author: Marc Mäurer < marc.maeurer@pm.me >