Kategorien
IT Programmierung

Ein Python Labyrinth Generator

In meinem heutigen Artikel möchte ich mich der Frage widmen, wie man denn ein zufälliges Labyrinth erzeugen kann. Dazu stelle ich vor, wie ich diese Aufgabe umgesetzt habe und einen Python Labyrinth Generator implementiert habe.
Was man grundsätzlich zum Einstieg in Python benötigt und wie man sich eine entsprechende Entwicklungsumgebung unter Windows aufsetzt habe ich bereits in früheren Artikeln beschrieben, wer mag kann dort gerne reinschauen! (Teil 1, Teil 2). Eine solche Umgebung habe ich für mein Labyrinth mit Python verwendet.

Mein Beitrag gliedert sich wie folgt:

Erste Schritte zum eigenen Labyrinth Generator

Doch nun zurück zum Python Labyrinth Generator: Wie erzeuge ich ein zufällig generiertes Labyrinth? Dazu habe ich mir zuerst eine Struktur überlegt, welche das Labyrinth repräsentiert. Es bietet sich an, den Datentyp Liste zu verwenden. Listen lassen sich auch verschachteln, so ist es möglich das Labyrinth zeilenweise im Speicher zu hinterlegen. Mein Labyrinth hat also die Datenstruktur einer Liste von Listen. Die äußere Liste enthält die Zeilen des Labyrinths, und jede Zeile wird durch eine innere Liste repräsentiert, die die einzelnen Felder dieser Zeile enthält. Jedes Feld wird nun durch einen bestimmten Wert repräsentiert, der den Status des Feldes im Labyrinth angibt.

Das Ganze initialisiere ich beim Klassenaufruf wie folgt:

class Maze:
    length = 0
    width = 0
    PATH = "."
    WALL = "w"
    UNKNOWN_SPOT = "u"
    __wall_todo_list = []

def __init__(self, length, width):
    self.length = length
    self.width = width
    self.maze = []
    for i in range(length):
        line = []
        for j in range(width):
            line.append(Maze.UNKNOWN_SPOT)
        self.maze.append(line)Code-Sprache: Python (python)

Dieser Python-Code definiert das Labyrinth als eine Klasse namens Maze und enthält die Methode init(), die beim Erstellen eines neuen Objekts der Klasse aufgerufen wird. Die Methode initialisiert ein neues Labyrinth mit einer bestimmten Breite und Länge die dem Konstruktor zu übergeben sind. Jedes Feld im Labyrinth wird mit dem Wert für UNKNOWN_SPOT initialisiert, repräsentiert durch ein einzelnes Zeichen. Wir haben jetzt also eine zweidimensionale Liste in gewünschter Größe des Labyrinths (Länge * Breite), in der jedes Feld noch unbekannt ist. Jedes Feld wird grundsätzlich durch ein einzelnes Zeichen näher spezifiziert.

Die Klassenvariablen enthalten neben Länge und Breite, sowie den drei Typen von Feldern (Pfad, Wand oder Unbekannt) auch eine Hilfsliste __wall_todo_list = []. Die Verwendung dieser Liste erkläre ich später.

Da unser Grundgerüst jetzt steht, können wir mit der Erzeugung eines Zufallslabyrinths beginnen.

Beginn der Erzeugung per zufälligem Startpunkt

Um ein Labyrinth zufällig zu berechnen gehe ich wie folgt vor: Zu allererst deklariere ich mir eine Funktion gen_random_maze(self) in der alle weiteren Schritte erfolgen und den eigentlichen Python Labyrinth Generator enthält. Die im folgenden gezeigten Codeausschnitte liegen, sofern nicht explizit anders dargestellt, alle in dieser Funktion.

Anschließend initialisiere ich den Python-eigenen Zufallsgenerator mit random.seed(). Diesen rufe ich ohne Parameter auf, was den Zufallsgenerator mit der aktuellen Systemzeit initialisiert und somit eine unterschiedliche Sequenz von Zufallszahlen bei jedem Programmstart erzeugt.
Anschließend generiere ich sowohl eine zufällige Längen- als auch Breitenkoordinate die innerhalb des noch unbekannten Labyrinths liegen. Das somit zufällig gewählte, innere Feld deklariere ich als Pfad. Alle vier Felder, die unmittelbar an diesen neuen Pfad angrenzen und noch unbekannt sind deklariere ich als Wand (Letzteres habe ich ausgegliedert in eine interne Hilfsfunktion).

Die so erzeugten, neuen Wand-Felder setze ich auf unsere eingangs erwähnte Hilfsliste __wall_todo_list. Diese Liste werden wir im weiteren Verlauf heranziehen um weitere Felder zu bearbeiten. Jeder Eintrag dieser Liste muss abgearbeitet werden, sie dient also als Todo-Liste.

def gen_random_maze(self):
    rand_length = random.randint(1, self.length - 2)
    rand_width = random.randint(1, self.width - 2)
    self.maze[rand_length][rand_width] = Maze.PATH
    self.__set_neighbouring_unknowns_as_walls([rand_length, rand_width])
