11. Unterrichtsblock

Python Arrays

Hinweis: Heute lernen wir, wie wir LISTEN als ARRAYS verwenden. Um mit Arrays in Python arbeiten zu können, muss man eine Bibliothek importieren, z. B. die NumPy-Bibliothek .

Arrays werden verwendet, um mehrere Werte in einer einzigen Variablen zu speichern:

Erstellen eines Arrays mit Autonamen:

# Array mit Autonamen
autos = ["Ford", "Volvo", "BMW"]

# Leeres Array zur späteren Befüllung mit Werten
autos = []

Was ist ein Array?

Ein Array ist eine spezielle Variable, die mehr als einen Wert gleichzeitig enthalten kann.

Wenn Sie über eine Liste mit Elementen verfügen (z. B. eine Liste mit Autonamen), könnte das Speichern der Autos in einzelnen Variablen wie folgt aussehen:

auto1 = "Ford"
auto2 = "Volvo"
auto3 = "BMW"

Was aber, wenn man die Autos durchgehen und ein bestimmtes finden möchte? Und was wäre, wenn man nicht 3 Autos, sondern 300 hätte?

Die Lösung ist ein Array!

Ein Array kann viele Werte unter einem einzigen Namen enthalten, und man kann auf die Werte zugreifen, indem man auf eine Indexnummer verweist.

Zugriff auf die Elemente eines Arrays

x = autos[0]

Ändern des Werts des ersten Array-Elements:

autos[0] = "Toyota"

Die Länge eines Arrays

Man kann die len()Methode verwenden, um die Länge eines Arrays (die Anzahl der Elemente in einem Array) auszugeben. Gibt die Anzahl der Elemente im cars Array zurück:

x = len(autos)

Hinweis: Die Länge eines Arrays ist immer um eins größer als der höchste Array-Index.

Iterieren von Array-Elementen

Mit einer for in-Schleife können alle Elemente eines Arrays durchlaufen werden.

Ausgabe jedes Elements im autos-Array:

# Einfacher Ausgabebefehl
for x in autos:
  print(x)

# Aufruf einer Funktion für jeden Wert innerhalb eines Arrays
for x in autos:
  inkrementieren()

Array-Elemente hinzufügen

Mit der Methode append()kann einem Array ein Element hinzugefügt werden.

autos.append("Honda")

Array-Elemente entfernen

Mit der Methode pop() kann ein Element aus dem Array entfernt werden.

autos.pop(1)

Man kann auch die Methode remove() verwenden, um ein Element aus dem Array zu entfernen.

autos.remove("Volvo")

Hinweis: Die Methode remove()entfernt nur das erste Vorkommen des angegebenen Werts.

Array-Methoden

Python verfügt über eine Reihe integrierter Methoden, die für Listen/Arrays verwendet werden können.

MethodeBeschreibung
append()Fügt am Ende der Liste ein Element hinzu
clear()Entfernt alle Elemente aus der Liste
copy()Gibt eine Kopie der Liste zurück
count()Gibt die Anzahl der Elemente mit dem angegebenen Wert zurück
extend()Fügen Sie die Elemente einer Liste (oder einer Iterable) zum Ende der aktuellen Liste hinzu
index()Gibt den Index des ersten Elements mit dem angegebenen Wert zurück
insert()Fügt ein Element an der angegebenen Position hinzu
pop()Entfernt das Element an der angegebenen Position
remove()Entfernt den ersten Element mit dem angegebenen Wert
reverse()Kehrt die Reihenfolge der Liste um
sort()Sortiert die Liste

Hinweis: Python bietet keine integrierte Unterstützung für Arrays, aber stattdessen können Python-Listen verwendet werden.

Aufgabe

Aufgabe 1: Listen und Append

Aufgabe: Erstelle ein Programm, das den Benutzer auffordert, drei Namen einzugeben. Speichere diese Namen in einer Liste und füge dann einen weiteren Namen hininzufügen, den du selbst wählst. Gib am Ende die gesamte Liste aus.

Aufgabe 2: Länge einer Liste

Aufgabe: Schreibe ein Programm, das eine Liste von fünf verschiedenen Früchten enthält. Das Programm soll die Gesamtanzahl der Früchte in der Liste ausgeben, indem es die len()-Funktion verwendet. Fordere den Benutzer anschließend auf, eine Frucht hinzuzufügen, und gib die neue Länge der Liste aus.

Aufgabe 3: Durchlaufen einer Liste mit einer Schleife

