Editor-Trick des Tages: Kommentarzeichen automatisch hinzufügen

In VSCode können Sie beliebig viele Zeilen markieren und mit einem Shortcut alle ausgewählten Zeilen auskommentieren. Das ist hilfreich, wenn Sie beispielsweise viele Aufrufe von print() geschrieben haben, die Sie jetzt nicht mehr brauchen.

Der Shortcut für Toggle Line Comment lautet Ctrl + #. Falls die markierten Zeilen bereits kommentiert sind, wird diese Tastenkombination die Kommentarzeichen entfernen. Wenn eine der markierten Zeilen schon kommentiert ist, aber die anderen nicht, werden überall Kommentarzeichen eingefügt:

print("execute this")
# print("ignore this")

wird zu

# print("execute this")
# # print("ignore this")

Sie können diesen Shortcut mit dem Multicursor aus einer der letzten Sitzungen kombinieren. So können Sie Zeilen auskommentieren, die an verschiedenen Stellen in der Datei stehen.

Probieren Sie es aus! Kopieren Sie die folgenden Zeilen in eine Pythondatei in VSCode und verwenden Sie mehrere Cursors (z.B. mit Alt+Klicken) und den Kommentarshortcut, um alle Zeilen mit "Ignore this" auszukommentieren.

print("execute this")
print("IGNORE this")
print("execute this")
print("execute this")
print("IGNORE this")
print("execute this")
print("execute this")
print("execute this")
print("IGNORE this")

Datentyp des Tages: Sets (Mengen)

Mengen kennen Sie schon aus der Vorlesung "Mathematische Grundlagen der Computerlinguistik". Mengen (englisch: Sets) ähneln in Python Listen, haben aber einige Eigenschaften, die sie von Listen unterscheiden:

  • Sets sind unsortiert.
  • Sets enthalten jedes Item nur einmal.

Genau wie Listen sind Sets ebenfalls mutable, das bedeutet, sie können "in place" verändert werden.

Sets können auf mehrere Arten erzeugt werden:

In [ ]:
set1 = set()               # leere Menge erstellen...

for i in [1,2,3,3,4,4,5]:
    set1.add(i)            # ... und nach und nach füllen
    
print("Set 1: " + str(set1))
In [ ]:
set2 = set([1,2,3,3,4,4,5]) # Menge direkt beim Erstellen mit Elementen füllen

print("Set 2: " + str(set2))
In [ ]:
set3 = {1,2,3,3,4,4,5}      # Keine Verwechslungsgefahr mit Dictionarys:
                            # Sets haben keine Values, nur Keys
    
print("Set 3: " + str(set3))

Der Unterschied zwischen set2 und set3 ist, dass set2 mithilfe eines Funktionsaufrufs erzeugt wurde. (Wir erkennen Funktionen inzwischen an den runden Klammern: set()) set3 dagegen wurde direkt als Menge erstellt, analog zu den Datentypen, die wir schon länger kennen, z.B. Listen.

Aufgabe

  1. Führen Sie die folgenden Codebeispiele aus. Entspricht die Ausgabe Ihren Erwartungen? Haben Sie eine Erklärung dafür, warum das passiert, was passiert?
In [ ]:
set4 = set("This is the boss, and I'm sick of waiting")

print(set4)
In [ ]:
set5 = {}

print(type(set5))
In [ ]:
set6 = set("This is the boss, and I'm sick of waiting".split())

print(set6)

Die verschiedenen Schreibweisen zum Erstellen einer Menge werden heute noch einmal auftauchen.

Durch die Art, wie Sets im Arbeitsspeicher angelegt werden, kann mit ihnen effizienter gearbeitet werden als mit Listen. Wir verwenden also immer dann Sets, wenn die Sortierung und die Anzahl der Vorkommen einzelner Elemente keine Rolle spielen.

Operationen auf Sets

Beachten Sie, dass Sets mutable sind. Änderungen müssen also nicht explizit dem Variablennamen zugewiesen werden, sondern verändern automatisch sofort den Inhalt des Sets. Beispielsweise können wir mit set1.add("hallo") das Wort "hallo" in die Menge set1 einfügen.