[...]Code-Sprache: Python (python)
def __set_neighbouring_unknowns_as_walls(self, coord):

    if self.maze[coord[0] - 1][coord[1]] == self.UNKNOWN_SPOT:
        self.maze[coord[0] - 1][coord[1]] = self.WALL
        self.__wall_todo_list.append([coord[0] - 1, coord[1]])

    if self.maze[coord[0]][coord[1] + 1] == self.UNKNOWN_SPOT:
        self.maze[coord[0]][coord[1] + 1] = self.WALL
        self.__wall_todo_list.append([coord[0], coord[1] + 1])

    if self.maze[coord[0] + 1][coord[1]] == self.UNKNOWN_SPOT:
        self.maze[coord[0] + 1][coord[1]] = self.WALL
        self.__wall_todo_list.append([coord[0] + 1, coord[1]])

    if self.maze[coord[0]][coord[1] - 1] == self.UNKNOWN_SPOT:
        self.maze[coord[0]][coord[1] - 1] = self.WALL
        self.__wall_todo_list.append([coord[0], coord[1] - 1])Code-Sprache: Python (python)

Nun, da wir einen zufälligen Startpunkt sowie eine initiale Hilfsliste haben, können wir mit dem Schleifendurchlauf zur Erzeugung von Pfaden beginnen.

Zufallspfade per Schleife erzeugen

Wie oben erwähnt, werden auf unsere Hilfsliste __wall_todo_list immer die neuen erzeugten Felder vom Typ Wand gesetzt. Über diese Liste lassen wir im Folgenden unseren Algorithmus laufen und prüfen jeweils, ob sich neue Pfade setzen lassen.

Dazu passiert folgendes: Ich nutze eine while-Schleife, die so lange ausgeführt wird, wie das Attribut __wall_todo_list nicht leer ist.

Innerhalb der Schleife gibt es mehrere Schritte. Zunächst werden zwei boolesche Hilfsparameter zurückgesetzt. Dann wird ein zufälliges Element aus der Liste __wall_todo_list ausgewählt per random.choice() Methode. Dies ist die Stelle im Code an der der zufällige Pfadverlauf entsteht.

Anschließend wird überprüft, ob das zufällig ausgewählte Feld nicht an einer Außenwand liegt, indem geprüft wird, ob seine Koordinaten im inneren Bereich des Labyrinths liegen. Wenn das der Fall ist, wird gezählt, wie viele direkte Nachbarn vom Typ Pfad das ausgewählte Feld hat. Wenn genau ein Nachbar ein Pfad ist, wird das aktuell ausgewählte Feld ebenfalls als Weg markiert. Seine Nachbarn, die noch als unbekannt markiert sind, werden zudem als Wände markiert und kommen zusätzlich auf die abzuarbeitende Hilfsliste.

Zuletzt wird das nun abgearbeitete Feld aus der __wall_todo_list entfernt, um sicherzustellen, dass es nicht wiederholt besucht wird. Der Schleifenkörper wird so oft wiederholt, bis die __wall_todo_list leer ist.

Das Ganze sieht im Python Code dann so aus:

while self.__wall_todo_list:
    inner_position = False
    one_path_neighbor = False
    rand_wall_field = random.choice(self.__wall_todo_list)
    if (rand_wall_field[0] > 0) \
            and (rand_wall_field[1] > 0) \
            and (rand_wall_field[0] < (self.length - 1)) \
            and (rand_wall_field[1] < self.width - 1):
        inner_position = True
        if self.__count_neighbouring_paths(rand_wall_field) == 1:
            one_path_neighbor = True
    if one_path_neighbor and inner_position:
        self.maze[rand_wall_field[0]][rand_wall_field[1]] = Maze.PATH
        self.__set_neighbouring_unknowns_as_walls(rand_wall_field)
    for w in self.__wall_todo_list:
        if w[0] == rand_wall_field[0] and w[1] == rand_wall_field[1]:
            self.__wall_todo_list.remove(w)
Code-Sprache: Python (python)

Die gegebene Methode __count_neighbouring_paths() zählt die Anzahl der Nachbarfelder des gegebenen Feldes, die vom Typ Pfad sind.

Die Methode nimmt die Koordinaten eines Feldes als Eingabe und prüft dann, ob jedes der vier umgebenden Felder ein Pfad-Feld ist. Wenn ein Nachbarfeld ein Pfad ist, wird s_paths um 1 erhöht. Am Ende der Methode wird s_paths zurückgegeben, was die Anzahl der Pfade rund um das gegebene Feld angibt. Beachte, dass die Methode darauf ausgelegt ist, nur mit Koordinaten innerhalb des Labyrinths aufgerufen zu werden, da sie ohne Überprüfung auf den Rand des Labyrinths zugreift.

def __count_neighbouring_paths(self, coord):
    s_paths = 0
    if self.maze[coord[0] - 1][coord[1]] == Maze.PATH:
        s_paths += 1
    if self.maze[coord[0] + 1][coord[1]] == Maze.PATH:
        s_paths += 1
    if self.maze[coord[0]][coord[1] - 1] == Maze.PATH:
        s_paths += 1
    if self.maze[coord[0]][coord[1] + 1] == Maze.PATH:
        s_paths += 1
    return s_pathsCode-Sprache: PHP (php)

Abschließende Fertigstellung des Labyrinths