Aufgabe: Erstelle ein Programm, das eine Liste von fünf Zahlen enthält. Verwende eine Schleife, um jede Zahl in der Liste zu durchlaufen und jede Zahl mit 2 zu multiplizieren. Speichere das Ergebnis in einer neuen Liste und gib diese am Ende aus.

Aufgabe 4: Arbeiten mit Dictionaries

Aufgabe: Schreibe ein Programm, das ein Dictionary enthält, das verschiedene Artikel (als Schlüssel) und deren Preise (als Werte) speichert. Das Programm soll den Benutzer auffordern, den Namen eines Artikels einzugeben. Wenn der Artikel im Dictionary vorhanden ist, gib den Preis aus. Andernfalls soll eine Nachricht ausgegeben werden, dass der Artikel nicht gefunden wurde. Füge am Ende einen neuen Artikel und dessen Preis zum Dictionary hinzu und gib das aktualisierte Dictionary aus.

Aufgabe 5: Tupel und Nutzereingaben

Aufgabe: Erstelle ein Programm, das ein Tupel von drei verschiedenen Städtenamen enthält. Das Programm soll den Benutzer auffordern, einen Index (0, 1 oder 2) einzugeben und den Namen der Stadt an diesem Index auszugeben. Fange mögliche Fehler ab, die durch ungültige Indizes verursacht werden können, und gib eine entsprechende Fehlermeldung aus.

Python Klassen & Objekte

Python ist eine objektorientierte Programmiersprache. Fast alles in Python ist ein Objekt mit seinen Eigenschaften und Methoden.

Klassen und Objekte sind die beiden Hauptaspekte der objektorientierten Programmierung. Folgedes Beispiel zeigt den Unterschied zwischen einer Klasse und den Objekten:

Klasse

Tier

Objekte innerhalb der Klasse

  • Katze
  • Hund
  • Pferd

Klasse

Schulfach

Objekte innerhalb der Klasse

  • Mathematik
  • Informatik
  • Deutsch

Eine Klasse ist wie ein Objektkonstruktor oder eine „Blaupause“ zum Erstellen von Objekten.

Erstellen einer Klasse

Um eine Klasse zu erstellen, verwendet man das Schlüsselwort class:

Erstellen Sie eine Klasse namens MeineKlasse mit einer Eigenschaft namens x:

class MeineKlasse:
  x = 5

Objekt erstellen

Jetzt können wir die Klasse MeineKlasse verwenden, um Objekte zu erstellen:

Erstellen eines Objekts mit dem Namen p1 und Ausgabe des Wert von x:

p1 = MeineKlasse()
print(p1.x)

Die Funktion __init__()

Die obigen Beispiele sind Klassen und Objekte in ihrer einfachsten Form und sind in realen Anwendungen nicht wirklich nützlich. Um die Bedeutung von Klassen zu verstehen, müssen wir die integrierte Funktion __init__() verstehen.

Alle Klassen verfügen über eine Funktion namens __init__(), die immer ausgeführt wird, wenn die Klasse initiiert wird. Um Funktionen zu erstellen, benötigen wir wieder das def Keyword.

Verwendung der Funktion __init__(), um Objekteigenschaften Werte zuzuweisen oder andere Vorgänge auszuführen, die beim Erstellen des Objekts erforderlich sind:

Beispiel

Erstellen einer Klasse mit dem Namen Person und Verwendung der Funktion __init__(), um Werte für Name und Alter zuzuweisen:

class Person:
  def __init__(self, name, alter):
    self.name = name
    self.alter = alter

p1 = Person("Peter", 36)

print(p1.name)
print(p1.alter)

Hinweis: Die __init__()Funktion wird jedes Mal automatisch aufgerufen, wenn die Klasse zum Erstellen eines neuen Objekts verwendet wird.

Der self-Parameter

Der self-Parameter ist ein Verweis auf die aktuelle Instanz der Klasse und wird für den Zugriff auf Variablen verwendet, die zur Klasse gehören.

Er muss nicht mit self benannt werden, man kann ihn beliebig benennen, aber er muss der erste Parameter einer beliebigen Funktion in der Klasse sein:

Verwendung der Wörter meintollesobjekt und abc anstelle von self :

