Lektion 1.1

Programmieren in einer textbasierten Sprache

19 min Lesezeit

In einer blockbasierten Umgebung wie Scratch steckst du Programme aus Blöcken zusammen. Bei größeren Programmen wird das mühsam: Hunderte Blöcke passen nicht auf den Bildschirm, und eine Änderung mitten im Programm kostet viel Mausarbeit. Darum sind fast alle Programme im Alltag als Text geschrieben.

Du lernst, dasselbe in Python zu tun: womit ein Programm rechnet, wie du es in Teile zerlegst, wie es mit Benutzern und Dateien spricht und wie du Fehler findest.

Definition

Vom Block zum Text

In einer textbasierten Programmiersprache schreibst du jede Anweisung als Zeile Text, und der Computer liest sie von oben nach unten. Die Schreibregeln der Sprache heißen Syntax. In Python gehört die Einrückung zur Syntax: Was zu einer Wiederholung oder Verzweigung gehört, steht eingerückt unter der Zeile mit dem Doppelpunkt. Ein Kommentar beginnt mit #\texttt{\#}, der Computer überspringt ihn.

BlockPython
setze zahl auf 5zahl = 5\texttt{zahl = 5}
sage zahlprint(zahl)\texttt{print(zahl)}
wiederhole 3 malfor i in range(3):\texttt{for i in range(3):}
falls zahl größer als 4, sonstif zahl > 4:\texttt{if zahl > 4:} und else:\texttt{else:}
wiederhole, solange zahl kleiner als 50while zahl < 50:\texttt{while zahl < 50:}

Das Zeichen =\texttt{=} heißt "speichere den Wert rechts in der Variablen links". range(3)\texttt{range(3)} liefert 0, 1 und 2, die Schleife läuft also dreimal.

Definition

Datentypen, Variablen und Operatoren

Jeder Wert hat einen Datentyp. Er bestimmt, was man mit dem Wert tun kann.

DatentypPythonBeispiele
Ganzzahlint\texttt{int}7\texttt{7}, -3\texttt{-3}
Gleitkommazahl (mit Nachkommastellen)float\texttt{float}3.5\texttt{3.5} (Punkt statt Komma)
Wahrheitswertbool\texttt{bool}True\texttt{True}, False\texttt{False}
Zeichenkette (Text)str\texttt{str}"Hallo"\texttt{"Hallo"}

Eine Variable ist ein Name für einen gespeicherten Wert, preis = 4.5\texttt{preis = 4.5} legt sie an. Operatoren verknüpfen Werte:

OperatorBedeutungBeispiel mit Ergebnis
+ - *\texttt{+ - *}rechnen wie in der Mathematik3 * 4\texttt{3 * 4} ergibt 12
/\texttt{/}Division, Ergebnis immer float\texttt{float}7 / 2\texttt{7 / 2} ergibt 3.5
//\texttt{//}ganzzahlige Division, Rest verworfen7 // 2\texttt{7 // 2} ergibt 3
%\texttt{\%}Rest der Division7 % 2\texttt{7 \% 2} ergibt 1
== != < > <= >=\texttt{== != < > <= >=}Vergleich, Ergebnis ein Wahrheitswert7 > 2\texttt{7 > 2} ergibt True
Definition

Logische Verknüpfungen und Wahrheitstafel

Wahrheitswerte verknüpfst du mit and\texttt{and} (und), or\texttt{or} (oder) und not\texttt{not} (nicht). Die Wahrheitstafel listet für jede Belegung von aa und bb das Ergebnis:

aba and ba or bnot a
FalseFalseFalseFalseTrue
FalseTrueFalseTrueTrue
TrueFalseFalseTrueFalse
TrueTrueTrueTrueFalse

and\texttt{and} ist nur wahr, wenn beide Seiten wahr sind. or\texttt{or} ist wahr, sobald eine Seite wahr ist. Vergleiche werden vor and\texttt{and} und or\texttt{or} ausgewertet.

Definition

Felder und Listen

Ein Feld (englisch Array) speichert viele Werte unter einem Namen. Jeder Wert hat eine Nummer, den Index, und der Index beginnt bei 0. In Python heißt dieser Typ Liste; sie kann wachsen und schrumpfen.

AnweisungWirkung
werte = [4, 8, 15]\texttt{werte = [4, 8, 15]}legt eine Liste an
werte[0]\texttt{werte[0]}erstes Element, hier 4
len(werte)\texttt{len(werte)}Länge der Liste, hier 3
werte.append(23)\texttt{werte.append(23)}hängt 23 hinten an
for w in werte:\texttt{for w in werte:}durchläuft alle Elemente der Reihe nach
Definition

Unterprogramme, Modularisierung, Bibliotheken und Zufallszahlen