Die Schleife hat nun also einen eindeutigen und zufälligen Pfad durch das Labyrinth erzeugt.
Es bleiben aber noch zwei Dinge zum Abschluss zu erledigen: Das Abarbeiten eventuell noch vorhandener, unbekannter Felder sowie das Setzen von Ein- und Ausgangspfaden.

Möglichwerweise noch vorhandene, unbekannte Felder müssen noch betrachtet werden. Dazu durchlaufe ich mit zwei verschachtelten for-Schleifen das gesamte Labyrinth. Jedes gefundene unbekannte Feld wird dann entsprechend als Wand deklariert.

def __set_remaining_unknown_as_wall(self):
    for i in range(self.length):
        for j in range(self.width):
            if self.maze[i][j] == Maze.UNKNOWN_SPOT:
                self.maze[i][j] = Maze.WALL
Code-Sprache: Python (python)

Im letzten Schritt müssen noch Eingangs- und Ausgangspfad erzeugt werden. Dazu habe ich jeweils eine for-Schleife implementiert, als Teil einer Methode __set_entrance_and_exit(). Diese dienen dazu, einen Eingang und einen Ausgang für das Labyrinth zu setzen.

Bei der ersten Schleife wird ein Pfad-Feld auf der linken Seite des Labyrinths gesucht, indem die Spalte an Index 1 für jede Zeile durchsucht wird. Wenn ein Weg-Feld gefunden wird, wird das Feld links davon (also Index 0, bzw. auf der linken Außenwand) ebenfalls als Pfad markiert, um den Eingang zu schaffen, und die Schleife wird beendet.

Bei der zweiten Schleife wird ein Pfad-Feld neben der rechten Außenwand des Labyrinths gesucht, indem die Spalte an Index „Breite-2“ für jede Zeile durchsucht wird. Wenn ein Pfad-Feld gefunden wird, wird das Feld rechts davon (also auf der rechten Außenwand) ebenfalls als Pfad markiert, um den Ausgang zu schaffen. Dann wird auch diese zweite Schleife beendet.

def __set_entrance_and_exit(self):
    for i in range(self.length):
        if self.maze[i][1] == Maze.PATH:
            self.maze[i][0] = Maze.PATH
            break
    for i in range(self.length - 1, 0, -1):
        if self.maze[i][self.width - 2] == Maze.PATH:
            self.maze[i][self.width - 1] = Maze.PATH
            breakCode-Sprache: Python (python)

Der Python Labyrinth Generator ist fertig!

In meinem Beitrag habe ich gezeigt, wie die Erstellung eines zufällig generierten Labyrinths mithilfe der Programmiersprache Python erfolgen kann. Dazu habe ich zunächst die Datenstrukturen festgelegt und deren Initialisierung vorgestellt. Anschließend habe ich einen Algorithmus gezeigt, der in einer Schleife unter Zuhilfenahme des Zufallsgenerators Pfade innerhalb des Labyrinths erzeugt. Diese Pfade bilden letztlich einen zufälligen, aber eindeutigen und einzigartigen Weg durch das Labyrinth.

Für die Ausgabe der hiermit erzeugbaren Zufallslabyrinthe habe ich sowohl eine Methode zum String-basierten Druck auf die Konsole als auch eine Zeichnung auf eine Canvas der GUI Bibliothek tk implementiert. Wie genau das machbar ist beschreibe ich in einem anderen Beitrag. Im Ergebnis hier aber ein Bild eines mit dem hier dargestellten Codes erzeugten Labyrinths:

Python Labyrinth Generator Ergebnis

Ich hoffe mein Artikel ist eine nützliche Anregung für alle, die sich für das Erstellen von Labyrinthen interessieren und Python als Programmiersprache nutzen und kennenlernen möchten. Ich habe versucht die Erklärungen so zu strukturieren und verständlich darzustellen, so dass auch Anfänger in Python diesem Beitrag gut folgen können.

Kategorien
IT Programmierung

Start mit Python – Teil 2: Anleitung unter Windows

In diesem zweiten Teil meines Beitrages möchte ich auf die konkreten Schritte im Rahmen meiner Anleitung für den Start mit Python unter Windows eingehen.
Meinen zweiten Teil der Anleitung habe ich deswegen wie folgt gegliedert:

Im ersten Teil (zurück zu Teil 1) habe ich bereits beschrieben, welche Werkzeuge wir grundsätzlich benötigen und welche Konzepte zugrunde liegen. Mit diesem Wissen im Hinterkopf können wir uns nun auf die konkrete Umsetzung konzentrieren. Diese möchte ich in den folgenden Abschnitten Schritt für Schritt darstellen.

Installation der Anaconda Distribution unter Windows

Beginnen wir mit der Installation der Python Distribution, und somit auch des benötigten Interpreters. Zu aller erst müssen wir die Distribution von der Herausgeberseite herunterladen. Der Download des Installers kann hier gestartet werden:

https://www.anaconda.com/products/individual

Das nach Auswahl des Download Buttons auftauchende Formular für den Newsletter kann, muss aber nicht, befüllt werden.
Nachdem der Download abgeschlossen ist, könnt ihr den Installer ausführen. Dies öffnet den Startdialog zur Installation:

Start mit Python. Installer der Anaconda3 64bit Distribution.

