Installation & Einrichtung
Einmal aufsetzen, dann nie wieder anfassen.
Python installieren
- Auf python.org/downloads die aktuelle Version herunterladen.
- Installer starten. Ganz unten den Haken bei „Add python.exe to PATH“ setzen.
- Auf Install Now klicken.
Die häufigste Stolperfalle
Ohne den PATH-Haken findet die Kommandozeile Python später nicht — stattdessen öffnet sich der Microsoft Store. Reparieren lässt sich das, indem du den Installer erneut startest, Modify wählst und den Haken nachträglich setzt.
Installation prüfen
PowerShell öffnen (Windows-Taste → „PowerShell“ tippen) und eingeben:
python --versionErwartete Ausgabe, etwa:
Python 3.13.2Editor
Nimm Visual Studio Code, kostenlos. Nach der Installation im Extensions-Reiter (Strg+Shift+X) die Erweiterung Python von Microsoft installieren. Sie bringt Syntaxhervorhebung, Autovervollständigung und einen Debugger mit.
Zwei Arten, Python zu benutzen
Interaktiv (REPL) — zum Ausprobieren. In PowerShell python eingeben:
>>> 2 + 2
4
>>> exit()Alles nach >>> tippst du selbst, die Zeile darunter ist die Antwort. Verlassen mit exit().
Als Skript — für echte Programme. Du schreibst Code in eine Datei name.py und startest sie:
python name.pyAb jetzt nutzen wir hauptsächlich Skripte.
Das erste Programm
Eine Zeile, die alles Wesentliche enthält.
Lege einen Ordner an, z. B. C:\Users\DeinName\PythonKurs, öffne ihn in VS Code und erstelle die Datei hallo.py:
print("Hallo Welt!")Speichern (Strg+S), dann im Terminal (in VS Code: Strg+ö) ausführen:
python hallo.pyHallo Welt!Das war’s — dein erstes Programm läuft.
Was passiert hier?
print(...)ist eine Funktion. Sie gibt etwas auf dem Bildschirm aus.- Die runden Klammern enthalten das Argument — das, womit die Funktion arbeiten soll.
"Hallo Welt!"ist ein String (Text). Text steht immer in Anführungszeichen.
Kommentare
Alles nach # ignoriert Python. Kommentare erklären, warum etwas passiert:
# Begrüßung ausgeben
print("Hallo Welt!") # auch am Zeilenende möglichVariablen und Datentypen
Namen für Werte — und die vier Sorten von Werten.
name = "Anna"
alter = 29
groesse = 1.72
ist_angemeldet = True
print(name, alter, groesse, ist_angemeldet)Anna 29 1.72 TrueDas = ist keine mathematische Gleichung, sondern eine Zuweisung: „Speichere rechts, nenne es links.“
Die vier Grundtypen
| Typ | Name | Beispiel | Beschreibung |
|---|---|---|---|
str | String | "Hallo" | Text |
int | Integer | 42 | Ganzzahl |
float | Float | 3.14 | Kommazahl — mit Punkt, nicht Komma |
bool | Boolean | True / False | Wahrheitswert, groß geschrieben |
Typ herausfinden:
print(type(alter)) # <class 'int'>
print(type(groesse)) # <class 'float'>Typen umwandeln
zahl_als_text = "42"
zahl = int(zahl_als_text) # String → Ganzzahl
print(zahl + 8) # 50
print(str(50)) # "50" Zahl → String
print(float("3.5")) # 3.5
print(int(3.99)) # 3 schneidet ab, rundet nicht!Regeln für Variablennamen
- Erlaubt: Buchstaben, Ziffern, Unterstrich — aber nicht am Anfang eine Ziffer.
- Groß-/Kleinschreibung zählt:
alterundAltersind verschiedene Variablen. - Üblich in Python ist
snake_case:max_punkte,erster_name. - Sprechende Namen wählen:
anzahl_versuchestattx.
Konstanten
Python kennt keine echten Konstanten. Konvention: GROSSBUCHSTABEN bedeutet „nicht ändern“ — MWST_SATZ = 0.19.
Strings genauer
Text zusammensetzen, formatieren, zerlegen.
Verketten und f-Strings
vorname = "Anna"
nachname = "Meier"
# Umständlich:
print("Hallo " + vorname + " " + nachname + "!")
# Besser — f-String (das f vor dem Anführungszeichen!):
print(f"Hallo {vorname} {nachname}!")f-Strings können auch rechnen und formatieren:
preis = 19.999
anzahl = 3
print(f"Gesamt: {preis * anzahl:.2f} Euro") # Gesamt: 59.99 Euro:.2f heißt „als Kommazahl mit 2 Nachkommastellen“.
Nützliche String-Methoden
text = " Hallo Welt "
print(text.strip()) # "Hallo Welt" — Leerzeichen außen weg
print(text.strip().upper()) # "HALLO WELT"
print(text.strip().lower()) # "hallo welt"
print(text.replace("Welt", "Python"))
print("a,b,c".split(",")) # ['a', 'b', 'c']
print("-".join(["a","b","c"])) # "a-b-c"
print(len("Hallo")) # 5
print("Hallo".startswith("Ha")) # True
print("ll" in "Hallo") # TrueStrings sind unveränderlich
text.upper() ändert text nicht, sondern gibt einen neuen String zurück. Wenn du ihn behalten willst: text = text.upper().
Zeichen herausgreifen
Gezählt wird ab 0:
wort = "Python"
# 012345
print(wort[0]) # P
print(wort[-1]) # n letztes Zeichen
print(wort[0:3]) # Pyt von 0 bis *vor* 3
print(wort[2:]) # thon
print(wort[:2]) # Py
print(wort[::-1]) # nohtyP rückwärtsMehrzeilige Strings
text = """Zeile 1
Zeile 2
Zeile 3"""Rechnen und Operatoren
Sieben Rechenzeichen, drei Vergleichsfallen.
a = 17
b = 5
print(a + b) # 22
print(a - b) # 12
print(a * b) # 85
print(a / b) # 3.4 normale Division, ergibt immer float
print(a // b) # 3 Ganzzahldivision (abgeschnitten)
print(a % b) # 2 Rest (Modulo)
print(a ** 2) # 289 Potenz% ist überraschend nützlich: zahl % 2 == 0 prüft, ob eine Zahl gerade ist.
Kurzschreibweisen
punkte = 10
punkte += 5 # entspricht: punkte = punkte + 5
punkte -= 3
punkte *= 2
print(punkte) # 24Vergleiche
Ergeben immer True oder False:
print(5 == 5) # True gleich (zwei Gleichheitszeichen!)
print(5 != 3) # True ungleich
print(5 > 3) # True
print(5 <= 5) # TrueKlassiker
= ist eine Zuweisung, == ein Vergleich. Wer im if versehentlich = schreibt, bekommt einen SyntaxError.
Logische Operatoren
alter = 25
hat_ausweis = True
print(alter >= 18 and hat_ausweis) # True beides muss stimmen
print(alter < 18 or hat_ausweis) # True eines reicht
print(not hat_ausweis) # False kehrt umEingaben vom Benutzer
Eine Funktion — und eine Falle, die jeden einmal erwischt.
name = input("Wie heißt du? ")
print(f"Hallo {name}!")input() liefert immer einen String
Auch bei Zahlen. input() gibt nie einen int zurück, selbst wenn der Benutzer „29“ tippt.
alter = input("Wie alt bist du? ")
print(alter + 1) # TypeError: kann String und Zahl nicht addierenRichtig:
alter = int(input("Wie alt bist du? "))
print(f"Nächstes Jahr bist du {alter + 1}.")Bedingungen: if / elif / else
Ab hier trifft dein Programm Entscheidungen.
alter = int(input("Alter: "))
if alter >= 18:
print("Volljährig")
elif alter >= 16:
print("Fast volljährig")
else:
print("Minderjährig")Einrückung ist Syntax
In Python bestimmt die Einrückung, was zu einem Block gehört — keine geschweiften Klammern. Rücke konsequent mit 4 Leerzeichen ein. VS Code macht das automatisch, wenn du nach dem : Enter drückst.
if True:
print("falsch") # IndentationError!Verschachteln
if angemeldet:
if ist_admin:
print("Adminbereich")
else:
print("Nutzerbereich")
else:
print("Bitte anmelden")Oft eleganter mit and:
if angemeldet and ist_admin:
print("Adminbereich")Was gilt als „wahr“?
Leere Dinge sind False, alles andere True:
if name: # True, wenn name nicht leer ist
print(f"Hallo {name}")False sind: 0, 0.0, "", [], {}, None, False.
Schleifen: while und for
Dinge wiederholen, ohne sie abzutippen.
while — solange etwas gilt
zaehler = 1
while zaehler <= 5:
print(zaehler)
zaehler += 1 # ohne diese Zeile: Endlosschleife!Praxisbeispiel — Eingabe wiederholen, bis sie stimmt:
while True:
eingabe = input("Zahl zwischen 1 und 10: ")
if eingabe.isdigit() and 1 <= int(eingabe) <= 10:
zahl = int(eingabe)
break # Schleife verlassen
print("Ungültig, nochmal.")
print(f"Danke: {zahl}")break— Schleife sofort beendencontinue— Rest des Durchlaufs überspringen, nächste Runde starten
for — über etwas hinweggehen
for buchstabe in "Python":
print(buchstabe)
for name in ["Anna", "Ben", "Clara"]:
print(f"Hallo {name}")range()
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(1, 6): # 1, 2, 3, 4, 5
print(i)
for i in range(0, 11, 2): # 0, 2, 4, 6, 8, 10
print(i)
for i in range(10, 0, -1): # Countdown 10 bis 1
print(i)Merke
Das Ende ist nie enthalten. range(1, 6) hört bei 5 auf.
Mit Index: enumerate()
namen = ["Anna", "Ben", "Clara"]
for i, name in enumerate(namen, start=1):
print(f"{i}. {name}")1. Anna
2. Ben
3. ClaraListen, Tupel, Dictionaries, Mengen
Die vier Behälter, in denen Python Daten sammelt.
Liste — geordnet, veränderbar
zahlen = [4, 8, 15, 16, 23, 42]
print(zahlen[0]) # 4
print(zahlen[-1]) # 42
print(len(zahlen)) # 6
print(zahlen[1:3]) # [8, 15]
zahlen.append(99) # hinten anfügen
zahlen.insert(0, 1) # an Position 0 einfügen
zahlen.remove(15) # Wert 15 entfernen
letztes = zahlen.pop() # letztes entnehmen und zurückgeben
zahlen.sort() # sortieren (verändert die Liste)
zahlen.reverse()
print(42 in zahlen) # True
print(sum(zahlen), min(zahlen), max(zahlen))List Comprehension
Kurzschreibweise, um aus einer Liste eine neue zu bauen:
quadrate = [x ** 2 for x in range(1, 6)]
print(quadrate) # [1, 4, 9, 16, 25]
gerade = [x for x in range(20) if x % 2 == 0]
print(gerade) # [0, 2, 4, ..., 18]Tupel — geordnet, unveränderbar
punkt = (3, 7)
x, y = punkt # "Entpacken"
print(x, y) # 3 7Nimm ein Tupel, wenn sich die Werte nie ändern sollen — Koordinaten, RGB-Farben, feste Konfiguration.
Dictionary — Schlüssel-Wert-Paare
Der wichtigste Datentyp in der Praxis:
person = {
"name": "Anna",
"alter": 29,
"stadt": "Berlin",
}
print(person["name"]) # Anna
print(person.get("beruf", "n/a")) # n/a — kein Fehler bei fehlendem Schlüssel
person["beruf"] = "Entwicklerin" # hinzufügen
person["alter"] = 30 # ändern
del person["stadt"] # löschen
for schluessel, wert in person.items():
print(f"{schluessel}: {wert}")
print("name" in person) # True
print(list(person.keys()))
print(list(person.values()))Achtung
person["beruf"] wirft einen KeyError, wenn der Schlüssel fehlt. person.get("beruf") gibt stattdessen None zurück.
Set — Menge ohne Duplikate
zahlen = {1, 2, 2, 3, 3, 3}
print(zahlen) # {1, 2, 3}
a = {1, 2, 3}
b = {3, 4, 5}
print(a | b) # {1,2,3,4,5} Vereinigung
print(a & b) # {3} Schnittmenge
print(a - b) # {1,2} DifferenzPraktisch, um Duplikate loszuwerden: list(set(meine_liste)).
Wann was?
| Brauche ich … | Nimm |
|---|---|
| geordnete Sammlung, die sich ändert | Liste |
| feste Wertegruppe | Tupel |
| Nachschlagen über einen Namen/Schlüssel | Dictionary |
| Eindeutigkeit, schnelle „ist drin?“-Prüfung | Set |
Funktionen
Der Punkt, an dem aus Skripten Programme werden.
def begruessen(name):
return f"Hallo {name}!"
print(begruessen("Anna"))defleitet die Definition ein.nameist der Parameter (Platzhalter),"Anna"das Argument (echter Wert).returngibt ein Ergebnis zurück und beendet die Funktion.
Ohne return gibt eine Funktion None zurück.
Standardwerte und benannte Argumente
def begruessen(name, gruss="Hallo"):
return f"{gruss} {name}!"
print(begruessen("Anna")) # Hallo Anna!
print(begruessen("Ben", "Moin")) # Moin Ben!
print(begruessen(gruss="Hi", name="Cem")) # Hi Cem!Mehrere Rückgabewerte
def min_max(zahlen):
return min(zahlen), max(zahlen)
kleinstes, groesstes = min_max([4, 8, 15, 16])
print(kleinstes, groesstes) # 4 16Docstrings und Type Hints
So sieht eine „erwachsene“ Funktion aus:
def flaeche(laenge: float, breite: float) -> float:
"""Berechnet die Fläche eines Rechtecks in Quadratmetern."""
return laenge * breiteType Hints (: float, -> float) sind Dokumentation für Menschen und Editoren — Python erzwingt sie nicht, aber VS Code warnt dich damit früh vor Fehlern.
Gültigkeitsbereich (Scope)
def f():
lokal = 5
print(lokal)
f()
print(lokal) # NameError — außerhalb unbekanntFaustregel
Eine Funktion sollte alles, was sie braucht, als Parameter bekommen und ihr Ergebnis mit return zurückgeben — nicht auf globale Variablen zugreifen.
Die main-Struktur
Bei Skripten, die mehr als ein paar Zeilen haben, üblich:
def main():
name = input("Name: ")
print(begruessen(name))
if __name__ == "__main__":
main()Die if-Zeile sorgt dafür, dass main() nur läuft, wenn die Datei direkt gestartet wird — nicht, wenn sie von einer anderen Datei importiert wird.
Fehler und Fehlerbehandlung
Fehlermeldungen sind die genaueste Hilfe, die du bekommst.
Fehlermeldungen lesen
Lies die letzte Zeile zuerst — dort steht Typ und Ursache. Die Zeile darüber sagt, wo es passiert ist.
Traceback (most recent call last):
File "test.py", line 3, in <module>
print(10 / 0)
ZeroDivisionError: division by zeroHäufige Fehlertypen
| Fehler | Bedeutung |
|---|---|
SyntaxError | Tippfehler — fehlender :, fehlende Klammer |
IndentationError | falsch eingerückt |
NameError | Variable existiert nicht (oft Tippfehler im Namen) |
TypeError | falscher Typ, z. B. "5" + 5 |
ValueError | richtiger Typ, unsinniger Wert, z. B. int("abc") |
IndexError | Listenindex außerhalb des Bereichs |
KeyError | Schlüssel im Dictionary nicht vorhanden |
FileNotFoundError | Datei gibt es nicht |
try / except
try:
zahl = int(input("Zahl: "))
ergebnis = 100 / zahl
except ValueError:
print("Das war keine Zahl.")
except ZeroDivisionError:
print("Durch 0 geht nicht.")
else:
print(f"Ergebnis: {ergebnis}") # nur wenn kein Fehler auftrat
finally:
print("Fertig.") # läuft immerNicht alles wegfangen
Fange nur Fehler ab, die du auch behandeln kannst. Ein pauschales except: verschluckt jeden Fehler und macht die Suche später zur Qual.
Selbst Fehler auslösen
def wurzel(x):
if x < 0:
raise ValueError("x darf nicht negativ sein")
return x ** 0.5Dateien lesen und schreiben
Damit Daten den Programmstart überleben.
Immer mit with arbeiten — das schließt die Datei automatisch, auch bei Fehlern.
Schreiben
with open("notizen.txt", "w", encoding="utf-8") as f:
f.write("Erste Zeile\n")
f.write("Zweite Zeile\n")Lesen
with open("notizen.txt", "r", encoding="utf-8") as f:
inhalt = f.read() # alles auf einmal
print(inhalt)
with open("notizen.txt", "r", encoding="utf-8") as f:
for zeile in f: # zeilenweise, speicherschonend
print(zeile.strip())Modi
| Modus | Bedeutung |
|---|---|
"r" | lesen (Standard); Fehler, wenn die Datei fehlt |
"w" | schreiben — überschreibt die Datei komplett |
"a" | anhängen |
"x" | neu anlegen; Fehler, wenn schon vorhanden |
Unter Windows wichtig
encoding="utf-8" immer angeben, sonst gibt es Ärger mit Umlauten.
JSON — strukturierte Daten speichern
import json
daten = {"name": "Anna", "punkte": [10, 20, 30]}
with open("daten.json", "w", encoding="utf-8") as f:
json.dump(daten, f, indent=2, ensure_ascii=False)
with open("daten.json", "r", encoding="utf-8") as f:
geladen = json.load(f)
print(geladen["punkte"]) # [10, 20, 30]Pfade mit pathlib
from pathlib import Path
ordner = Path("C:/Users/DeinName/PythonKurs")
datei = ordner / "notizen.txt" # Slash statt Strings zusammenkleben
print(datei.exists())
print(datei.read_text(encoding="utf-8"))
for py_datei in ordner.glob("*.py"):
print(py_datei.name)Module und die Standardbibliothek
„Batteries included“ — das meiste ist schon da.
Importieren
import math
print(math.sqrt(16)) # 4.0
print(math.pi)
from random import randint, choice
print(randint(1, 6))
print(choice(["Kopf", "Zahl"]))
import datetime as dt
print(dt.date.today())Nützliche Module ohne Installation
| Modul | Wofür |
|---|---|
math | Wurzeln, Rundung, Trigonometrie |
random | Zufallszahlen, zufällige Auswahl |
datetime | Datum und Uhrzeit |
json | JSON lesen/schreiben |
pathlib | Dateipfade |
os, sys | Betriebssystem, Kommandozeilen-Argumente |
csv | Tabellen im CSV-Format |
re | Reguläre Ausdrücke (Textmuster) |
collections | Counter, defaultdict u. a. |
Eigene Module
def begruessen(name):
return f"Hallo {name}!"from werkzeuge import begruessen
print(begruessen("Anna"))Beide Dateien liegen im selben Ordner.
Objektorientierung
Bauplan und Exemplar — die Grundlagen genügen fürs Erste.
Eine Klasse ist ein Bauplan, ein Objekt ein konkretes Exemplar davon.
class Konto:
def __init__(self, inhaber, stand=0):
self.inhaber = inhaber
self.stand = stand
def einzahlen(self, betrag):
if betrag <= 0:
raise ValueError("Betrag muss positiv sein")
self.stand += betrag
def abheben(self, betrag):
if betrag > self.stand:
raise ValueError("Nicht genug Guthaben")
self.stand -= betrag
def __str__(self):
return f"Konto {self.inhaber}: {self.stand:.2f} €"
konto = Konto("Anna", 100)
konto.einzahlen(50)
konto.abheben(30)
print(konto) # Konto Anna: 120.00 €__init__ist der Konstruktor — läuft beim Erzeugen des Objekts.selfist das Objekt selbst und steht als erster Parameter in jeder Methode.__str__bestimmt, wasprint(objekt)ausgibt.
Vererbung
class Sparkonto(Konto):
def __init__(self, inhaber, stand=0, zinssatz=0.02):
super().__init__(inhaber, stand)
self.zinssatz = zinssatz
def zinsen_gutschreiben(self):
self.einzahlen(self.stand * self.zinssatz)dataclass
Für reine Datencontainer bequemer:
from dataclasses import dataclass
@dataclass
class Punkt:
x: float
y: float
p = Punkt(3, 4)
print(p) # Punkt(x=3, y=4)Virtuelle Umgebungen und pip
Ein Projekt, eine Umgebung — dann kollidiert nichts.
# Im Projektordner:
python -m venv .venv
# Aktivieren:
.\.venv\Scripts\Activate.ps1Vorne in der Zeile steht jetzt (.venv).
Wenn PowerShell blockiert
Einmalig ausführen:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSignedPakete installieren
pip install requests
pip list # was ist installiert?
pip freeze > requirements.txt # festhalten
pip install -r requirements.txt # woanders wiederherstellenDeaktivieren mit deactivate. Der Ordner .venv gehört nicht ins Git-Repository.
Beliebte Pakete
| Paket | Wofür |
|---|---|
requests | Webseiten/APIs abrufen |
pandas | Tabellen und Datenanalyse |
matplotlib | Diagramme |
openpyxl | Excel-Dateien |
flask / fastapi | Webanwendungen und APIs |
pytest | Tests schreiben |
Sauber programmieren
Gewohnheiten, die sich ab dem zweiten Projekt auszahlen.
Stil (PEP 8)
- 4 Leerzeichen einrücken, keine Tabs.
snake_casefür Variablen und Funktionen,PascalCasefür Klassen.- Leerzeichen um Operatoren:
a = b + c, nichta=b+c. - Zeilen möglichst unter ~88 Zeichen.
Struktur
- Eine Funktion, eine Aufgabe. Wird sie länger als ~20 Zeilen, zerlege sie.
- Wiederholst du Code zum dritten Mal, mach eine Funktion daraus.
- Sprechende Namen schlagen Kommentare. Kommentiere das Warum, nicht das Was.
Debuggen
print()an den entscheidenden Stellen ist völlig legitim und oft am schnellsten.- Der Debugger in VS Code (
F5, Haltepunkt per Klick links neben die Zeilennummer) zeigt dir alle Variablen zu jedem Zeitpunkt. - Fehlermeldung nicht verstanden? Den Text der letzten Zeile wörtlich suchen — meist steht die Antwort auf Stack Overflow.
Testen
from rechnen import addiere
def test_addiere():
assert addiere(2, 3) == 5Ausführen mit pytest. Sobald du Funktionen schreibst, auf die du dich verlassen willst, lohnen sich Tests.
Übungsprojekte
In dieser Reihenfolge — jedes Projekt baut auf dem vorigen auf.
Temperaturumrechner
Celsius einlesen, in Fahrenheit umrechnen, ausgeben.
übt: input · float · f-Strings
Zahlenraten
Programm würfelt 1–100, Nutzer rät, Hinweis „zu hoch“/„zu niedrig“, Versuche zählen.
übt: random · while · if · break
Notenrechner
Beliebig viele Noten einlesen (Abbruch bei leerer Eingabe), Durchschnitt, beste und schlechteste Note ausgeben.
übt: Listen · Schleifen · sum/min/max
To-do-Liste
Menü: Aufgabe hinzufügen, anzeigen, abhaken, löschen, beenden. Speichern in einer JSON-Datei, sodass die Liste beim nächsten Start noch da ist.
übt: Dictionaries · Funktionen · Dateien · JSON
Wortzähler
Textdatei einlesen, die 10 häufigsten Wörter ausgeben.
übt: Dateien · collections.Counter · Sortieren
Wetterabfrage
Mit requests eine offene Wetter-API abfragen (z. B. open-meteo.com, ohne Schlüssel) und die Temperatur für eine Stadt anzeigen.
übt: pip · APIs · JSON · Fehlerbehandlung
Wenn du feststeckst
Zerlege die Aufgabe in den kleinstmöglichen nächsten Schritt und bring nur den zum Laufen. „To-do-Liste“ ist unlösbar groß; „Eine Aufgabe an eine Liste anhängen und ausgeben“ ist in fünf Minuten erledigt.
Wie es weitergeht
Richtungen, sobald die Grundlagen sitzen.
Sinnvolle nächste Schritte
- Git und GitHub — Versionsverwaltung, gehört zum Handwerk.
- Tests mit
pytest. - Ein Schwerpunkt: Datenanalyse (
pandas), Web (fastapi/django), Automatisierung (Dateien, Excel, E-Mails) oder Machine Learning.
Nachschlagen
- docs.python.org/de — offizielle Doku, auf Deutsch
- Automate the Boring Stuff — kostenlos online, sehr praxisnah
- Real Python — gute Tutorials mittlerer Tiefe
Die wichtigste Regel
Lies weniger, tippe mehr. Nimm dir ein kleines eigenes Problem aus deinem Alltag — eine Datei umbenennen, eine Tabelle auswerten, etwas regelmäßig abfragen — und löse es mit Python. Damit lernst du in einer Woche mehr als mit zehn Tutorials.