[ Home ] [ Seitenende ] [ Start ] [ Teil 1 ] [ Teil 2 ] [ Teil 3 ]

 

 

 

Künstliche Intelligenz (KI) – Grundlagen Python

 

 

2  Programmiergrundlagen in Python

 

Python gilt als eine "einfache" Programmiersprache, die durch die "einfache" Syntax "einfach" zu lernen ist. Wie einfach oder schwer die typischen Programmiergrundlagen in Python sind, wirst du hier sehen.

Falls du mehr darüber wissen möchtest, ist sowohl die Originalseite, als auch Wikipedia eine gute Quelle. Wir verwenden Python 3. Solltest du über Code in einer Python 2 Version stolpern, wirst du merken, dass es einige Unterschiede gibt. Solltest du dir jedoch Python neu installieren müssen, ist Python 3 die richtige Wahl. Das Problem ist vergleichbar mit den verschiedenen Windows-Versionen - es gibt noch einige XP-Nutzer, jedoch ist der State-of-the-Art eine neuere Version.

In diesem Tutorial wird ein wenig mathematisches Verständnis vorausgesetzt. Solltest du direkt am Anfang bereits Schwierigkeiten mit den Aufgaben haben, schau doch einmal in diese Tutorials, die teilweise noch grundlegender sind.

 

2.1  Variablentypen

 

Wie die meisten Programmiersprachen unterscheidet Python zwischen verschiedenen Variablentypen. Nachfolgend siehst du einen Teil dieser, und zwar die am häufigsten genutzten Typen:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_01a.py)

 

Im Gegensatz zu anderen, meist älteren Programmiersprachen, gibt es in Python wider Erwarten kein sogenanntes engl. „char“ (= „character“), d.h. einzelnes Zeichen. Dabei kann es sich bei einem einzelnen Zeichen um ein Sonderzeichen, eine Ziffer, einen Buchstaben oder auch um einen engl. „space“ (= Leerzeichen „ “) oder engl. „blank“ (= Leerstelle) handeln.®

 

¬Das „Gemeine“ an Leerzeichen ist, dass man sie nicht immer sofort sieht, d.h. auf einen Blick erkennt. Während man ein Leerzeichen als Worttrennzeichen zwischen zwei® ¬Worten sofort sieht, ist das vorangestellte oder nachgeordnete Leerzeichen oftmals erst dann sichtbar, wenn man die Zeilenschaltung, engl. line feed“ (LF = hexadezimal 0A16), und die Absatzschaltung (= Wagenrücklauf der Schreibmaschine), engl. carriage return“ (CR = hexadezimal 0D16), aus dem Fließtext entfernt (siehe rot markierte Pfeile). Beim LF und dem CR handelt es sich innerhalb einer Textverarbeitung oder einer Textdatei um sogenannte Steuerzeichen, die, um den Lesefluss nicht zu stören, im Text selbst unsichtbar sind und demzufolge unterdrückt werden:

 

 

(Vergrößern: auf das Bild klicken! | Textdatei teil_02_prog_01b.txt)

 

Wenn man sich z.B. in einem formatierten Textdokument der Textverarbeitung LibreOffice Writer von LibreOffice alle Leerzeichen anzeigen lassen will, dann muss man im Menü in der Textverarbeitung das Symbol „Kapitälchen“  aktivieren/anklicken, sodass dieses hellblau markiert erscheint: .

 

Obwohl sich in Python keine einzelnen Zeichen vom Typ „char“ deklarieren oder initialisieren lassen, sondern immer nur ganze Zeichenketten vom Typ str(ing)“

 

·        Statement <s : str>

 

·        Statement <s : str = “Hello world“>,

 

lassen sich dennoch einzelne Zeichen einem anfangs noch leeren Zeichenstring <s_string> wie folgt hinzufügen:

 

·        Statement <s_string = s_string + s[n]> (siehe im roten Kasten)

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_01b.py)

 

Damit sich einzelne Zeichen einer Zeichenkette einzeln darstellen oder bearbeiten lassen, braucht es u.a. eine sogenannte <fornext>-Schleife, die bei älteren Programmiersprachen aus insgesamt drei Parametern besteht:

 