Mit einem Klick auf Next gelangt ihr zu den Lizenzbedingungen. Dieses solltet ihr vollständig lesen. Seid ihr einverstanden, so erklärt ihr dies mit einem Klick auf ‚I Agree‘ und weiter geht’s.
Im Folgedialog wählt ihr aus, ob Anaconda nur für den aktuell eingeloggten Benutzer oder für alle Nutzer des Systems installiert werden soll. Ich empfehle die Installation für alle Nutzer.
Nachdem ihr das entschieden habt, müsst ihr noch bestätigen, dass der Installer seine Software systemweit installieren darf, und auswählen, unter welchem Pfad die Distribution installiert wird. Auch hier empfehle ich, den vorgeschlagenen Standardpfad zu verwenden.

Im folgenden Dialog ‚Advanced Installation Options‘ solltet ihr beide Optionen auswählen. Also das Setzen der Pfadvariable (PATH environment) und das Setzen von Anaconda3 als die Python Umgebung für das System. Ersteres hat zu Folge, dass Windows automatisch die ausführbaren Dateien der Distribution findet, ohne jedes Mal den kompletten Pfad eingeben zu müssen. Die zweite Option sorgt unter anderem dafür, dass später unsere IDE Anaconda als Python Umgebung erkennt.

Advanced Options Anaconda Installer

Nachdem ihr die beiden Optionen ausgewählt und mit einem Klick auf ‚Install‘ bestätigt habt, beginnt die Installation! Nach Abschluss der Installation bietet euch der Installer noch das Aufrufen von Tipps, hier ist es euch überlassen was ihr wählt. Mit Klick auf ‚Finish‘ habt ihr es dann geschafft. Herzlich Glückwunsch, die Anaconda Distribution ist nun erfolgreich installiert!

Test der Anaconda Installation

Ein kurzer Test gefällig, ob die Installation tatsächlich erfolgreich war? Startet zuerst eine Windows-Konsole indem ihr dazu die Tastenkombination WIN-R drückt und anschließend „cmd“ eingebt. Auf der Konsole gebt ihr dann den Befehl „ipython“ ein. Jetzt wird, dank gesetzter Pfadvariable während der Installation, aus dem aktuellen Pfad heraus die iPython-Konsole gestartet.
Dort könnt ihr wiederum jeden Python Befehl eingeben, zu Testzwecken sei hier einfach print("Hallo Welt") gewählt. Wenn alles funktioniert hat, sieht es so aus:

Test der iPython-Konsole
Zum Test ist hier die iPython-Konsole mit dem Befehl ‚ipython‘ gestartet. Neben der Ausführung von Python Befehlen lassen sich z.B. auch die Version des Interpreters u.v.m. nachsehen.

Wie eingangs beschrieben, benötigen wir neben der Distribution bzw. des Interpreters noch die Entwicklungsumgebung (IDE) um unseren Quellcode zu erstellen und bearbeiten zu können. In diesem Fall habe ich mich für PyCharm entschieden. Die Installation wird im folgenden Abschnitt dargestellt.

Installation der PyCharm IDE

Der Download von PyCharm ist über folgenden Link zu erreichen:

https://www.jetbrains.com/pycharm/download/#section=windows

Wir haben die Wahl zwischen der Professional- und der Community-Edition. Letztere ist kostenfrei und wird in diesem Beitrag verwendet. Nachdem ihr den Download abgeschlossen und die .exe Datei ausgeführt habt, startet der Installer.

Start des PyCharm Installers

Mit ‚Next‘ gelangt ihr zur Auswahl des Pfades. Auch hier empfehle ich grundsätzlich, den vorgeschlagenen Standardpfad zu übernehmen.

Im nächsten Dialog legt ihr optionale Dinge fest. Ihr könnt euch eine Verknüpfung auf dem Desktop erzeugen lassen, aber interessanter sind die anderen drei Optionen: Mit ‚Add Open Folder as Project‘ könnt ihr euer Kontextmenü erweitern lassen. Das hat den Vorteil, dass ihr im Explorer mit der rechten Maustaste den Projektordner direkt mit PyCharm öffnen lassen könnt. Zudem könnt ihr die .py-Dateierweiterung mit PyCharm verknüpfen und PyCharm zur Pfadvariable eures Betriebssystems hinzufügen. Beides ist empfehlenswert.

Optionen des PyCharm Installers

Ein Klick auf Next bringt euch zur Auswahl des Menüeintrages im Windows Start Menü, auch hier übernehme ich den vorgeschlagenen Standardname. Ein abschließender Klick auf ‚Install‘ beginnt die Installation. Diese sollte nach kurzer Zeit abgeschlossen sein und ihr habt erfolgreich die IDE installiert.

Widmen wir uns also nun unserem aller ersten Projekt! Doch bevor wir munter drauf los programmieren können, müssen wir eine virtuelle Umgebung für unser Projekt erzeugen. Wie das geht zeige ich jetzt:

Erzeugen einer virtuellen Python-Umgebung

In Teil 1 dieses Artikels wurde bereits beschrieben, warum wir virtuelle Umgebungen überhaupt benötigen und wofür sie gut sind. Sie können uns, kurz gesagt, eine Menge Arbeit ersparen, da sie Konflikte zwischen unterschiedlichen Projekten und deren Abhängigkeiten vermeiden.