Operation Bedeutung
len(s) Anzahl der Elemente in s
s.add(e) Füge dem Set s das Element e hinzu
s1.update(s2) Ergänze s1 um alle Elemente aus s2
s1.intersection(s2) oder s1 & s2 Erzeuge die Schnittmenge von s1 und s2
s1.union(s2) oder s1 | s2 Erzeuge die Vereinigungsmenge von s1 und s2
s1.difference(s2) oder s1 - s2 Erzeuge eine Menge, die alle Elemente enthält, die in s1, aber nicht in s2 enthalten sind
s1.issubset(s2) True, wenn s1 eine Teilmenge von s2 ist
e in s True, wenn das Element e in s enthalten ist; sonst False
s.discard(e) Entferne das Element e aus s, falls es enthalten ist

Interaktives Ausprobieren von Code in der Python-REPL

Wenn Sie eine schwierige Funktion schreiben und sich unsicher sind, wie bestimmte Anweisungen sich verhalten werden, ist es manchmal hilfreich, die Anweisungen isoliert auszuprobieren und sich das Ergebnis anzusehen.

Dazu steht Ihnen die interaktive Python-REPL zur Verfügung. REPL bedeutet Read-Evaluate-Print-Loop und bezeichnet Umgebungen, in denen einzelne Befehle eingegeben werden und dann gelesen und ausgewertet werden, woraufhin das Ergebnis ausgegeben wird.

Wir haben bisher viel mit Jupyter Notebooks als Ersatz für eine REPL gearbeitet, aber wenn Sie Ihr eigenes Programm schreiben, wäre es mühsam, erst ein Notebook starten zu müssen - und unnötig, schließlich läuft Python ja auch auf Ihrem System.

Wenn Sie in Visual Studio Code Ihr Programm schreiben, können Sie im Editor ein Terminal öffnen und dort Python interaktiv nutzen. Dazu öffnen Sie mit Ctrl + Shift + P die Command Palette und geben >REPL ein. Es erscheint ein Befehl namens Python: Start REPL, den Sie mit Enter bestätigen.

Unterhalb des Textbereichs im Editor sehen Sie jetzt ein Terminal, in dem Python geöffnet wird.

Der Prompt im Terminal besteht aus der Sequenz >>>. Geben wir einen einzelnen Befehl ein, z.B. print("Hallo Welt!"), und bestätigen ihn mit Enter, wird der Befehl sofort ausgeführt. In der folgenden Zeile steht die Ausgabe des Befehls. Darauf folgt eine neue Zeile mit einem Prompt, in der wir wieder eine Eingabe machen können.

Read-Evaluate-Print

Read-Evaluate-Print bedeutet, dass der Interpreter nach jeder Zeile versucht, den eingegebenen Code auszuwerten. Das schlägt fehl, wenn wir z.B. nicht alle Klammern schließen, die wir geöffnet haben. Dann folgt eine Zeile mit einem Prompt der Form ..., in der wir den restlichen Code - mindestens die schließende Klammer - eingeben können.

Wir können auch Schleifen oder Funktionsdefinitionen in der REPL schreiben. Das ist leider etwas mühsam, weil die Einrückungen nicht automatisch gesetzt werden und wir also in jeder Zeile neu vier Leerzeichen setzen müssen (oder noch mehr, je nach Verschachtelung).

Sie können die REPL nutzen, um bestimmte Anweisungen isoliert auszuprobieren, bevor Sie sie in Ihr Programm einbauen.

Besonderheiten der REPL

Bisher haben wir Code im Umfang ganzer Dateien ausgeführt. Sobald ein Fehler auftrat, stürzte unser Programm ab und wir mussten es nochmal versuchen. In der REPL ist das anders: Wenn eine eingegebene Zeile fehlschlägt, bleibt die REPL offen und Sie können direkt die nächste Zeile eingeben und ausführen.

Eine weitere Besonderheit der REPL ist, dass wir uns Werte anzeigen lassen können, ohne print() aufzurufen. Das liegt daran, dass der REPL-Interpreter die eingegebene Zeile auswertet und uns die "Antwort" sofort sagt.

