13. Hausaufgaben

13.1. Hausaufgabe 1

Hausaufgabe 1.1 (1 Punkt)

Gegeben ist eine Funktion f(x):

f(x) := \sqrt{a + x ^ b}-\frac{x}{c-4}

  1. Erzeugen Sie ein Python Skript mit beliebigem Namen mittels Spyder.
  2. Definieren Sie drei Variablen a, b und c mit den Werten 9, 4 und 7.
  3. Definieren Sie eine Variable x mit dem Wert 2.
  4. Berechnen Sie den Wert der Funktion f(x) für x = 2.
  5. Geben Sie das Ergebnis aus 4) in der folgenden Form aus: x = ..., f(x) = .... Setzen Sie dabei für die Punkte den Wert für x und Ihr Ergebnis aus 4) ein.
  6. Wiederholen Sie die Punkte 4) und 5) aber verwenden Sie anstelle des Divisionsoperators / den Ganzzahldivisionsoperator // zum Definieren der Funktion.
  7. Probieren Sie selbstständig weitere Werte für die Variablen a, b und c aus. Geben Sie in einem Kommentar Werte für a, b und c an, die dazu führen, dass das Skript abgebrochen und der Fehler ZeroDivisionError angezeigt wird.

13.2. Hausaufgabe 2

Hausaufgabe 2.1 (1 Punkt)

Gegeben ist eine Liste Zahlen mit den Einträgen 99, 'Vier', 0, 7.5, 3.

Schreiben Sie einen Code, der die folgenden Punkte löst und lassen Sie sich zu jedem Punkt eine kurze Ausgabe mit erklärendem Text ausgeben.

  1. Finden Sie heraus ob sich die Zahl 7.5 in dieser Liste befindet.
  2. Wenn ja, an welcher Stelle befindet sich die Zahl 7.5? Kontrollieren Sie, ob Sie die richtige Stelle gefunden haben, indem Sie den zum jeweiligen Index zugehörigen Wert aus Zahlen auslesen.
  3. Löschen Sie das Element 'Vier' aus Zahlen.
  4. Geben Sie die Länge der Liste aus.
  5. Sortieren Sie die Liste und geben Sie das Ergebnis mittels print aus.
  6. Fügen Sie das Element '4' ans Ende der Liste an.
  7. Multiplizieren Sie jedes Element der Liste mit 3.
  8. Multiplizieren Sie die Liste mit 2 und speichern Sie das Ergebnis als neue Liste Werte ab.
  9. Erstellen Sie eine neue Liste doppel_Liste, die die Liste Zahlen als 0. Element und die Liste Werte als 1. Element enthält. D.h. doppel_Liste ist eine Liste, die Listen enthält.
  10. Kopieren Sie doppel_Liste explizit.
  11. Überprüfen Sie auf mindestens eine Art, dass eine Veränderung an der Kopie die ursprüngliche Liste tatsächlich nicht verändert.

Hinweis

Überprüfen Sie nach jedem Punkt durch Ausgabe in der Konsole, dass Ihr Code richtig funktioniert.

Hausaufgabe 2.2 (1 Punkt)

  1. Definieren Sie eine Liste Ausgaben mit folgenden Einträgen: " Konzert = 20", "Kino =  20.5", "  Sportschuhe    = 60". Die Liste beschreibt die Ausgaben innerhalb eines Monats in Euro.
  2. Extrahieren Sie die Zahlenwerte aus den Strings der Liste und speichern Sie sie in den Variablen Konzert, Kino und Sportschuhe als Gleitkommazahlen ab. Achten Sie darauf, dass die Strings beliebige Zahlen mit beliebig vielen Leerzeichen beinhalten können.
  3. Berechnen Sie die Summe der Ausgaben und geben Sie das Ergebnis per print Befehl aus.
  4. Erstellen Sie ein Dictionary Ausgaben_dict, das die Variablen Konzert, Kino und Sportschuhe mit ihren jeweiligen Zahlenwerten enthält. Dabei soll der jeweilige Variablenname als String der Schlüssel sein. Für den Wert wird der jeweilige Zahlenwert als Gleitkommazahl zugeordnet.
  5. Errechnen Sie erneut die Summe der Ausgaben. Verwenden Sie diesmal jedoch das Dictionary Ausgaben_dict für die Berechnung. Geben Sie das Ergebnis erneut per print Befehl aus.
  6. Fügen Sie eine weitere Ausgabe mit dem Schlüssel "Konzert" und dem Wert 30 in das Dictionary Ausgaben_dict hinzu und geben Sie das Dictionary mittels print Befehl aus. Beantworten Sie folgende Frage im Kommentar: Was passiert mit dem zugehörigen Wert, wenn in ein Dictionary ein bereits vorhandener Schlüssel hinzugefügt wird?