Um eine solche virtuelle Umgebung für Python aufzusetzen gibt es mehrere Möglichkeiten. Da wir Anaconda verwenden nutzen wir hierzu den ‚conda‘ Befehl. Dieser wurde weiter oben in Schritt 1 der Anleitung zusammen mit der Distribution installiert. Dies können wir testen, indem wir auf der Windows-Konsole den Befehl conda -V eingeben. Dann erscheint die aktuelle conda Version.

Konsolentest Installation der Distribution

Nun können wir unsere erste virtuelle Umgebung für Python einrichten. Der Befehl ist folgendermaßen aufgebaut:

conda create -n UMGEBUNG python=X.Y

wobei UMGEBUNG durch einen auszuwählenden Namen für die neue Umgebung zu ersetzen ist. X.Y ist durch die gewünschte Python-Version zu ersetzen. Erzeugen wir jetzt eine neue Umgebung mit dem Namen meine_umgebung mit der Python-Version 3.9. Wir brauchen also den Befehl

conda create -n meine_umgebung python=3.9

Die erfolgreiche Einrichtung sieht dann folgendermaßen aus:

Erfolgreiche Einrichtung einer neuen, virtuellen Python Umgebung mit conda create.

Nun haben wir endlich unsere erste virtuelle Umgebung für Python eingerichtet! Bevor wir diese verwenden können, müssen wir sie aktivieren. Mit dem Aktivieren-Befehl können wir zukünftig flexibel zwischen verschiedenen virtuellen Umgebungen wechseln.
Der benötigte Befehl lautet

conda activate meine_umgebung

und dessen Ausführung beschert uns folgende Ausgabe:

Aktivierung unserer Umgebung

Um der Vollständigkeit willen möchte ich an dieser Stelle noch die beiden Möglichkeiten aufzeigen mit denen wir Umgebungen deaktivieren und entfernen können:

conda deactivate

und

conda remove -n UMGEBUNGSNAME --all

Diese beiden Befehle möchten wir an dieser Stelle aber eben nicht ausführen. Schließlich haben wir unsere neue virtuelle Umgebung gerade erst eingerichtet und aktiviert! Daher machen wir im nächsten Schritt damit weiter, mit unserer installierten IDE PyCharm und der neuen virtuellen Umgebung unser erstes Projekt zu starten.

Erstes Projekt unter PyCharm

Sehr gut! Wir haben jetzt die wichtigsten Werkzeuge installiert und eine eigene virtuelle Umgebung für unser Projekt erzeugt. Wir sind also bereit um mit Python loszulegen!

Starten wir also PyCharm. Beim ersten Start müsst ihr noch die Nutzungsbedingungen lesen und akzeptieren. Und dann geht es los! Ihr bekommt den Startbildschirm, von dem aus wir direkt mit dem Erzeugen eines neuen Projektes beginnen.

PyCharm Startdialog

Nach einem Klick auf ‚New Project‘ müsst ihr im folgenden Bildschirm zwei wichtige Dinge einstellen. Unter ‚Location‘ wird der Pfad benannt, unter dem das neue Projekt und alle zugehörigen Datein abgelegt werden.
Bei den beiden folgenden Options-Bullets wählt ihr die zweite aus (‚Previously configured interpreter‘). Dahinter wählt ihr den Pfad zu der im vorigen Schritt eingerichteten virtuellen Umgebung:

Konfiguration des Projekts
Die Abbildung zeigt wie die zuvor mit dem conda Befehl eingerichtete virtuelle Umgebung ‚meine_umgebung‘ ausgewählt wird.

An dieser Stelle zeigt sich auch bereits der erste Komfortgewinn einer IDE: denn mit dem ersten Bullet kann direkt aus der IDE heraus die virtuelle Umgebung erzeugt werden. Dies spart den „manuellen“ Schritt über die Konsole.

Mit Klick auf ‚create‘ wird das Projekt gemäß der Konfiguration erzeugt. Dies kann einen kurzen Moment dauern. Habt ihr bei der Konfiguration das Erzeugen der Main-Methode ausgewählt erhaltet ihr folgende Ansicht:

PyCharm mit Beispiel

Durchstarten mit „Hallo Welt!“

Doch was wäre eine erster Start ohne ein klassisches „Hallo Welt“-Programm?! Also passen wir unsere main.py-Datei noch ein wenig an, genauer mit:

if __name__ == '__main__':
    print("Hallo Welt!")
Code-Sprache: Python (python)

Anschließend noch speichern und schon können wir den neuen Code mit einem Klick oben rechts auf das grüne Dreieck ausführen.

PyCharm Hallo Welt

Für die Ausgabe öffnet PyCharm ein internes Konsolenfenster und gibt, wie erwartet, „Hallo Welt!“ aus! Der zusätzlich ausgegebene Exit Code ‚0‘ sagt uns zudem, dass das Programm ohne Fehler und Probleme durchgelaufen ist.

Nun sind alle wesentlichen Voraussetzungen für einen erfolgreichen Start mit Python in die Programmierung geschaffen: Wir haben eine vollständige Distribution samt Interpreter installiert, eine Entwicklungsumgebung aufgesetzt, und zu guter Letzt unser erstes „Hallo Welt“-Projekt im Rahmen einer virtuellen Umgebung aufgesetzt.