1.     Startwert der Zählvariablen wie z.B. <n = 0>,

2.     Endwert mit der Bedingung, so lange n < 10 Endwert ist und

3.     Schrittweite n mit <n = n + 1> oder kürzer <n += 1>

 

Beispiel

 

·        Statement <for (n = 0, n < 10, n += 1):>

 

Im modernen Python gibt es von der alten <fornext>-Schleife nur noch die Abfrage, ob sich die Zählvariable n noch im Bereich , engl. range, von [0, …, 9] befindet oder nicht:

 

·        Statement <for n in range(10):>

 

Eine neuere Art der <fornext>-Schleife bezieht sich die Funktion eines Wörterbuches, engl. dictionary, das sich aus Schlüsselwörtern und deren „Übersetzung“  - im Sinne eines Variableninhalts -  bezieht. Das Schlüsselwort selbst ist aber KEINE Variable (siehe dunkelgrüne Kästen)!

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_01b.py)

 

 

(Vergrößern: auf das Bild klicken! | Bild teil_02_prog_01e.jpg)

 

 

2.2  Programmiergrundlagen in Python

 

In diesem Abschnitt werden wir typische Programmiergrundlagen in Python kennen lernen. Was du schon gesehen hast, ist, dass man eine Variable in Python ganz einfach zu definieren kann. Jetzt geht es darum, klassische Codestrukturen in Python zu sehen.

 

2.2.1  Logische Operatoren

Die meisten nachfolgenden Strukturen nutzen logische Bedingungen. Diese sind typischerweise:

  • a == b (gleich)
  • a != b (ungleich)
  • a < b (kleiner)
  • a <= b (kleiner gleich)
  • a > b (größer)
  • a >= b (größer gleich)
  • a & b (und)
  • a | b (oder)

Bei Nutzung von „und“- oder oder“-Bedingungen werden häufig Klammern benötigt, um die Verknüpfungen korrekt zu gruppieren, zum Beispiel: ( a < 5 ) & ( b = 3 ).

 

2.2.2  If-elif-else

Eine If-elif-else“-Struktur ist eine einfache Möglichkeit, Code aufgrund von logischen Bedingungen auszuführen. Im Alltag eines Data Scientist kann das bedeuten, dass man zum Beispiel verschiedene Modelle hat, die man jedoch nur bei ausreichender Datenlage trainiert.

Ein sehr generelles Beispiel ist:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_02.py)

 

2.2.3  While-Loop

Der Code innerhalb einer While“-Schleife wird so lange durchgeführt, bis die logische Bedingung am Schleifenbeginn nicht mehr erfüllt ist. Diese Funktion kann man nutzen, wenn man zum Beispiel einen Optimierungsalgorithmus benutzt. Der Gedanke hierbei ist, so lange zu optimieren, bis sich der Funktionswert nur noch wenig ändert.

Weiterhin kann der While“-Befehl mit den Befehlen continue, break und else verknüpft werden. Bitte führe die nachfolgenden zwei Zellen aus und klicke links neben die ausgeführte Zelle, um eine große Ansicht zu bekommen.

Nutze dann den interaktiven Code, um die nachfolgenden Fragen für dich zu beantworten:

  • Welche Funktion hat das <continue>-Statement?

    <continue> dient dazu, direkt wieder an den Beginn der Schleife zu springen. Es findet keine Ausführung von Code nach dem Statement statt.


  • Welche Funktion erfüllt das "Break"-Statement und was ist der Unterschied zu einem "Else"?

    <break> unterbricht die Ausführung der Schleife, sodass die Schleife abgebrochen und kein weiterer Sourcecode mehr innerhalb der Schleife ausgeführt wird.

    <else> wird aufgerufen, wenn die Schleife erfolgreich durchgelaufen wurde und nicht durch <break> unterbrochen wurde.

 

Die <while>-Schleife im nachfolgenden Quellkode des Programms teil_02_prog_03a.py ist schon etwas gewöhnungsbedürftig, da ungewohnt und nicht alltäglich. Nicht alltäglich ist die <else>-Anweisung im pinkfarbenen Kasten, die sich nämlich auf die <if>-Anweisung im Kopf der <while>-Schleife bezieht:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_03a.py)

 