Ein Unterprogramm (in Python eine Funktion) ist ein benannter Programmteil, den du immer wieder aufrufen kannst. Werte kommen über Parameter hinein, und return\texttt{return} gibt einen Rückgabewert zurück.

ZeileEinrückungAnweisung
10def verdoppeln(x):\texttt{def verdoppeln(x):}
21return x * 2\texttt{return x * 2}

verdoppeln(7)\texttt{verdoppeln(7)} ergibt 14. Modularisierung heißt, ein großes Programm in Teile mit je einer Aufgabe zu zerlegen, die du einzeln schreibst und testest. Eine Programmbibliothek ist eine fertige Sammlung von Unterprogrammen, die du mit import\texttt{import} holst. Die Bibliothek random\texttt{random} liefert Zufallszahlen: random.randint(1, 6)\texttt{random.randint(1, 6)} gibt eine ganze Zahl von 1 bis 6 zurück, beide Grenzen eingeschlossen. Der Computer erzeugt sie nach einer Rechenvorschrift, die zufällig wirkt (Pseudozufall).

Beispiel

Ein Unterprogramm mit einer Liste

Wie lautet die Ausgabe?

ZeileEinrückungAnweisung
10def mittelwert(zahlen):\texttt{def mittelwert(zahlen):}
21summe = 0\texttt{summe = 0}
31for z in zahlen:\texttt{for z in zahlen:}
42summe = summe + z\texttt{summe = summe + z}
51return summe / len(zahlen)\texttt{return summe / len(zahlen)}
60print(mittelwert([4, 8, 15, 5]))\texttt{print(mittelwert([4, 8, 15, 5]))}

Zeile 6 ruft die Funktion auf, der Parameter zahlen\texttt{zahlen} bekommt die Liste. Die Schleife addiert die Elemente: summe wird 4, dann 12, dann 27, dann 32. len(zahlen)\texttt{len(zahlen)} ist 4. Der Rückgabewert ist 32 / 4 = 8.0, und print\texttt{print} gibt 8.0 aus.

Definition

Eingabe, Dateien und grafische Oberfläche

Mit name = input("Dein Name: ")\texttt{name = input("Dein Name: ")} zeigt das Programm den Text an und wartet. input\texttt{input} liefert das Eingegebene immer als Zeichenkette. Eine Zahl wandelst du mit int(...)\texttt{int(...)} oder float(...)\texttt{float(...)} um.

Nach dem Programmende sind die Variablen weg. Dauerhaft bleiben Daten nur in Dateien. with open("namen.txt", "w") as f:\texttt{with open("namen.txt", "w") as f:} öffnet eine Datei zum Schreiben, und eingerückt darunter schreibt f.write("Anna")\texttt{f.write("Anna")} Text hinein. Mit "r"\texttt{"r"} statt "w"\texttt{"w"} öffnest du sie zum Lesen, und f.read()\texttt{f.read()} liefert den Inhalt als Zeichenkette.

Eine grafische Benutzeroberfläche (GUI) hat Fenster, Knöpfe und Textfelder. Python bringt dafür die Bibliothek tkinter\texttt{tkinter} mit. Jeder Knopf bekommt ein Unterprogramm, das beim Klick läuft. Das Programm wartet auf Ereignisse wie Klicks, statt nur von oben nach unten zu laufen.

Definition

Spezifikation, Lesbarkeit und Kommentare

Bevor du programmierst, legst du die Spezifikation fest: eine genaue Beschreibung, was das Programm bei welchen Eingaben liefern soll, auch in Sonderfällen. Für mittelwert\texttt{mittelwert} lautet sie: "Eingabe ist eine Liste mit mindestens einer Zahl, Ausgabe ist die Summe geteilt durch die Anzahl."

Der Quelltext soll lesbar sein: sprechende Namen (mittelwert\texttt{mittelwert} statt m\texttt{m}), kurze Unterprogramme, saubere Einrückung. Ein Kommentar erklärt, warum etwas so geschrieben ist, nicht nur, was dort steht: # -999 bedeutet: kein Messwert\texttt{\# -999 bedeutet: kein Messwert}.

Definition

Fehlerarten, Tests, Debugger und Logging

Es gibt drei Fehlerarten. Bei einem Syntaxfehler versteht Python das Programm nicht, und es startet gar nicht (zum Beispiel fehlt der Doppelpunkt hinter if\texttt{if}). Bei einem Laufzeitfehler startet es, bricht aber in einer Zeile ab, etwa bei 5 / 0\texttt{5 / 0} oder int("abc")\texttt{int("abc")}. Bei einem Semantikfehler läuft es durch und liefert ein falsches Ergebnis.