Jetzt steht dem Beginn größerer Projekte nichts mehr im Wege. Um diese aufzusetzen, müssen natürlich nicht jedes mal erneut alle oben beschriebenen Schritte durchlaufen werden. Sind Distribution und IDE erst installiert, könnt ihr ganz bequem eine neue virtuelle Umgebung für weitere Projekte aufsetzen und diese auch parallel in der IDE bearbeiten. Spätestens ab dann zahlen sich auch die Vorteile der virtuellen Umgebung aus.

Ich hoffe der Beitrag konnte euch den Start mit Python unter Windows etwas erleichtern und euch bei den ersten Schritten unterstützen.
Ich wünsche euch viel Spaß beim Einstieg in die Python-Programmierung!

übrigens…

… wer weiterführende Inhalte zum Thema Programmierung mit Python sucht, der wird natürlich zu Hauf im Internet fündig. Als eine sehr gelungene Seite für Einsteiger ohne Vorkenntnisse kann ich diese hier empfehlen:

https://cscircles.cemc.uwaterloo.ca/using-website-de/

Dort befindet sich ein kostenfreier Online-Kurs des „Center for Education in Mathematics and Computing“ der University of Waterloo. Der komplett auf deutsch gehaltene Kurs wird betrieben von den Bundesweiten Informatikwettbewerben (BWINF).

Für Fortgeschrittene kann ich zudem das Python 3 Handbuch von Johannes Ernesti und Peter Kaiser empfehlen. Die Online-Version des deutschsprachigen Buches befindet sich offen zugänglich hier:

https://openbook.rheinwerk-verlag.de/python/

Das Buch eignet sich hervorragend als Nachschlagewerk. Wer tiefer in Python einsteigen möchte, kommt im deutschsprachigen Bereich an diesem Buch kaum vorbei.

Hier geht es zurück zum ersten Teil meines Artikels: Teil 1
Und hier geht es zurück zur Startseite meines Blog: blog-mensch.de

Vielen Dank für’s Lesen! Ich freue mich zudem immer über Kommentare.

Kategorien
IT Programmierung

Start mit Python – Teil 1: Grundlagen, was brauchen wir?

In diesem Beitrag möchte ich eine Anleitung für den Start mit Python unter Windows liefern. Dazu beschreibe ich alles was nötig ist, um die Voraussetzungen für das erste eigene Python-Projekt zu schaffen.
Dabei ist es mir wichtig, neben einer konkreten Anleitung, auch das Verständnis wichtiger, zugrundeliegender Konzepte zu vermitteln. Daher gliedere ich meinen Artikel in zwei Teile: Teil 1 zeigt Grundlagen zum Start mit Python auf. Dabei beschreibe ich, was man ganz generell benötigt und erkläre auch, wieso wir das alles brauchen. In Teil 2 beschreibe ich anschließend anhand einer praktischen Schritt für Schritt Anleitung die konkrete Umsetzung. Dieser zweite Teil reicht dann vom Download und der Installation, über die Konfiguration bis hin zum allerersten eigenen Projekt.

Hier die Gliederung des ersten Teils:

In „Start mit Python – Teil 2“ (direkt dorthin) befasse ich mich dann mit folgenden Punkten:

  • Installation der Anaconda Distribution unter Windows
  • Test der Anaconda Installation
  • Installation der PyCharm IDE
  • Erzeugen einer virtuellen Python-Umgebung
  • Erstes Projekt unter PyCharm
  • Durchstarten mit „Hallo Welt!“

Beginnen wir mit diesem ersten, einführenden Teil. Hier konzentriere ich mich auf wichtige grundlegende Erläuterungen. Diese sind notwendig, um zu verstehen, warum einige der im zweiten Teil folgenden, konkreten Schritte überhaupt notwendig sind. Denn startet man als Anfänger ohne Vorerfahrung in die Programmierung, so kann es möglicherweise frustrierend sein, so viele Installationen und Konfigurationen vorzunehmen, bevor man seine erste Code-Zeile schreibt. Insofern kann es nicht schaden, wenn man versteht was dahinter steckt.

Warum Python?

Gründe für einen Python Einstieg gibt es viele. Ob als Teil der Ausbildung bzw. des Studiums, oder aus beruflichen Gründen. Manch einer nutzt Python auch im privaten Bereich, da es sehr flexibel und einfach zu handhaben ist. In meinem Fall hatte ich einfach Lust mir etwas Neues anzuschauen, also musste eine neue Programmiersprache her. Meine bisherigen Erfahrungen sammelte ich alle mit Sprachen wie Java oder C++. Doch mit Python hatte ich bislang nie zu tun. Über die Programmierung mit Python habe ich allerdings sehr häufig viel Positives gehört. So gilt diese Sprache beispielsweise als sehr leicht erlernbar und deren Programmcode als gut lesbar. Darüber hinaus gibt es noch viele weitere Vorteile, zum Beispiel die intuitive Nutzbarkeit, die praktikable Umsetzung von Deklarationen, etc.
Aus all diesen Gründen dachte ich mir, dass es nun an der Zeit ist Python näher zu betrachten! Diesen neuen Start in die Programmierung und meinen Beginn mit Python möchte ich hier mit euch teilen.

Was wir zum Start mit Python brauchen