Wie man anhand des nachfolgenden Quellkodes sieht, gibt es innerhalb der <while>-Schleife in den Zeilen 10 bis 22 im Wesentlichen nachfolgende Statements (siehe roter Kasten):

 

1.     die Erhöhung des Schleifenzählers i um jeweils +1 in Zeile 10,

2.     die <if>-Abfrage mit <if i == 3:> in Zeile 11,

3.     die <elif>-Abfrage mit <elif i > 5:> in Zeile 15,

4.     der <print>-Befehl mit <print(i)> in Zeile 21,
um den aktuellen
Wert des Schleifenzählers i anzuzeigen.

 

Wie man ferner sieht, bezieht sich die <else>-Abfrage in Zeile 23 auf die <if>-Abfrage im Kopf der <while>-Schleife:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_03b.py)

 

Übrigens: Bei der <while>-Schleife oben im Quellkode des Programms handelt es sich um eine sogenannte kopfgesteuerte <while>-Schleife bei der die Abfragebedingung i < 6 gleich zu Beginn der <while>-Schleife abgefragt wird.

 

Demzufolge wird der nachfolgende Programmkode stets nur dann ausgeführt, wenn die Schleifenbedingung i < 6 bei jedem Schleifendurchlauf erfüllt ist (siehe roter Kasten)!

 

 

Die fußgesteuerte <while>-Schleife

 

In Python gibt es im eigentlichen Sinne keine fußgesteuerten <while>-Schleifen, wie sie in anderen Programmiersprachen bekannt sind.

 

Fußgesteuerte Schleifen, auch <do-while>-Schleifen genannt, zeichnen sich dadurch aus, dass zuerst der Codeblock ausgeführt wird, egal wie die Bedingung lautet. Erst danach wird die Bedingung überprüft. Ist die Bedingung wahr, wird die Schleife erneut durchlaufen. Ist die Bedingung falsch, wird die Schleife beendet.

 

Python bietet diese Art von Schleife standardmäßig nicht. Es gibt jedoch zwei Möglichkeiten, eine ähnliche Funktionalität zu erreichen:

 

1.     <while>-Schleife mit <True>-Bedingung und <break>:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_03c.py)

 

2.     <for>-Schleife mit einem Bereich von 1 bis 9:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_03d.py)

 

Wichtig in diesem Zusammenhang ist noch, dass es sich bei dem Unterstrich _ im

 

·        Statement <for _ in range(1, 10):>

 

um eine Variable handelt; so wie z.B. die Zählvariable <loop>.

 

 

<for>-Schleife mit einem Bereich von 1 bis :

 

Interessant wird es bei der <for>-Schleife noch einmal, wenn es darum geht, dass man mit dieser bis ¥ zählt. Dazu ist es dann allerdings erforderlich, dass man die engl. „library“, d.h. Bibliothek sys gleich zu Beginn des Programms importiert:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_03e.py)

 

2.2.4  For-Loop

 

Eine <for>-Schleife bedeutet eine Iteration über eine definierte Sequenz. Das bedeutet, das man sich schrittweise durch fortwährende Wiederholung dem Ergebnis annähert. Dabei wird das Ergebnis umso genauer, je mehr Iterationen man durchführt.

 

Als Sequenz bezeichnet man dabei eine Abfolge von auf- oder absteigenden Zahlen wie z.B. 1, 2, 4, 8, … = 20, 21, 22, 23 ," binäre Zahlenfolge. Diesbezüglich kann eine Sequenz aber auch aus einer gemischten Folge von Zahlen, Ziffern, Zeichenketten, Ausdrücken usw. bestehen.

 

Beispiel

 

Wenn man sich bei der Sparkasse, einer Bank oder Kreditinstitut ein Darlehen/Kredit aufnimmt, dann muss dabei der gesetzliche (Jahres-) Effektivzins angegeben werden, sodass sich verschiedene Kredite mit teils unterschiedlichen Konditionen wie z.B. Laufzeit, Verzugszinsen bei ausgesetzter Tilgung oder vorzeitiger Rückzahlung, Kreditbetrag, Provision usw. miteinander vergleichen lassen. Dabei lässt sich der effektive (Jahres-) Zinssatz nur iterativ, d.h. durch Annäherung ermitteln bzw. berechnen.

 