## self Parameter wurde anders benannt
class Person:
  """
  Kommentar, der beschreibt was die Klasse können soll. Die Erklärung für den Nutzen von Funktionen werden dabei eingerückt
  -- Erklärung für Nutzen von Funktion 1
  -- Erklärung für Nutzen von Funktion 2 
  """
  def __init__(meintollesobjekt, name, alter):
    meintollesobjekt.name = name
    meintollesobjekt.alter = alter

  def meineFunktion(meintollesobjekt):
  """
  Detaillierte Erklärung zur Funktion
  :param meintollesobjekt: Beschreibung des ersten Parameters
                           ggf. erweiterte Infos
  """
    print("Hallo mein Name ist " + meintollesobjekt.name)

p1 = Person("Peter", 36)
p1.meineFunktion()


## Übliche Schreibweise mit self-Parameter
class Person:
  """
  Kommentar, der beschreibt was die Klasse können soll. Die Erklärung für den Nutzen von Funktionen werden dabei eingerückt
  -- Erklärung für Nutzen von Funktion 1
  -- Erklärung für Nutzen von Funktion 2 
  """
  def __init__(self, name, alter):
    self.name = name
    self.alter = alter

  def meineFunktion(self):
    """
    Detaillierte Erklärung zur Funktion
    """
    print("Hallo mein Name ist " + self.name)

p1 = Person("Peter", 36)
p1.meineFunktion()

Hinweis: Der self-Parameter ist ein Verweis auf die aktuelle Instanz der Klasse und wird für den Zugriff auf Variablen verwendet, die zur Klasse gehören.

Aufgabe

Einfache Klassendefinition und Objektinitialisierung

Ziel: Erstelle eine Python-Klasse namens Buch, die Bücher mit ihren Titeln und Autoren repräsentiert. Jedes Buch-Objekt soll bei seiner Initialisierung den Titel und den Autor als Argumente erhalten. Schreibe anschließend Code, um zwei Buchobjekte mit spezifischen Titeln und Autoren zu erstellen und die Details jedes Buches auszugeben.

Schritte:

  1. Klassendefinition: Definiere eine Klasse Buch. Die __init__-Methode der Klasse soll zwei Parameter annehmen (abgesehen von self): titel und autor. Speichere diese Parameter in Instanzvariablen innerhalb der Klasse.
  2. Objektinitialisierung: Erstelle zwei Instanzen der Buch-Klasse mit folgenden Details:
    • Buch 1: Titel: „Die unendliche Geschichte“, Autor: „Michael Ende“
    • Buch 2: Titel: „Momo“, Autor: „Michael Ende“
  3. Daten Ausgabe: Füge eine Methode in die Buch-Klasse ein, die zeige_details heißt und die Details des Buches ausgibt, also Titel und Autor.
  4. Teste deinen Code: Initialisiere die beiden Buchobjekte und rufe ihre zeige_details-Methode auf, um sicherzustellen, dass die Details korrekt ausgegeben werden.

Beispiel für erwartete Ausgabe:

Titel: Die unendliche Geschichte, Autor: Michael Ende
Titel: Momo, Autor: Michael Ende

Die Funktion __str__()

Die Funktion __str__() steuert, was zurückgegeben werden soll, wenn das Klassenobjekt als String dargestellt wird. Wenn die Funktion __str__() nicht gesetzt ist, wird die String-Darstellung des Objekts zurückgegeben. Mit dem def Keyword wird die Funktion erstellt.

Die String-Darstellung eines Objekts OHNE die Funktion __str__():

# Folgender Aufbau würde keine brauchbare Ausgabe erzeugen
class Person:
  def __init__(self, name, alter):
    self.name = name
    self.alter = alter

p1 = Person("Peter", 36)

print(p1)

# Ausgabe: <__main__.Person object at 0x00000176721AF4D0>

Die String-Darstellung eines Objekts MIT der Funktion __str__():

# Folgender Aufbau würde eine brauchbare Ausgabe erzeugen
class Person:
  def __init__(self, name, alter):
    self.name = name
    self.alter = alter

  def __str__(self):
    return f"{self.name}({self.alter})"

p1 = Person("Peter", 36)

print(p1)

# Ausgabe: Peter(36)

f-Strings

Das f vor den Anführungszeichen in einem String (wie f"...") in Python kennzeichnet einen sogenannten f-String. F-Strings, eingeführt in Python 3.6, bieten eine sehr bequeme Art, Variablen und Ausdrücke innerhalb von Zeichenketten (Strings) einzubetten und zu formatieren. Der Buchstabe f steht hierbei für „formatiert“.

Innerhalb der geschweiften Klammern {} eines f-Strings kann man Variablen, Ausdrücke, Funktionen und sogar Methodenaufrufe platzieren, die zur Laufzeit ausgewertet und durch ihre jeweiligen Werte ersetzt werden. Das macht den Code nicht nur kürzer und leichter lesbar, sondern auch flexibler, weil man direkt mit den Variablen innerhalb des Strings arbeiten kann, ohne sie vorher in den String konvertieren zu müssen.