13.3. Hausaufgabe 3

Hausaufgabe 3.1 (1 Punkt)

Gegeben ist ein Dictionary Einkaufszettel:

Einkaufszettel = {'Milch':'0.5 l', 'Wasser':'5 l', 'Einwegmasken':'10 Stueck',
                  'Brot':'1 kg', 'Nudeln':'2 kg', 'Kartoffeln':'3 kg',
                  'Wein':'3 l','Desinfektionsspray':'2 Dosen', 'Schokolade':'0.1 kg'}

Der Schlüssel gibt das Produkt an, der Wert beschreibt die Produktmenge in der entsprechenden Einheit.

  1. Erstellen Sie drei Listen (Essen, Getraenke, Sonstiges), die die zugehörigen Produktmengen ohne Einheit enthalten:
  • Produktmengen mit Einheit kg sollen in die Liste Essen eingefügt werden
  • Produktmengen mit Einheit l sollen der Liste Getraenke zugeordnet werden
  • Die Liste Sonstiges soll jene Produktmengen enthalten, die andere Einheiten besitzen
  1. Summieren Sie die Produktmengen in der Liste Essen auf und speichern Sie das Ergebnis in der Variable Summe_Essen.

  2. Geben Sie abschließend alle drei Listen in Ihrer Konsole aus. Die Liste Essen sollte zum Beispiel wie folgt aussehen:

    In [1]: print(Essen)
    [1.0, 2.0, 3.0, 0.1]
    
  3. Geben Sie außerdem den Wert der Variable Summe_Essen per print Befehl aus. Verwenden Sie dabei für die Formatierung die f-String Methode und geben Sie die Zahl mit zwei Kommastellen aus.

Hinweis

Sie können zum Aufsummieren der Produktmengen die Listenfunktion sum verwenden.

Hausaufgabe 3.2 (1 Punkt)

Gegeben ist eine Liste Pruefungsantritte, die als Einträge jeweils eine Liste pro Person mit den Daten Vorname, Nachname und Prüfungspunkte enthält:

Pruefungsantritte = [["Anton","Jahn",60],
                    ["Natalia","Schwarz",37],
                    ["Manuel","Berger",88],
                    ["Heinrich","Meier",100],
                    ["Christoph","Müller",22],
                    ["Mario","Burger",70]]

Die Liste Bezahlt enthält die Vornamen aller Teilnehmer, die den Kurs bezahlt haben:

Bezahlt = ["Anton","Manuel","Natalia","Mario"]

Legen Sie nun ein Dictionary Bestanden an, welches als Schlüssel die Nachnamen jener Personen enthält, die den Kurs bezahlt und die Abschlussprüfung bestanden haben. Als Wert sollen die Prüfungspunkte der jeweiligen Personen angegeben werden. Die Abschlussprüfung gilt als bestanden wenn zumindest 60 Punkte erreicht werden.