Bei Python handelt es sich um eine Hochsprache, oder auch höhere Programmiersprache genannt. Eine solche Sprache eignet sich besonders gut dazu, von Menschen sowohl verfasst, als auch gelesen (und verstanden) zu werden. Wir können diese Sprache gut mit einem Texteditor verfassen, denn sie ist für die Anwendung durch Menschen gestaltet. Somit steht unser erstes Werkzeug fest, wir benötigen einen Editor.

Von einer Maschinensprache, die letztlich durch Nullen und Einsen dargestellt, und von einem Computer ausgeführt wird, ist Python jedoch noch sehr weit entfernt. Daher muss unser Quellcode, wie alle anderen Hochsprachen auch, zuerst in Maschinensprache übersetzt werden. Damit sind wir auch schon bei unserem zweiten Werkzeug angelangt. Wir benötigen einen Interpreter. Denn dieser erledigt für uns genau die benötigte Übersetzung unseres selbst verfassten Quellcodes in Maschinensprache.

Zusammenhang Editor, Quellcode und Interpreter

Ich konzentriere mich in diesem Beitrag auf eben diesen Standardfall, nämlich dass Python interpretiert wird. Es gibt auch die Möglichkeit, Python mit einem Compiler zu übersetzen, ähnlich wie es beispielsweise bei Sprachen wie C, C++, .NET, etc., der Fall ist. Der Unterschied ist, vereinfachend gesagt der, dass ein Interpreter zur Laufzeit des Programms die Übersetzung durchführt, während ein Compiler dies bereits vor der Ausführung erledigt. Doch das soll ein anderes Thema sein, dem ich mich möglicherweise in einem gesonderten Beitrag widme.

Die integrierte Entwicklungsumgebung

Wir wissen nun also, dass wir mindestens zwei Werkzeuge für unseren Start mit Python benötigen: Einen Editor, um den Quellcode zu verfassen, und einen Interpreter, der für uns diesen Code dann schließlich in Maschinensprache übersetzt und zur Ausführung bringt.

Natürlich könnte man den Quellcode nun theoretisch mit dem standardmäßig vorhandenen Editor unter Windows oder Ähnlichem verfassen. Etwas mehr Komfort soll es dann aber doch sein. Ginge es bei diesem Komfort nur um Syntax-Highlighting, so kämen auch Tools wie Notepad++ in Frage. Doch ich habe mich dazu entschieden, eine vollwertige IDE (Integrated Development Environment, zu deutsch: Integrierte Entwicklungsumgebung) zu nutzen. Eine solche IDE beinhaltet immer den von uns benötigten Editor. Allerdings lässt sie uns darüber hinaus später in den Genuss von weiteren Komfortfunktionen wie Debugging, Versionierung, die integrierte Einbindung eines Repository, etc., kommen. Nach einer kurzen Recherche kamen für mich zwei verschiedene IDE in Frage: Visual Studio Code von der Firma Microsoft oder PyCharm des Unternehmens JetBrains. Natürlich gibt es da noch einige Andere, aber das soll ein anderes Thema sein… Entschieden habe ich mich letztlich für PyCharm, die ersten Schritte dazu folgen im zweiten Teil meines Artikels.

Die Python Distribution

Wie eingangs erwähnt, benötigen wir neben dem Editor bzw. der IDE auch noch einen Interpreter. Hier setze ich ebenso auf Komfort und nehme gleich eine vollständige Python-Distribution. Entschieden habe ich mich für die Distribution Anaconda in der ‚Individual Edition‘. Diese ist für den privaten Gebrauch kostenlos. Die Distribution bringt neben des reinen Interpreters noch weitere Vorteile mit sich. Diese sind zum Beispiel die eigene Paketverwaltung oder der schlanke Kommandozeileninterpreter iPython. (Darüber hinaus noch einiges mehr.)

Auch hier beschreibe ich den Download und die Installation in Teil 2 des Artikels. Doch bevor wir damit loslegen, und die konkreten Installationen und Konfigurationen durchführen, folgen erst ein paar Worte zu wichtigen Konzepten. Dies erleichtert uns das Verständnis bezüglich notwendiger Konfigurationen. Insbesondere das Konzept virtueller Entwicklungsumgebungen, welche auf Basis der verwendeten Distribution einzurichten sind, erschließt sich nicht zwingend auf den ersten Blick. Um dies besser zu verstehen, müssen wir im Folgenden noch ganz kurz auf grundlegende Begrifflichkeiten und Zusammenhänge eingehen.

Programmiersprache und Pakete

Eine Programmiersprache ist eine formale Sprache, die es uns erlaubt, Algorithmen und Datenstrukturen zu beschreiben. Das bedeutet, dass wir mit einzelnen, fest definierten Schritten, die Lösung von Problemen beschreiben. Wie bereits in Abschnitt 2 dargestellt, erfolgt diese Beschreibung in der Regel in einer Hochsprache, in unserem Fall Python.

Die Kunst des Programmierens besteht nun darin, das zu lösende Problem mit der gegebenen Syntax und Semantik der Programmiersprache zu beschreiben und zu lösen. Dabei zerlegt man das Gesamtproblem typischerweise in viele kleine Teilprobleme.