Semantikfehler findest du durch Testen. Ein Testfall besteht aus einer Eingabe und dem erwarteten Ergebnis, das du aus der Spezifikation bestimmst. Ein automatisierter Test prüft das selbst: assert mittelwert([4, 8]) == 6\texttt{assert mittelwert([4, 8]) == 6} bricht mit einer Fehlermeldung ab, wenn das Ergebnis nicht stimmt. Teste normale Fälle und Grenzfälle.

Der Debugger führt das Programm Zeile für Zeile aus. An einem Haltepunkt hält er an, und du siehst alle Variablen. Logging heißt: Das Programm schreibt beim Laufen Meldungen auf, etwa mit print\texttt{print} oder der Bibliothek logging\texttt{logging}.

Beispiel

Einen Fehler mit einem Testfall finden

Diese Funktion soll den Mittelwert berechnen. Der Test in Zeile 6 schlägt fehl.

ZeileEinrückungAnweisung
10def mittelwert(zahlen):\texttt{def mittelwert(zahlen):}
21summe = 0\texttt{summe = 0}
31for z in zahlen:\texttt{for z in zahlen:}
42summe = summe + z\texttt{summe = summe + z}
51return summe / (len(zahlen) + 1)\texttt{return summe / (len(zahlen) + 1)}
60assert mittelwert([4, 8]) == 6\texttt{assert mittelwert([4, 8]) == 6}

Erwartet wird (4 + 8) / 2 = 6. Das Programm rechnet 12 / 3 = 4.0, der Vergleich 4.0 == 6 ist falsch, und assert\texttt{assert} bricht ab. Ohne den Test gäbe es nur ein falsches Ergebnis ohne Meldung: ein Semantikfehler. Die Ursache steckt in Zeile 5, der Teiler ist um 1 zu groß. Richtig ist return summe / len(zahlen)\texttt{return summe / len(zahlen)}, dann gilt 12 / 2 = 6.0, und der Test besteht.

Grenzfall: mittelwert([])\texttt{mittelwert([])} teilt durch 0 (Laufzeitfehler). Die Spezifikation schließt die leere Liste aus, das ist erlaubt.

Häufige Fehler

Gleichheitszeichen und Vergleich

„x = 5\texttt{x = 5} und x == 5\texttt{x == 5} bedeuten dasselbe.“

Richtig ist

x = 5\texttt{x = 5} speichert den Wert 5 in x. x == 5\texttt{x == 5} vergleicht und liefert True oder False. In einer Bedingung schreibst du if x == 5:\texttt{if x == 5:}. Mit nur einem Gleichheitszeichen meldet Python einen Syntaxfehler.

Häufige Fehler

Eingaben sind Zahlen

„input\texttt{input} liefert die Zahl, die ich eintippe, ich kann gleich damit rechnen.“

Richtig ist

input\texttt{input} liefert immer eine Zeichenkette. Aus "3" und "4" macht das Pluszeichen "34", nicht 7. Erst int(input(...))\texttt{int(input(...))} gibt dir eine Zahl.

Zusammenfassung

  • Python schreibt Programme als Zeilen. Die Einrückung gehört zur Syntax, Kommentare beginnen mit #.

  • Datentypen: Ganzzahl, Gleitkommazahl, Wahrheitswert, Zeichenkette. Operatoren rechnen, vergleichen und verknüpfen (and, or, not).

  • Listen speichern viele Werte unter einem Namen, der Index beginnt bei 0.

  • Unterprogramme haben Parameter und einen Rückgabewert. Modularisierung und Bibliotheken wie random halten Programme übersichtlich.

  • Eingaben liefern Zeichenketten, Dateien bewahren Daten dauerhaft, eine GUI reagiert auf Ereignisse.

  • Eine Spezifikation legt vorher fest, was das Programm tun soll. Lesbarer Quelltext und Kommentare helfen beim Verstehen.

  • Syntax-, Laufzeit- und Semantikfehler unterscheiden sich. Testfälle, Debugger und Logging helfen bei der Suche.

Übungen

Aufgabe 1Numerisch

Das Programm setzt a = 29\texttt{a = 29} und gibt dann a // 6 + a % 6\texttt{a // 6 + a \% 6} aus. Welche Zahl erscheint?

Aufgabe 2Multiple Choice

Für welche Belegung ist "a or not b" falsch?

Aufgabe 3Multiple Choice

Ein Programm startet ohne Meldung und läuft bis zum Ende, gibt aber für den Mittelwert von 2 und 4 den Wert 2.0 aus. Welche Fehlerart liegt vor?

Aufgabe 4Freitext

Du schreibst alter = input("Alter: ")\texttt{alter = input("Alter: ")} und dann print(alter + 1)\texttt{print(alter + 1)}. Das Programm bricht mit einem Laufzeitfehler ab. Erkläre die Ursache und gib die verbesserte Zeile an.