Gehen Sie dazu wie folgt vor:
  1. Legen Sie ein leeres Dictionary Bestanden an.
  2. Lesen Sie mit Hilfe einer Schleife den Vornamen, den Nachnamen und die Prüfungspunkte jeder Person aus Pruefungsantritte aus. Definieren Sie dafür innerhalb der Schleife die Variablen Vorname, Nachname und Punkte.
  3. Überprüfen Sie, ob die Person bezahlt hat, das heißt, ob sich der Vorname in der Liste Bezahlt befindet. Überprüfen Sie außerdem, ob die Person die benötigte Punkteanzahl erreicht hat.
  4. Wenn die Person bezahlt und die benötigte Punkteanzahl erreicht hat, tragen Sie die Person in das Dictionary Bestanden ein. Verwenden Sie den Nachnamen als Schlüssel und die Punkteanzahl als Wert.
  5. Geben Sie das Dictionary Bestanden in Ihrer Konsole aus.

13.4. Hausaufgabe 4

Hausaufgabe 4.1 (1 Punkt)

  1. Schreiben Sie eine Funktion append2 mit den Argumenten Liste (Typ: list), String (Typ: str) und verbose (Typ: bool):
  • Das Argument verbose soll optional sein und den Default Wert False besitzen.
  • Die Funktion soll genauso wie die Listenfunktion append die übergebene Zeichenkette zur übergebenen Liste hinzufügen.
  • Im Gegensatz zu append soll append2 aber die neue verlängerte Liste zurückgeben.
  • Wird das optionale Argument verbose auf True gesetzt, soll die neue verlängerte Liste schon mit dem Funktionsaufruf per print Befehl ausgegeben werden.
  1. Definieren Sie zum Testen Ihrer Funktion im Hauptprogramm die folgende Liste Liste, sowie die folgenden Zeichenkette String:

    Liste  = ['Anna','Maria','Marko']
    String = 'Theo'
    
  2. Rufen Sie im Hauptprogramm ihre Funktion einmal mit dem Argument verbose=False auf und speichern Sie die Rückgabe der Funktion als Variable Liste_False. Geben Sie danach Liste_False per print Befehl aus.

  3. Definieren Sie Liste und String neu und wiederholen Sie die Schritte aus Punkt 3) mit dem Argument verbose=True und dem Variablennamen Liste_True.

  4. Definieren Sie Liste und String noch einmal neu. Verwenden Sie diesmal aber die bekannte Listenfunktion append um den String der Liste hinzuzufügen. Speichern Sie die Rückgabe der Funktion in der Variable Liste_append. Geben Sie Liste_append mit print Befehl aus. Kommentieren Sie in Ihrem Skript, wieso Liste_append den Wert None besitzt.

13.5. Hausaufgabe 5

Hausaufgabe 5.1 (1 Punkt)

Ziel dieser Aufgabe ist es Funktionen zu schreiben, die eine Textdatei mit Informationen über Fahrzeuge einlesen sowie abspeichern können. Die Funktionen sollen im Hauptteil des Programms auf eine Beispieldatei angewendet werden.

Auf TUWEL finden Sie die Beispieldatei fahrzeuge.txt. Jede Zeile enthält die Bezeichnung eines Fahrzeugs, den Neupreis in Euro, das Alter in Jahren, sowie den durchschnittlichen Wertverlust des Fahrzeugs pro Jahr in Euro. Die einzelnen Einträge sind durch einen Beistrich (,) voneinander getrennt. z.B.:

VW Golf, 25000.0, 5, 2500.0
  1. Erstellen Sie eine Funktion Einlesen(filename), die die Werte aus einer Textdatei mit Namen filename einliest und die Daten als Dictionary zurückgibt. Als Key des Dictionaries verwenden Sie die Bezeichnung des Fahrzeugs. Der Value ist eine Liste mit Neupreis, Alter und Wertverlust pro Jahr. Gehen Sie dabei davon aus, dass die Textdatei im selben Verzeichnis wie Ihr Python-Skript liegt.

  2. Verwenden Sie die Funktion Einlesen im Hauptteil Ihres Skripts, um die Beispieldatei fahrzeuge.txt als Dictionary einzulesen. Verwenden Sie das Dictionary, um den Restwert aller Fahrzeuge zu berechnen (Restwert = Neupreis - Alter in Jahren * Wertverlust pro Jahr). Hängen Sie den berechneten Restwert an die Liste des entsprechenden Eintrags im Dictionary an.

  3. Schreiben Sie eine Funktion Schreibe(fahrzeugDict,filename), die die Bezeichnung des Fahrzeugs und den Restwert aus dem Dictionary fahrzeugDict in eine Textdatei mit dem Namen filename abspeichert. Der Restwert soll als Gleitkommazahl mit zwei Nachkommastellen abgespeichert werden. Als Trennzeichen verwenden Sie einen Doppelpunkt (:).

  4. Wenden Sie die Funktion Schreibe im Hauptteil des Skripts auf das in Punkt 2) erstellte Dictionary an und verwenden Sie restwerte.txt als Dateinamen. Eine Zeile der Ausgabedatei soll z.B. wie folgt aussehen:

    VW Golf: 12500.00
    

Hinweis

Das Programm muss mit beliebigen Textdateien des oben genannten Formats funktionieren. Wenn Ihre Abgabe nur mit der Textdatei aus TUWEL funktioniert erhalten Sie keine Punkte.

13.6. Hausaufgabe 6

Hausaufgabe 6.1 (1 Punkt)

  1. Erstellen Sie eine Klasse Fahrzeug, die die Attribute bezeichnung, neupreis, alter, und den Wertverlust pro Jahr wertverlust übergeben bekommt. wertverlust soll dabei als privates Attribut gespeichert werden. Berechnen Sie im Konstruktor außerdem den Restwert (Restwert = Neupreis - Alter in Jahren * Wertverlust pro Jahr) und speichern Sie ihn als Klassenattribut restwert ab. Das Erstellen eines Objekts könnte z.B. so aussehen:

    In [1]: VWGolf = Fahrzeug("VW Golf", 25000.0, 5, 2500.0)
    In [2]: print(VWGolf.restwert)
    12500.0
    
  2. Erstellen Sie eine Methode get_Wertverlust, die den Wertverlust des jeweiligen Fahrzeugs zurückgibt, und eine Methode set_Wertverlust, über die sich der Wertverlust setzen lässt. Achten Sie dabei darauf, dass in der Set Methode der Restwert des Fahrzeugs neu berechnet werden muss. z.B.:

    In [3]: print(VWGolf.get_Wertverlust())
    2500.0
    In [4]: VWGolf.set_Wertverlust(3000.0)
    In [5]: print(VWGolf.get_Wertverlust())
    3000.0
    In [6]: print(VWGolf.restwert)
    10000.0
    
  3. Überladen Sie den < Operator (__lt__), sodass der Restwert zweier verschiedener Fahrzeug-Objekte miteinander verglichen wird. z.B.:

    In [1]: VWGolf = Fahrzeug("VW Golf", 25000.0, 5, 2500.0)
    In [2]: Porsche911 = Fahrzeug("Porsche 911", 100000.0, 2, 10000.0)
    In [3]: print(Porsche911 > VWGolf)
    True
    In [4]: print(Porsche911 < VWGolf)
    False
    

Hausaufgabe 6.2 (1 Punkt)

  1. Erstellen Sie eine von Fahrzeug abgeleitete Klasse Nutzfahrzeug, die das zusätzliche Attribut nutzlast in kg übergeben bekommt. Um die restlichen Attribute von Nutzfahrzeug zu initialisieren, verwenden Sie den Konstruktor der Klasse Fahrzeug. Das Erstellen eines Nutzfahrzeug Objekts könnte z.B. so aussehen:

    In [1]: FordTransit = Nutzfahrzeug("Ford Transit", 20000.0, 3, 2000.0, 800.0)
    
  2. Überladen Sie den print-Operator (__str__) der Klasse Nutzfahrzeug, sodass die Bezeichnung des Fahrzeugs, sein Restwert, sowie die Nutzlast ausgegeben werden. z.B.:

    In [2]: print(FordTransit)
    Ford Transit: Restwert = 14000.00 Euro, Nutzlast = 800.00 kg
    