Bei Variablendefinitionen erhalten wir in der REPL keine Rückgabe, sondern sehen sofort den nächsten Prompt:

>>> s = "Ein String"
>>>

Sobald wir aber etwas eingeben, das zu einer Antwort ausgewertet werden kann, wird die Antwort direkt nach unserer Zeile angezeigt.

>>> s = "Ein String"
>>> s
"Ein String"
>>> 5 + 3
8
>>> print("Ausgabe")
Ausgabe
>>>

Wie Sie sehen, gibt es einen Unterschied zwischen dem Auswerten eines Strings und dem Aufrufen der print-Funktion.

Wann benutzen wir die REPL?

  • Wenn wir ein sehr kleines Code-Fragment ausprobieren wollen, bevor wir es in unsere Pythondatei einbauen: Wie funktioniert nochmal strip/split/join/...?
  • Wenn wir noch nicht genau wissen, wie wir eine Aufgabe lösen wollen. In der REPL können wir z.B. alle möglichen Operationen auf Listen oder Dictionarys einfach ausprobieren. Das hilft uns eventuell dabei, auf die richtige Idee zu kommen, wie die Aufgabe zu lösen ist. Zum Schluss übernehmen wir die Befehle, die nützlich sind, in unsere Pythondatei und haben eine fertige Lösung.

Recherchieren mit der Python-Dokumentation und StackOverflow

Inzwischen haben wir eine Reihe Funktionalitäten von Python besprochen, die Sie jederzeit in den Skripten der letzten Vorlesungen nachlesen können. Außerhalb dieses Kurses wird es Ihnen aber gelegentlich passieren, dass Sie etwas programmieren wollen, was im Kurs nicht behandelt wurde.

Die Python-Dokumentation listet die Datentypen und dazugehörigen Methoden, die wir verwenden können, auf und erklärt, wie jeder Bestandteil der Sprache eingesetzt wird. Sie ist daher eine unverzichtbare Ressource für Ihre weitere Programmierkarriere (sofern Sie bei Python bleiben).

Wenn Sie im Browser die Seite https://docs.python.org öffnen, sehen Sie Folgendes:

Da Pythonversionen sich teilweise stark unterscheiden, ist es wichtig, dass Sie auf die Doku für Ihre Version zugreifen. Dazu können Sie oben links die Version auswählen, in der Sie programmieren.

Oben rechts können Sie Stichworte eingeben, über die Sie etwas erfahren möchten. Nehmen wir beispielsweise an, dass wir aus einer Menge mit 10 Elementen genau 2 zufällige Elemente auswählen möchten. Wir kennen schon random.randint() für Zufallszahlen und random.choice() für die Auswahl genau eines zufälligen Elements aus einer Sequenz, aber können wir die Auswahl von 2 Elementen vielleicht auch mit einem einzigen Befehl umsetzen?

Zufällige Auswahl von n Elementen aus einer Menge

Da Methoden und andere Signalwörter in Python alle englischsprachig sind, müssen wir unser Ziel zunächst ins Englische übersetzen. Aus "zufällige Auswahl" wird "random sample".

Schon am Titel des ersten Treffers sehen wir, dass das Modul random eine Methode zur Verfügung stellt, die sample heißt. (Direktlink)

Wir sehen also, dass wir mit dem Befehl random.sample(our_set, 2) die Zufallsauswahl von 2 Elementen aus unserer Menge erreichen können. Im Text unterhalb des Befehls folgen Erklärungen, welche Typen die population haben kann und wie random.sample() sich verhält. Wir können ausprobieren, ob alles wie erwartet funktioniert:

In [ ]:
import random

our_set = {1,2,3,4,5,6,7,8,9,10}
for i in range(5):
    print(random.sample(our_set, 2))

StackOverflow als Ergänzung zur Python-Doku

Nicht immer ist es so leicht, in der Dokumentation nachzuschlagen, welche Befehle man benutzen muss, um bestimmte Dinge zu erreichen. Hier ein Beispiel:

