# Python Tutorium ## Hausaufgabe 1 ### Aufgabe 1 Gehe alle Zahlen von 1 bis 100 durch. Wenn die Zahl durch 3 teilbar ist, soll `Python` ausgegeben werden. Ist die Zahl durch 5 teilbar, soll `Rocks` ausgegeben werden. Ist die Zahl durch 15 teilbar, soll `PythonRocks` ausgegeben werden. ### Aufgabe 2 Gib folgenden Text ``` Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ``` - in einer Zeile aus - auf mehreren Zeilen aus (mindestens 5) ### Aufgabe 3 Nimm den Text aus Aufgabe 2 und ersetze jedes Leerzeichen durch einen Unterstrich. Dann ersetze jedes `Lorem` durch `Juhu!`. ### Aufgabe 4 Erstelle eine Liste mit folgenden Werten: - Kartoffeln - Nudeln - Früchte Hänge jedes der Worte an den folgenden Satz an und gib ihn aus: `Ich esse gern ` Dann entferne einen beliebigen Wert aus der Liste und gib die Liste aus. Füge 3 Beliebige Werte zur Liste hinzu und hänge jedes Wort der Liste erneut an den gegebenen Satz. ### Aufgabe 5 Sei `x=0`, solange `x<100`, soll x ausgegeben werden. Schreib eine `for`-Schleife und eine `do-while`-Schleife. ## Feedback Hausaufgabe 1 ### Generell: Es geht zwar, alles als Script zu schreiben, aber ich finde es schöner, wenn man die einzelnen Aufgaben in Funktionen verpackt und einen Entry-point benutzt. Dann sieht das schöner aus, und das muss man auch ein bisschen üben. ### Aufgabe 1: Das funktioniert gut. Es gibt aber einen cooleren Weg: ```python for value in range(1,100): if value % 3 == 0: print("Python", end='') if value % 5==0: print("Rocks", end='') print() ``` Der `end`-Parameter legt fest, was am Ende der Zeile sein soll. Wenn man das auf einen leeren Wert legt, wird die Zeile nicht beendet. Dann kann man die letzte Abfrage sparen. Wenn eine Zahl durch 3 und 5 teilbar ist, ist sie auch durch 15 teilbar. Trotzdem sehr gut gelöst! ### Aufgabe 2: Sehr gut. Genau, worauf ich abgezielt habe. Multiline Strings. ### Aufgabe 3: Wenn man den originalen Wert nicht mehr braucht, wie hier, kann man auch die Variable überschreiben. Also statt ```python x = lorem.replace(" ", "_") ``` einfach ```python lorem = lorem.replace(" ", "_") ``` Das ist aber nicht so wichtig und nur eine Stil-Sache. ### Aufgabe 4: Das ist nicht so unelegant, wie du anscheinend denkst und es funktioniert. Also gut gemacht :) Meine Vorliebe ist aber, Formatstrings zu benutzen. Das ist irgendwie schöner und übersichtlicher. ```python print(f"Ich esse gerne {x}") ``` Cool, dass du das unpacking entdeckt hast (`x, y, z = liste`). Da hatte ich auf eine Schleife abgezielt: ```python liste = ["Kartoffeln", "Nudeln", "Früchte"] for word in liste: print(f"Ich esse gerne {word}") ``` Mit dieser Schleife kannst du alle Werte in den Satz einsetzen, egal, wie lang die Liste ist, ohne etwas anpassen zu müssen. ### Aufgabe 5: Die erste Schleife ist gut. Die zweite Schleife gibt die Zahlen 1 - 99 aus. Da fehlt also die 0. Statt der `while`-Schleife hatte ich auf die `do-while` Schleife gezielt. Das war mein Fehler, weil es die gar nicht gibt :D Sorry dafür. ## Hausaufgabe 2 Für diese Aufgabe kannst du alles in einem Projekt machen. Du musst nicht für jede Erweiterung alle Dateien kopieren. ### Aufgabe 1 - Klassen #### a) Erzeuge eine Klasse `Tier` mit folgenden Attributen: - `beine`: Anzahl der Beine - `name`: Rufname des Tiers - `spezies`: Spezies des Tiers In deinem Programm soll ein Tier so initialisiert werden können: ```python mein_tier = Tier("Hubert", 4) ``` Vorerst soll `Spezies` für jedes Tier einfach nur `Tier` sein. #### b) Erzeuge eine zweite Klasse `Fahrzeug` mit den Attributen: - `Hersteller` - `Modell` - `Räder` - `PS` #### c) Sorge dafür, dass ```python mein_tier = Tier("Hubert", 4) print(mein_tier) ``` die folgende Ausgabe erzielt: ``` Spezies: 'Tier', Name: 'Hubert', Beine: '4' ``` #### d) Sorge dafür, dass ```python mein_fahrzeug = Fahrzeug("Toyota", "Corolla", 4, 184) print(mein_fahrzeug) ``` folgende Ausgabe erzielt ``` Hersteller: 'Toyota', Modell: 'Corolla', Räder: '4' Leistung: '184 PS' ``` > Suchbegriffe: > - `__init__(self)` > - `__str__(self)` > - class ### Aufgabe 2 - Vererbung #### a) Schreibe eine Klasse `Hund`, die die Eigenschaften der Klasse `Tier` erbt. Ein Hund soll immer 4 Beine haben. Weiterhin soll jeder Hund einen Namen erhalten und der `Spezies`-Wert soll immer `Hund` sein. > Suchbegriffe: > - inheritance > - super > - self > - `__init__(self)` ```python hund = Hund("Argus") print(hund) ``` soll folgende Ausgabe ergeben: ``` Spezies: 'Hund', Name: 'Argus', Beine: `4` ``` #### b) **(i)** Schreib eine Klasse `Spinne`, die die Eigenschaften der Klasse `Tier` erbt. Das Attribut `Spezies` soll hier immer Spinne sein und die Anzahl der Beine immer 8. **(ii)** Erweiter die Klasse spinne um das Attribut `status`. Der Status soll angeben, ob die Spinne lebt, oder nicht. Zu Anfang soll der Wert lebendig sein. **(iii)** Pass die Ausgabe (siehe Hund) auf die Spinne an und erweitere sie um den aktuellen Status. **(iv)** Erweitere die Klasse um eine Funktion `schlagen(mit)`. `mit` soll einen String übergeben, der einen Gegenstand beschreibt, mit dem man die Spinne schlägt. Außerdem, soll die Funktion den Zustand der Spinne auf `tot` setzen. Erzeuge im Hauptprogramm ein Objekt der Klasse Spinne, gib die Attribute aus, nutze die Funktion schlagen und gib die Attribute erneut aus. #### c) **(i)** Schreib eine Klasse `Panzer`, die die Klasse `Fahrzeug` erweitert. Die neue Klasse soll außer den geerbten Attributen folgende neue enthalten: - Kaliber - Vorrat: Anzahl der mitgeführten Granaten - Besatzung: Anzahl der Besatzungsmitglieder **(ii)** Füge die neuen Attribute zur Ausgabe der Klasse `Panzer` hinzu. ## Aufgabe 3 - User input Das wird das Hauptprogramm dieser Aufgabe. Bitte den Nutzer, einzugeben, ob er ein Tier oder ein Fahrzeug erfassen möchte. Die Eingabe sollte `Tier` oder `Fahrzeug` akzeptieren. Wird etwas anderes eingegeben, soll das Programm eine sinnvolle Nachricht ausgeben und erneut fragen. Ist eine Eingabe gültig, soll als nächstes die Art des Tieres oder Fahrzeugs angegeben werden. Danach sollen die Attribute für die jeweilige Klasse abgefragt werden. Ist die Eingabe vollständig, soll die erzeugte Klasse mit allen Attributen ausgegeben werden. Der Nutzer soll das Programm jederzeit durch Eingabe von `Exit` beenden können. > Suchbegriffe: > - input() ## Aufgabe 4 Erweitere das Programm um eine Abfrage, ob die vorher erzeugte Klasse gespeichert werden soll. Wählt der Nutzer `Ja`, häng die Beschreibung der Klasse an die Datei `out.txt` an. > Suchbegriffe: > - append to file > - write to file > - `with` statement # Feedback Tut2 ## Aufgabe 1 Zuerst gab es eine Fehlermeldung, weil ```python= mein_tier = Tier(4, "Hubert", "Tier") ``` 3 argumente gibt. Dein Konstruktor, hat aber keine Argumente akzeptiert. Wenn man ```python= def __init__(self): self.beine = "" self.name = "" self.spezies = "" ``` zu ```python= def __init__(self, beine, name, spezies): self.beine = beine self.name = name self.spezies = spezies ``` ändert, funktioniert das. So war es auch in der Aufgabenstellung beschrieben. Der Konstruktor (die `__init__()`) sollte Beine etc als Argumente bekommen. Die Fehlermeldung in `Save()` passiert, weil die `write()` Funktion ein Argument braucht, wie du erkannt hast. Jede Klassenfunktion bekommt den `self`-Parameter übergeben. Den kann man hier nutzen. ```python= speichern.write(str(self)) ``` Hier wird self, also das Objekt auf dem die Funktion gerufen wird zu einem String konvertiert. Dabei wird die vorher geschriebene `__str__` funktion benutzt. Der Aufruf funktioniert dann schließlich so: ```python= mein_tier = Tier(4, "Hubert", "Tier") mein_tier.Save() ``` Um jetzt Daten zu ändern, muss die UserInput-Funktion noch gerufen werden ```python= mein_tier.UserInput() ``` Momentan wird jedes Mal, wenn man eine Klasse speichern möchte, die vorherige überschrieben. Viel schöner wäre es doch aber, wenn man die alle hintereinander speichern könnte. Noch ein Hinweis zum Stil: Wenn man Daten abfragt, ist es gut, am Ende der Frage ein Leerzeichen einzufügen. Sieht schöner aus. Bei der Klasse Fahrzeug gilt das gleiche Feedback. ## Aufgabe 2 ### a) Sieht sehr gut aus. Ich hätte mir die Klasse nur in einer `hund.py` gewünscht. ### b) Sieht auch sehr gut aus. Hier bitte in `spinne.py` verpacken. ### c) Hier schlägt der Konstruktor fehl, weil der Fahrzeug-Konstruktor keine Argumente entgegen nimmt. Außerdem ist das Kaliber jetzt für jeden Panzer den du erzeugst immer 130 mm. Die Ausgabe der Eckdaten für den Panzer soll auch in anderen Klassen, die Panzer importieren funktionieren. Dazu muss die `__str__()`-Methode angepasst werden. ## Aufgabe 3 Der Kontrollfluss ist genau richtig. Nach den Korrekturen in Klasse Tier und Fahrzeug funktioniert das so nicht mehr. Du hast hier die Wahl, entweder den Konstruktoren von Tier und Fahrzeug default werte zu geben. ```python= def __init__(self, beine=3, ....): ``` Alternativ, kannst du in `task3.py` die Klassen mit leeren Parametern erzeugen: ```python= neues_fahrzeug = Fahrzeug("", "", ...) ``` Das wäre aber schlechter Stil. ## Aufgabe 4 Wieso ist bei der Eingabe des Fahrzeugs der Speichervorgang im Hauptprogramm und nicht in der Funktion? # Hausaufgabe 3 Wir machen im Grunde das gleiche, wie oben. Nur vielleicht lustiger. Vielleicht. Ziel der Übung ist es, ein Grundgerüst für ein Minigame zu bauen. Vorerst wird das ganze Textbasiert laufen. Ich wünsche mir in der Abgabe folgende Dateistruktur: - inventory - inventory.py - item.py - character - character.py - player.py - test - main.py ## Aufgabe 1 - Inventar ### a) - item.py Erstelle eine Klasse `Item`. Ein item hat die folgenden Werte: - `hr_name` - der Human-readable name des Items - `short_name` - der Kurzname des Items - `hp_impact_inventory` - der Einfluss des Items auf die maximalen Lebenspunkte, wenn im Inventar - `hp_impact_use` - der Einfluss des Items auf die Lebenspunkte, wenn es benutzt wird - `xp_impact_inventory` - `xp_impact_use` - `ap_impact_inventory` - `ap_impact_use` - `ad_impact_inventory` - `ad_impact_use` - `uses_left` - Anzahl der verbleibenden Nutzungen dieses Items - `usable` - boolean, legt fest, ob das Item aktiv benutzt werden kann, oder ob es passives item ist Außerdem soll es die Funktionen: - `show_item_stats(short_name)` - zeigt die Werte des items an geben. ### b) Erstelle eine Klasse `Inventory`. Ein Inventar hat die Folgenden Werte: - `used_size` - Anzahl der Gegenstände, die ein Character momentan trägt. - `max_size` - die Anzahl der Gegenstände, die ein Character tragen kann. - `item_list` - Liste der items, die ein Character trägt. Außerdem soll es die Funktionen: - `add_item(short_name)` - `drop_item(short_name)` - entfernt das item aus dem Inventar geben. ## Aufgabe 2 - Character ### a) character.py Erstelle eine Klasse `Character`. Ein Character hat die Werte: - `base_hp` - Lebenspunkte ohne items - `additional_hp` - Lebenspunkte, die durch Items hizugefügt werden - `base_xp` - Erfahrungspunkte - `additional_xp` - `base_ap` - Rüstungspunkte - `additional_ap` - `base_ad` - Angriffsschaden - `additional_ad` - `inv` - Inventar (Siehe inventory.py) - `position` - ein Tupel (x, y) der Position des Characters auf der Map Außerdem soll es die Funktionen: - `use_item(short_name)` - xp, ap, ad impacts_use werden angewendet, solange uses_left > 0 - uses_left wird reduziert - `attack(enemy)` - `receive_damage(damage)` - Zahl, die festlegt, wie hoch der Schaden ist - wird erst vom Rüstungswert und dann von HP abgezogen ### b) player.py Die Klasse `Player` soll alle attribute der Klasse `Character` erben. Außerdem soll sie zusätzlich diese Funktionen enthalten. - `go_north()` - `go_east()` - `go_south()` - `go_west()` (nicht der Pet Shop Boys song, obwohl der gut ist) - `search_vicinity()` - gibt eine Liste mit Items in der Umgebung zurück ## Aufgabe 3 - Tests In `test.py` sollen alle Elemente getestet werden: - Sei ein Character auf Feld (x, y) - nach Bewegung Nord muss position (x,y+1) sein etc. - Füge drei Items zum Inventar eines Spielers hinzu - Simuliere einen Kampf zwischen Character und Character