13.7. Hausaufgabe 7

Hausaufgabe 7.1 (1 Punkt)

Schreiben Sie basierend auf der Funktion Einlesen aus Hausaufgabe 5.1 eine Methode Einlesen_Check. Diese Methode soll das selbe machen wie die Funktion Einlesen, aber zusätzlich überprüfen, ob die Information in der übergebenen Datei das richtige Format hat. Es sollen nur Fahrzeuge gespeichert werden, für die Angaben im richtigen Format vorhanden sind.

Fangen Sie dazu die folgenden typischen Fehler mit Hilfe von try-except-else Blöcken ab:

  1. Die Datei könnte z.B. nicht existieren.
  2. Die Datei könnte anstatt Zahlenwerte für das Alter usw. etwas enthalten, das sich nicht zu einem Integer oder Float konvertieren lässt. Siehe z.B. die Testdatei fahrzeuge_fehlerhaft_v1.txt auf TUWEL.
  3. Die Datei könnte in einer Zeile falsche Trennzeichen, z.B. Strichpunkte (;) statt Beistrichen (,) enthalten bzw. eine falsche Anzahl an Angaben enthalten. Siehe z.B. die Testdatei fahrzeuge_fehlerhaft_v2.txt auf TUWEL.

Geben Sie eine hilfreiche Fehlermeldung aus, wenn ein Fehler aufgetreten ist!

Hinweis

Am Besten Sie gehen wie folgt vor:

  • Rufen Sie die Funktion mit einer Datei auf, die den gewünschten Fehler erzeugt (einige Dateien finden Sie auf TUWEL).
  • Finden Sie den minimalen Codeblock, der den Fehler erzeugt.
  • Schreiben Sie eine try-except Anweisung mit dem richtigen Fehlertyp.
  • Überlegen Sie sich, welche Teile des Codes nur ausgeführt werden sollen, wenn KEIN Fehler aufgetreten ist. Diese Teile gehören in einen else-Block.
  • Wenn ein Codeblock in mehreren try-Blöcken enthalten sein müsste: Verwenden Sie stattdessen einen try-Block mit mehreren except-Blöcken und einem else-Block!

Testen Sie Ihren Code mit einigen Beispielen. Wenn Ihre Funktion richtig funktioniert, sollten Sie in etwa folgende Ausgaben erhalten:

  • Bei einer nicht existierenden Datei, z.B. fahrzeuge_existiertnicht.txt:

    In [1]: fahrzeugDict = Einlesen_Check('fahrzeuge_existiertnicht.txt')
    Datei 'fahrzeuge_existiertnicht.txt' nicht gefunden!
    In [2]: print(fahrzeugDict)
    {}
    
  • Mit der Testdatei fahrzeuge_fehlerhaft_v1.txt:

    In [1]: fahrzeugDict = Einlesen_Check('fahrzeuge_fehlerhaft1.txt')
    Falscher Datentyp!
    Falscher Datentyp!
    In [2]: print(fahrzeugDict)
    {'VW Golf': [25000.0, 5.0, 2500.0], 'Tesla Model3':[50000.0, 1.0, 5000.0]}
    
  • Mit der Testdatei fahrzeuge_fehlerhaft_v2.txt:

    In [1]: fahrzeugDict = Einlesen_Check('fahrzeuge_fehlerhaft2.txt')
    Falsche Trennzeichen oder falsche Anzahl von Werten!
    Falsche Trennzeichen oder falsche Anzahl von Werten!
    In [2]: print(fahrzeugDict)
    {'VW Golf': [25000.0, 5.0, 2500.0], 'Skoda Fabia':[12000.0, 4.0, 1200.0]}
    

Hinweis

Bitte verwenden Sie ausschliesslich die Lösungen und zur Verfügung gestellten Dateien aus TUWEL!

Hausaufgabe 7.2 (1 Punkt)