Wir wollen einen String umdrehen. Wir verwenden die Doku, um herauszufinden, ob bzw. wie das geht. Egal, welche Suchbegriffe wir eingeben (reverse, string reverse, reverse string, revert string, ...), bekommen wir keinen offensichtlich richtigen Treffer.

In so einem Fall können wir Google bemühen. Idealerweise googeln Sie solche Fragen in etwa in der folgenden Form:

Wie Sie sehen, beginnt die Suchanfrage mit dem Stichwort python. Nichts ist frustrierender, als Zeit mit einer Erklärung zu verschwenden und erst nach einigen Minuten zu merken, dass die Erklärung sich auf die falsche Programmiersprache bezieht...

Danach folgt das Thema, das uns interessiert. Wir haben das Problem auf Englisch mit string reverse beschrieben.

Zuletzt folgt die Angabe des Stichworts stackoverflow.

StackOverflow ist eine Q&A-Seite für Programmierthemen, die seit 2008 existiert. Meist sind die Fragen sehr spezifisch und klar formuliert, oft enthalten sie kleine Codebeispiele, und dank dem Bewertungssystem für die Antworten sind richtige/empfehlenswerte Antworten leicht zu finden.

Wenn Sie die Antwort auf Ihre Frage auf anderen Seiten als SO finden, besteht immer die Gefahr, dass die Informationen veraltet sind oder sich auf eine andere Pythonversion beziehen! Auf SO wird die Pythonversion entweder direkt angegeben, oder in den Antworten wird darauf hingewiesen, falls es Unterschiede zwischen den Versionen gibt.

Schauen wir uns mal den ersten Treffer auf StackOverflow an:

Die bestbewertete Antwort steht als erstes unter der Frage. Der Beispielcode und die dazugehörige Ausgabe zeigen uns, dass die Lösung tatsächlich das macht, was wir erwarten. In der Erklärung ist eine Seite aus der Python-Dokumentation verlinkt, auf der wir mehr erfahren können.

Einige Kommentare der besten Antwort erwähnen, dass es einen Unterschied macht, ob man Python 2 oder Python 3 benutzt. Weiter unten folgen weitere ausführliche Antworten, in denen verschiedene Lösungen verglichen werden und wir lernen können, dass Slicing die beste Lösung für unseren Anwendungsfall ist.

Beachten Sie immer das Datum der Fragen und Antworten, die Sie bei der Recherche finden. Bei grundlegenden Fragen (im Erstsemesterkurs wahrscheinlich der häufigere Fall) ist es zwar zweitrangig, ob eine Antwort dieses Jahr oder vor drei Jahren gepostet wurde. Aber wenn Sie z.B. Probleme mit Ihrer Installation haben und eine Antwort auf SO finden, die mehrere Jahre alt ist, ist es sehr wahrscheinlich, dass die angegebene Lösung Ihnen heute nicht weiterhilft.

Merkmale einer guten StackOverflow-Antwort

  • Gute Bewertung (die Zahl links vom Text der Antwort)
  • Je nach Thema: Einigermaßen aktuelles Erstellungsdatum
  • Mindestens ein kurzes, verständliches Codebeispiel mit Angabe des erwarteten Outputs
  • Erklärung, warum der angegebene Code eine gute Wahl ist oder welche Alternativen es gibt
  • Information dazu, ob die Lösung in Python 2 oder Python 3 oder in allen Pythonversionen funktioniert
  • Idealerweise: Link auf offizielle Python-Dokumente, die weitere Infos zum Thema enthalten
  • Bei komplexeren Aufgaben: Einschätzung oder Messung des Rechenaufwands der angegebenen Lösung
  • Evtl. Vergleich verschiedener Möglichkeiten, das Problem zu lösen

Beim Recherchieren finden wir häufig Antworten, die wir gar nicht verstehen (weil wir erst seit wenigen Monaten programmieren). Das ist aber nicht schlimm! Wenn Sie weitersuchen oder im Thread etwas weiter nach unten scrollen, werden Sie verständlichere Posts zum Thema finden. So wird Ihr Verständnis der Programmiersprache nach und nach geschult.