Vorteil: Man spart sich z.B. das Casting von Integers und Floats

## Beispeil ohne f-String

name = "Welt"
nachricht = "Hallo, " + name + "!"
print(nachricht)


## Beispeil mit f-String

name = "Welt"
nachricht = f"Hallo, {name}!"
print(nachricht)

Beide Beispiele produzieren die Ausgabe Hallo, Welt!, aber das zweite Beispiel nutzt den f-String, um die Variable name direkt in den String einzubetten.

In der __str__-Methode unseres Buch-Objekts aus den Übungsaufgaben ermöglicht der f-String, dass die Attribute titel und autor des Objekts direkt in die zurückgegebene Zeichenkette eingefügt werden, was den Code sehr klar und prägnant macht:

def __str__(self):
    return f"Buch: {self.titel} von {self.autor}"

So wird aus dem f-String eine formatierte Zeichenkette, die die Titel- und Autorwerte des Buchobjekts enthält, wenn die Methode aufgerufen wird.

Aufgabe

Erweiterung der Buch-Klasse mit einer __str__-Methode

Ziel: Modifiziere die Buch-Klasse aus der vorherigen Aufgabe, indem du eine __str__-Methode hinzufügst, die eine formatierte Zeichenkette (f-String) zurückgibt, wenn ein Buchobjekt in einen String umgewandelt wird oder direkt ausgegeben wird. Anschließend, erstelle erneut zwei Buchobjekte mit vorgegebenen Titeln und Autoren und gib sie aus, um die Funktionalität der __str__-Methode zu testen.

Schritte:

  1. Modifiziere die Klassendefinition: Füge der Buch-Klasse eine __str__-Methode hinzu. Diese Methode soll keinen Parameter außer self akzeptieren und eine Zeichenkette zurückgeben, die den Titel und den Autor des Buches in einem ansprechenden Format enthält.
  2. Formatierung der Ausgabe: Die __str__-Methode sollte eine Zeichenkette zurückgeben, die etwa folgendermaßen aussieht: "Buch: [Titel] von [Autor]", wobei [Titel] und [Autor] durch die entsprechenden Werte der Instanzvariablen ersetzt werden.
  3. Erstellung und Ausgabe von Buchobjekten: Erstelle wie in der vorherigen Aufgabe zwei Buchobjekte mit den gleichen Titeln und Autoren. Verwende dieses Mal jedoch die print-Funktion, um die Objekte direkt auszugeben, anstatt eine spezielle Methode aufzurufen. Überprüfe, ob die Ausgabe der __str__-Methode entspricht.

Erwartete Ausgabe:

Buch: Die unendliche Geschichte von Michael Ende
Buch: Momo von Michael Ende

Objektmethoden

Objekte können auch Methoden enthalten. Methoden in Objekten sind Funktionen, die zum Objekt gehören.

Erstellung eine Methode in der Person-Klasse:

Einfügen einer Funktion, die eine Begrüßung druckt, und Ausführung auf dem p1-Objekt:

class Person:
  def __init__(self, name, alter):
    self.name = name
    self.alter = alter

  def meineFunktion(self):
    print("Hallo mein Name ist " + self.name)

p1 = Person("Peter", 36)
p1.meineFunktion()

Aufgabe

Speichern von Buchobjekten in einer Liste

Ziel: Ergänze die bestehende Buch-Klasse und den darauf aufbauenden Code, indem du eine Funktion hinzufügst, die es ermöglicht, mehrere Buchobjekte in einer Liste zu speichern. Erstelle eine Funktion, die durch alle gespeicherten Buchobjekte iteriert und deren Details mittels der __str__-Methode ausgibt.

Schritte:

  1. Liste für Buchobjekte: Definiere eine leere Liste namens bibliothek, in der die Buchobjekte gespeichert werden sollen.
  2. Funktion zum Hinzufügen von Büchern: Erstelle eine Funktion namens buch_hinzufuegen, die ein Buchobjekt als Parameter nimmt und es der bibliothek-Liste hinzufügt.
  3. Funktion zum Anzeigen der Bücher: Entwickle eine Funktion zeige_buecher, die durch die bibliothek-Liste iteriert und jedes Buchobjekt mithilfe der print-Funktion ausgibt. Nutze hierbei die __str__-Methode der Buchobjekte, um eine formatierte Ausgabe zu erreichen.
  4. Testen des Codes: Erstelle einige Buchobjekte und füge sie mit der buch_hinzufuegen-Funktion zur bibliothek-Liste hinzu. Verwende anschließend die zeige_buecher-Funktion, um alle Bücher in der Liste auszugeben.