Verwenden Sie das Modul doctest, um Ihre Klasse Fahrzeug aus Hausaufgabe 6.1 zu testen:

  1. Kopieren Sie hierfür die Lösung von Hausaufgabe 6.1 aus TUWEL in ein neues Python-File.
  2. Schreiben Sie für alle Methoden der Klasse (also Konstruktor, set_Wertverlust, get_Wertverlust, und < Operator) jeweils einen Test. Das Testen von privaten Attributen des Konstruktors ist nicht so einfach - beschränken Sie sich beim Testen des Konstruktors daher auf die restlichen Attribute (bezeichnung, neupreis, alter, restwert). Vergessen Sie nicht darauf bei der Methode set_Wertverlust zu testen, ob auch das Attribut restwert korrekt neu berechnet wird.
  3. Führen Sie danach den doctest im Hauptteil des Skripts aus.

Hinweis

Bitte verwenden Sie ausschließlich die Lösungen aus TUWEL!

13.8. Hausaufgabe 8

Hausaufgabe 8.1

In dieser Hausaufgabe soll der geschätzte Restwert eines Fahrzeugs mit dem realen Restwert grafisch verglichen werden. Gegeben sind hierfür folgende Variablen:

wert  = 25000.0                                 # Neuwert in Euro
jahre = [0,1,2,3,4,5]                           # Liste des Fahrzeugalters in Jahren
wertverlust_durschnitt = 2500.0                 # Durschnittlicher Wertverlust pro Jahr in Euro
wert_prozent_real = [100.0,70.0,60.0,55.0,52.0,50.0]

wert ist der Neuwert in Euro, die Liste jahre beinhaltet das Fahrzeugalter in Jahren und wertverlust_durchschnitt ist der durchschnittliche Wertverlust pro Jahr in Euro. wert_prozent_real ist der reale Restwert des Fahrzeugs in Prozent vom Neupreis für das jeweilige Jahr. Zum Beispiel ist der Restwert nach 0 Jahren 100% des Neuwerts, nach 1 Jahr 70% des Neuwerts etc.

Gehen Sie nun wie folgt vor:

  1. Wandeln Sie die Listen jahre und wert_prozent_real in NumPy-Arrays um. Bennennen Sie die Arrays jahre_array sowie wert_prozent_real_array. Importieren Sie dafür die entsprechende Bibliothek.

  2. Berechnen Sie den geschätzten Restwert des Fahrzeugs für jedes Jahr und speichern Sie das Ergebnis in einem neuen NumPy-Array wert_jahre_durschnitt. Versuchen Sie, das neue Array komplett ohne zusätzliche Funktionen oder Schleifen zu berechnen! wert_jahre_durschnitt sollte dann wie folgt aussehen:

    In [1]: print(wert_jahre_durschnitt)
    array([25000., 22500., 20000., 17500., 15000., 12500.])
    
  3. Berechnen Sie nun ein Array wert_jahre_real mit Hilfe des Arrays wert_prozent_real_array. Versuchen Sie erneut, keinerlei zusätzlichen Funktionen oder Schleifen zu verwenden. wert_jahre_real sollte dann wie folgt aussehen:

    In [1]: print(wert_jahre_real)
    array([25000., 17500., 15000., 13750., 13000., 12500.])
    
  4. Vergleichen Sie nun die Restwerte aus den Arrays wert_jahre_durschnitt und wert_jahre_real für jedes Jahr grafisch. Verwenden Sie dafür die plot Funktion der Bibliothek matplotlib (siehe Kapitel 12.2. im Skriptum). Ihr Ergebnis sollte dann wie folgt aussehen:

_images/HUE8_1_plot.png
  1. Berechnen Sie abschließend den realen Restwert nach 1.5 Jahren. Verwenden Sie dafür die Funktion interp1d von Scipy (siehe Kapitel 12.3. Skriptum). Geben Sie dann das Ergebnis per print Befehl aus. Die Ausgabe sollte dann wie folgt aussehen:

    Realer Wert nach 1.5 Jahren: 16250.00 Euro