Ein Paket versteht sich in diesem Zusammenhang nun als Bündelung zusammenhängender Beschreibungen, die in einer Programmiersprache verfasst sind. Pakete können verwendet werden, um sinnvoll abgrenzbare Teilprobleme zu kapseln. Somit wird es möglich, dass man immer wiederkehrende Teilprobleme nicht auch immer wieder erneut beschreiben muss. Denn dann reicht es aus, bereits bestehende Pakete wiederzuverwenden.

Betrachten wir hierzu ein Beispiel. Vorhandene, bereits gelöste Teilprobleme sind etwa Pakete zur Erstellung einer grafischen Benutzeroberfläche (GUI) oder Pakete mit Implementierungen von Datenbankanbindungen. Angenommen wir haben einen Entwickler, dessen Aufgabe es ist, eine Buchhaltungssoftware zu programmieren. Dieser Entwickler kann sich nun ganz auf das implementieren der Buchungslogik konzentrieren. Bestimmte Teilprobleme dabei, nämlich das Anzeigen der Buchungen oder das Speichern in einer Datenbank, muss er nicht mehr selbst lösen. Dafür kann er vorhandene Pakete wiederverwenden, die ihm von anderen Entwicklern bereit gestellt werden.

Beispiel einer Wiederverwendung von Paketen
Beispiel einer Wiederverwendung von Paketen

Im konkreten Falle einer solchen Wiederverwendung durch eine Anwendung, spricht man auch von einer Abhängigkeit der Anwendung zu diesem Paket. Darüber hinaus können auch Pakete untereinander Abhängigkeiten haben.

Was daraus jedoch für Probleme entstehen können, und wie wir sie lösen können, betrachten wir im folgenden Abschnitt.

Virtuelle Umgebungen

Wir wissen jetzt, dass uns die Wiederverwendung von Paketen die Programmierung erleichtern können. Doch neben den beschriebenen Vorteilen bringt dies auch Nachteile mit sich. Denn in der Praxis ist es so, dass sich sowohl Pakete, als auch die Programmiersprache selbst, dynamisch weiterentwickeln bzw. verändern. Daher kommt es häufig dazu, dass unterschiedliche Anwendungen teilweise unterschiedliche Versionen von Python selbst oder einzelner Pakete benötigen. Dies führt schnell zu einem Geflecht von Abhängigkeiten. Dieses kann schnell sehr komplexe Ausmaße annehmen, und sich darüber hinaus noch von Anwendung zu Anwendung unterscheiden. Diese anwendungsspezifischen Abhängigkeiten können dann im Widerspruch oder Konflikt zueinander stehen.

Um genau diese Konflikte und Widersprüche zu vermeiden, verwenden wir virtuelle Umgebungen. Denn diese kapseln, übergeordnet für jede Anwendung separat, die jeweilige Version der Programmiersprache, der Pakete und die Pakete selbst. Das macht das Wechseln zwischen der Entwicklung unterschiedlicher Anwendungen sehr einfach und flexibel. Zudem schließt es die vorgenannten Konflikte und Widersprüche prinzipiell aus.

Greifen wir unser obiges Beispiel des Entwicklers einer Buchhaltungssoftware nochmal auf. Nehmen wir an, dieser Entwickler hat noch ein zweites Projekt, welches ebenso eine Datenbankanbindung und eine grafische Benutzeroberfläche benötigt. Hier kann er also ebenfalls die bekannten Pakete wiederverwenden. Aus bestimmten Gründen benötigt dieses zweite Projekt aber andere Versionen dieser Pakete, welche nicht mit denen aus dem Projekt der Buchhaltungssoftware kompatibel sind. Hätte der Entwickler nun keine Möglichkeit der Trennung beider Projekte, so entstünde schnell ein Konflikt aufgrund von Inkompatibilitäten der unterschiedlichen Paketversionen. Doch zum Glück liegen beide Projekte in unterschiedlichen, virtuellen Umgebungen. So bekommt jedes Projekt genau die Version des Paketes die es benötigt.

Beispiel virtueller Trennung
Aufgrund der unterschiedlichen virtuellen Umgebung können die Projekte unterschiedliche Versionen der gleichen Pakete konfliktfrei nutzen.

Wie geht es weiter?

Wir wissen nun was wir grundsätzlich an Werkzeugen für einen Start mit Python mindestens benötigen, nämlich

  • eine IDE mit Editor zum Bearbeiten unseres Quellcodes, und
  • eine Python-Distribution mit Interpreter.

Zudem wissen wir jetzt, Begriffe wie Programmiersprache und Pakete, besser einzuordnen, und warum uns virtuelle Umgebungen das Leben leichter machen.
Daher können wir uns nun endlich an die konkrete Umsetzung und den praktischen Anteil begeben. Im zweiten Teil des Beitrages zeige ich die notwendigen Schritte für das Einrichten solcher virtuellen Umgebungen, das Installieren der Distribution und der IDE, sowie das Aufsetzen des ersten Projektes. Am Ende werden wir eine voll einsatzfähige Entwicklungsumgebung haben, und unser erstes „Hallo Welt“-Projekt erfolgreich gestartet haben. Somit sollte der Start mit Python unter Windows problemlos gelingen. Danke für die Aufmerksamkeit und viel Spaß beim Weiterlesen!
Hier geht es direkt weiter zu Teil 2:
Anleitung zum Start mit Python unter Windows – Teil 2