Wie man beim nachfolgenden Programm teil_02_prog_04a.py sieht, lässt sich die Liste <sequenz> in der <for>-Schleife der Reihe nach „abarbeiten“ und mittels <print>-Statement anzeigen. Das wiederum setzt voraus, dass die Liste <sequenz> indexiert, d.h. intern mit einem Index versehen ist, der bei Null beginnt:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_04a.py)

 

Selbstverständlich lässt sich der Content (= Inhalt) der Liste <sequenz> auch direkt in den Kopf der <for>-Schleife einbauen. Dabei gilt es aber zu beachten, dass sich die Liste nicht mehr als Variable <sequenz> benutzen lässt! Und zwar mit der Folge, dass sich die Inhalte der Sequenz nachträglich nicht mehr verändern lassen:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_04b.py)

 

Mit dem Quellkode des nachfolgenden Programms teil_02_prog_04c.py lässt sich „beweisen“, dass die einzelnen Elemente bzw. Ausdrücke in der Liste <sequenz> tatsächlich klammheimlich, sozusagen im Hintergrund still und leise indexiert wurden (siehe auch Statement <sequenz[loop]>):

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_04c.py)

 

Mit dem Quellkode des nächsten Programms teil_02_prog_04d.py lässt sich ebenfalls „beweisen“, dass die einzelnen Elemente bzw. Ausdrücke in der Liste <sequenz> tatsächlich still und leise indexiert wurden.

 

Mit der Schleifenzähler-Variablen <loop> bzw. der Index(!)-Variablen <loop> lassen sich nämlich nicht nur einzelne Elemente der Liste <sequenz> ansprechen, sondern auch mit dem

 

·        Statement <if loop == 2:>

 

selektieren (siehe rote Kästen):

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_04d.py)

 

Der Quellkode des nächsten Programms teil_02_prog_04e.py zeigt, dass sich die <for>-Schleife mit dem <range>-Befehl auch mit bis zu drei Parametern und zwar

 

1.)         startwert = 0,

2.)         endwert = 4 und

3.)         increment = +1

 

konfigurieren lässt (siehe roter Kasten)!

 

Außerdem lassen sich wegen der Indexierung der einzelnen Elemente der Liste <sequenz> auch selbige gezielt selektieren und mittels des

 

·        Statements <if sequenz[loop] == 'leer':>

 

auswerten bzw. darauf reagieren (siehe blaue Kästen):

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_04e.py)

 

Man kann über Listen iterieren, zum Beispiel eine Liste mit ML-Modellen (ML = Maschine Learning), aber auch über Listen von Zahlen. Hierfür wird häufig der range(start, stopp, increment)-Befehl verwendet. Beachte, dass Python bei 0 anfängt zu zählen und ein Element vor dem Ende aufhört. Eine Schleife über range(4) geht daher über 0, 1, 2, 3:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_04f.py)

 

Wenn man sich den Screenshot mit der Anzeige im Konsolefenster so anschaut, dann scheint die Sequenz mit den Ausgabewerten [2, 6, 10, 14, 18, 22, 26] auf den ersten Blick etwas kryptisch aus. Der Grund dafür sind dabei auch die drei Parameter im

 

·        Statement <for x in range(2, 30, 4):>,

 

die einem noch immer ungewohnt erscheinen. Wenn man aber einen Blick zurück wirft auf das vorherige Programm teil_02_prog_04e.py, dann sieht man sofort, was es mit den drei Parametern im <range(2, 30, 4)> auf sich hat:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_04g.py)

 

2.2.4.1  Aufgabe: <break>, <continue> und <else> in der <for>-Loop

 

Auch bei der <for>-Schleife gibt es die Befehle <break>, <continue> und <else>. Bitte versuche,

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_03b.py)

 

wie oben in der <while>-Schleife, diese Befehle in die <for>-Schleife einzubauen. Tipp: Du brauchst nur eine Zeile im Code von oben zu ändern:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_04h.py)

 

2.2.5  Enumerator

 