Die Erfahrung zeigt, dass die Datenbasis von StackOverflow für fast alle unsere Programmierprobleme ausreichend ist. Python ist so verbreitet, dass die allermeisten Probleme, die uns begegnen, auch schon jemand anderem als uns passiert sind. Das bedeutet, dass man viele Jahre lang darauf verzichten kann, selbst eine Frage auf SO zu posten - man muss ja nur die Frage finden, die die letzte Person gestellt hat, die das gleiche Problem hatte.

Sonderfälle treten dann auf, wenn Sie z.B. mit besonderen Modulen arbeiten, die nicht so verbreitet sind. Dann kann es Sinn machen, eine eigene Frage zu stellen. StackOverflow hat eine Anleitung zum Stellen von Fragen, die sehr viel Wert darauf legt, dass keine Duplikate erzeugt werden.

Python-Doku vs. StackOverflow

Während die Python-Dokumentation schnell weiterhilft, wenn es darum geht, wie bestimmte Methoden verwendet werden, ist StackOverflow pragmatischer orientiert und hilft uns vor allem in Fällen, wo wir nicht wissen, welche Methode wir anwenden sollen.

Die Pythondokumentation sollte Ihre erste Anlaufstelle sein, wenn Sie spezielle Fragen zu einzelnen Datentypen, Methoden oder Modulen haben. Vor allem wenn Sie einem neuen Datentyp oder einem neuen Modul begegnen, lohnt es sich, in der Dokumentation nachzuschauen, was man mit diesem Datentyp/diesem Modul alles machen kann.

Wenn Sie Hilfe für einen konkreten, isolierbaren Anwendungsfall brauchen, ist manchmal StackOverflow die bessere Wahl. Die Python-Doku enthält zwar ausführliche Informationen zu einzelnen Themen, aber hilft nicht dabei, unterschiedliche Teile von Python miteinander zu kombinieren, um Aufgaben zu lösen.

Achten Sie darauf, dass Sie alles verstehen, was Sie in einer StackOverflow-Antwort finden. Falls Sie es nicht verstehen und trotzdem die vorgeschlagene Lösung in Ihr eigenes Programm einbauen, ist es sehr sehr sehr wahrscheinlich, dass es später Probleme gibt, weil die verwendete Lösung nicht hundertprozentig zum Kontext passt, in dem Sie sie verwenden.

Aufgabe

  1. In HTML gibt es einige Zeichen, die eine besondere Funktion haben, zum Beispiel die spitzen Klammern: <>. Um auf einer Webseite spitze Klammern als Symbole anzuzeigen, muss man sie deshalb anders schreiben, nämlich als &lt;&gt;. Genau wie der Backslash, den wir bereits kennen, ist das eine Methode, um bestimmte Zeichen zu escapen. Finden Sie mithilfe der Python-Dokumentation heraus, mit welcher Methode man diese Zeichen in Strings escapet. Suchen Sie auch eine StackOverflow-Antwort zu dem Thema. Welche der beiden Ressourcen finden Sie verständlicher? Tipp: Sie können die Google-Suchanfragen python docs html escape und python html escape stackoverflow verwenden.
  2. Auf StackOverflow finden Sie einen Thread über die Frage, wie man am besten Mengen initialisiert. Passt der Inhalt der Antworten zu Ihren Überlegungen am Anfang der heutigen Vorlesung?

Zusammenfassung

Sie haben heute gelernt,

  • wie Mengen in Python verwendet werden und worin sie sich von Listen unterscheiden
  • wie Sie in VSCode eine interaktive Python-Umgebung (REPL) starten, in der Sie einzelne Befehle nacheinander ausführen können
  • wie Sie die Python-Dokumentation und StackOverflow nutzen können, um mehr über Python zu lernen und um Probleme zu lösen, bei denen Sie alleine nicht weiterkommen
  • wie Sie mit random.sample() eine zufällige Auswahl einer bestimmten Anzahl von Elementen aus einer Kollektion extrahieren können
  • wie Sie in Python einen String umdrehen können
  • wie Sie in Python einen String html-escapen können