Erwartete Ausgabe:

Buch: Die unendliche Geschichte von Michael Ende
Buch: Momo von Michael Ende

Objekteigenschaften ändern

Man kann die Eigenschaften von Objekten wie folgt ändern:

Ändern des Alters von p1 auf 40:

p1.alter = 40

Objekteigenschaften löschen

Man kann Eigenschaften von Objekten löschen, indem man das del-Schlüsselwort verwendet:

Löschen Sie die Alterseigenschaft aus dem p1-Objekt:

del p1.alter

Objekte löschen

Man kann Objekte löschen, indem man das del-Schlüsselwort verwendet:

Löschen des p1-Objekts:

del p1

Die pass-Anweisung

class-Definitionen dürfen nicht leer sein. Wenn man jedoch aus irgendeinem Grund eine class-Definition ohne Inhalt haben will, gibt man die pass-Anweisung ein, um eine Fehlermeldung zu vermeiden.

class Person:
  pass

Aufgabe Der Objekt-Taschenrechner

Ziel

Erstelle eine Python-Klasse namens Taschenrechner, die ein Objekt darstellt, das die vier grundlegenden arithmetischen Operationen (+, -, *, /) durchführen kann. Die einzelnen Operationen sollen dabei eigene Methoden innerhalb der Klasse sein.

Schritte zur Implementierung

  1. Klassendefinition:
    • Definieren Sie eine Klasse namens Taschenrechner.
    • Die __init__-Funktion kann in dieser einfachen Version leer bleiben oder nur eine Begrüßung ausgeben (verwenden Sie hierfür die pass-Anweisung oder lassen Sie __init__ weg, wenn keine Initialisierung notwendig ist).
  2. Methoden-Definitionen:
    • Erstellen Sie vier Instanzmethoden, die jeweils zwei Zahlen als Parameter (neben self) annehmen:
      • addieren(self, zahl1, zahl2)
      • subtrahieren(self, zahl1, zahl2)
      • multiplizieren(self, zahl1, zahl2)
      • dividieren(self, zahl1, zahl2)
  3. Implementierung der Logik:
    • Jede Methode soll die jeweilige Berechnung durchführen.
    • Die Methode soll das Ergebnis zurückgeben (return) und zusätzlich eine formatierte Nachricht auf der Konsole ausgeben, die die Rechnung und das Ergebnis klar darstellt. Nutzen Sie dafür f-Strings!
  4. Objekt und Test:
    • Erstellen Sie eine Instanz (ein Objekt) Ihrer Klasse, z. B. mein_rechner.
    • Rufen Sie jede der vier Methoden mit Beispielzahlen auf und geben Sie das zurückgegebene Ergebnis (zusätzlich zur Ausgabe in der Methode) aus.

Beispiel für erwartete Ausgabe

--- Testlauf Taschenrechner ---
Addition: 10 + 5 = 15
Ergebnis der Addition: 15

Subtraktion: 20 - 7 = 13
Ergebnis der Subtraktion: 13

Multiplikation: 4 * 6 = 24
Ergebnis der Multiplikation: 24

Division: 50 / 10 = 5.0
Ergebnis der Division: 5.0

Erweiterung

Um die gelernten Konzepte input() und Fehlerbehandlung zu integrieren, können Sie die Aufgabe wie folgt erweitern:

Herausforderung: Interaktive Nutzung

Erweitern Sie Ihre Klasse Taschenrechner um eine neue Methode namens starte_rechner(self).

Fehlerbehandlung (optional): Fangen Sie ab, wenn der Benutzer versucht, durch Null zu dividieren, und geben Sie in diesem Fall eine Fehlermeldung aus.

Ablauf: Diese Methode soll den Benutzer in einer Endlosschleife (while True) auffordern, eine Operation und zwei Zahlen einzugeben.

Eingaben: Fragen Sie den Benutzer nach der gewünschten Operation (+, -, *, /) und anschließend nach Zahl 1 und Zahl 2.

Verzweigung: Verwenden Sie if/elif/else, um zu prüfen, welche Operation gewählt wurde, und rufen Sie dann die entsprechende Klassenmethode auf (z. B. self.addieren(z1, z2)).