Der Enumerator (= Aufzählungstyp) erleichtert eine <for>-Loop, wenn sowohl der Index als auch der Sequenzeintrag selbst benötigt werden:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_05a.py)

 

Wie man im obenstehenden Quellkode sieht, benennt die Liste <list2> der Reihe nach diejenigen Sportwagenhersteller, die verwendet werden, während die Liste <list1> die zu den Automarken gehörigen Motorgeräusche zuordnet. Dabei gilt es zu beachten, dass prinzipiell beide Listen gleich lang sein und demzufolge gleich viele Elemente enthalten müssen, damit sich jedem Sportwagen das entsprechende Motorgeräusch zuordnen lässt!

 

Beim Ausführen des Quellkodes verhält es sich dann so, dass das Motorgeräusch umso länger andauert, je weiter hinten sich der Sportwagenhersteller in der Liste <list2> befindet. Um darüber hinaus das Dröhnen des Motors bzw. der Auspuffanlage noch zu verstärken, verdoppelt sich die Laufzeit des Motorgeräusches von Fahrzeug zu Fahrzeug, sodass der letzte Sportwagen in der Liste <list2> am längsten aufheult.

 

Weil sich die unterschiedlichen Motorengeräusche stets einem bestimmten Sportwagen und dessen Hersteller zuordnen lassen, wurden die beiden Listen <list2> und <list1> im Programm teil_02_prog_05b.py gegeneinander vertauscht:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_05b.py)

 

Selbstverständlich lässt sich die <for>-Schleife mit dem <enumerate>-Statement auch mit der <for>-Schleife mit Elementzuweisung wie folgt programmieren:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_05c.py)

 

2.2.6  List comprehensions

List comprehensions sind eine besondere Funktion von Python. Sie ermöglichen eine <for>-Schleife in Kombination mit einem weiteren Befehl, zum Beispiel einer <if>-Abfrage oder einer einfachen mathematischen Operation und erhöhen die Lesbarkeit. Zunächst erscheint das Konzept schwierig, aber sie sind eine einfache und effektive Möglichkeit zur Codeoptimierung:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_06a.py)

 

Der bisher fehlende <print>-Befehl für die Ergebnisanzeige lässt sich natürlich problemlos in das nachfolgende Programm teil_02_prog_06b.py einfügen.

 

Wenn man sich bei dieser Gelegenheit auch noch das Rechenergebnis mittels einer entsprechenden <for>-Schleife zeilenweise anzeigen lässt, dann wird ein Schuh daraus:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_06b.py)

 

Bei der Programmierung in Python lassen sich Potenzen wie z.B. x^2 nur mit der

 

·        Syntax <x**2>

 

richtig berechnen!

 

 

In diesem Zusammenhang verhält es sich außerdem so, dass sich die Basis x von x2 nicht aus der engl. comprehension, d.h. aus dem „Verständnis“ ablösen und einzeln berechnen oder darstellen lässt:

 

·        Statement <squares = [x**2 for x in range(11)]>

 

Die Berechnungsergebnisse von y = f(x) = x^2 lassen sich mittels einer <for>-Schleife auch einzeln, d.h. zeilenweise im Konsolefenster einzeigen, indem man die Liste <squares> mit dem comprehension und deren

Elemente sequentiell, d.h. der Reihe nach ausliest:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_06c.py

 

Nachfolgend noch der „Beweis“, dass es sich bei der Variablen <squares> tatsächlich um eine vom Typ <list> handelt (siehe rote Kästen):

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_06d.py

 

2.2.7  Funktionen

Funktionen werden benötigt, um immer wieder aufrufbare Mechanismen zu definieren; genau wie die Funktionsvorschrift einer mathematischen Funktion. Notwendig sind ein oder mehrere <input>-Variablen, sowie ein <return>-Statement, dass das Ergebnis der Operation wieder zurück gibt:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_07a.py

 

Wir entwickeln das bestehende Programm weiter, indem wir dieses anwenderfreundlicher und universeller gestalten:

 

 

(Vergrößern: auf das Bild klicken! | Programm teil_02_prog_07b.py

 

 

 

[ Home ] [ Seitenanfang ] [ Start ] [ Teil 1 ] [ Teil 2 ] [ Teil 3 ]