PDF-Datei

Werbung
Aufgabe 1 (Terminal) ¶
Das echte Leben spielt sich leider nicht immer nur in Jupyter-Notebooks ab. Eine wichtige
Kernkompetenz stellt das Bedienen einer Shell (auch Kommandozeile oder Konsole genannt) dar; eine
Shell läuft in der Regel in einem sogenannten Terminal-Programm. In Jupyter können Sie ein Terminal
samt Shell öffnen, indem Sie auf die Schaltfläche New klicken und dort dann Terminal auswählen.
Anmerkung: Selbsverständlich kann man all diese Dinge auch auf einem lokalen Terminal außerhalb von
Jupyter tun. Oder Sie melden sich über das Programm ssh auf gp1.cs.upb.de oder einem der
Poolrechner an. Eine Liste der Poolräume samt Belegung finden Sie hier: https://cs.unipaderborn.de/rechnerbetrieb-irb/poolraeume/ (https://cs.uni-paderborn.de/rechnerbetriebirb/poolraeume/) ; eine Liste der Rechner ist hier: https://irb-service.cs.unipaderborn.de/poolrechner.html (https://irb-service.cs.uni-paderborn.de/poolrechner.html). (Vorzugsweise
melden Sie sich auf einem Poolrechner an und nicht auf gp1.cs.upb.de. Dort funktioniert allerdings nur
Ihr regulärer Account, nicht die gp1_16_... Accounts).
Vorsicht: Manche Befehle variieren aber je nach Betriebssystem.
a)
Erstmal ein paar Aufwärmübungen mit dem Terminal. Wenden Sie jeden dieser Befehle einmal an.
Wenn Sie factor eingeben, können Sie danach eine Zahl eingeben, die dann vom Terminal in
Primfaktoren zerlegt wird.
Der date Befehl gibt Ihnen das aktuelle Datum aus.
Mithilfe von id kommen Sie an Informationen über sich selbst.
Wenn Sie time vor einen Befehl schreiben, wird dessen Laufzeit gemessen. (Besonders
interessant, wenn Sie selbst geschriebene Programme ausführen.)
Vielleicht der wichtigste Befehl von allen: man - kurz für manual (Handbuch). man nimmt als
ersten Parameter den Befehl entgegen, zu dem Sie Hilfe brauchen. Probieren Sie z.B.:
man man - Das Handbuch zum Handbuch
man bash- Das Handbuch zur üblichen Shell.
Viele Kommandos verstehen auch optionale Parameter wie -h, -? oder --help. Probieren Sie das bei
ein paar Beispielen aus.
b)
Nun beschäftigen wir uns mit der Navigation im Dateisystem. Sie können sich jederzeit mithilfe des
Befehls ls die Liste der im aktuellen Verzeichnis liegenden Verzeichnisse und Ordner anzeigen lassen.
Das aktuelle Verzeichnis selbst wird mit pwd angezeigt (print working directory). cd (change directory) ist
der Befehl, mit dem man das Verzeichnis wechseln kann. (Syntax: cd Verzeichnis oder cd .. um ins
übergeordnete Verzeichnis zu gelangen)
Erstellen Sie (touch Dateiname) eine neue Textdatei (.txt) in einem beliebigen Ordner und bearbeiten
Sie diese (nano Dateiname). Nano verlassen Sie wieder mit der Tastenkombination Ctrl+X. Nachdem
Sie das getan haben, gehen Sie über die übliche Oberfläche von Jupyter in das entsprechende
Verzeichnis und überprüfen, ob in der Datei tatsächlich das steht, was Sie gerade hineingeschrieben
haben.
Das funktioniert so im Prinzip auch mit Notebooks (.ipynb), aber tun Sie sich das nicht an (Notebooks
sind sog. JSON-Dateien, die von Hand nicht komfortabel editiert werden können).
Finden Sie nun mithilfe des Befehls info (eine Alternative zu man) heraus, wie Sie Dateien kopieren,
umbenennen, löschen und verschieben können. Das info-Menü können sie mit der Taste Q wieder
verlassen.
Hinweis: Zum Umbenennen und Verschieben von Dateien können Sie denselben Befehl nutzen.
Hinweis: Alternative Editoren sind etwa vi oder emacs.
c)
In einem Terminal kann man auch Python verwenden. Dazu ruft man zunächst den Interpreter mit dem
Befehl python3 auf. Probieren Sie das einmal aus, indem Sie einige Zeilen Code eintippen. Zum Beispiel
ein paar Zuweisungen, print-Befehle, oder was Ihnen sonst so in den Sinn kommt.
Auf diese Art können Sie beliebig große und komplexe Programme schreiben, es gibt hier keine
Einschränkungen gegenüber Editoren oder Notebooks. Auch Funktions- und Klassendefinitionen sind
möglich. Sie können Ihren Code allerdings nicht speichern, sondern nur direkt ausführen.
Beachten Sie aber, dass eine eingegebene Zeile nicht mehr korrigiert werden kann. Das heißt bei einem
Fehler muss man schlimmstenfalls mit der gesamten Funktions- oder Klassendefinition neu beginnen.
Implementieren Sie im Interpreter eine Klasse, deren Objekte einen String speichern, der im Konstruktor
übergeben wird. Der Aufruf der Methode __str__ soll diesen String zurückgeben.
Aufgabe 2 (Programme ausführen)
a)
In dieser Aufgabe soll es darum gehen, dass Sie eine Python-Datei, welche im Dateisystem vorliegt,
ausführen. Dazu erstellen Sie mithilfe eines Editors (der gewöhnliche Texteditor reicht dafür bereits aus)
eine .py Datei, in welche Sie lauffähigen Code hineinschreiben. Dieser Code sollte einige print()Anweisungen enthalten, da diese sich für die Veranschaulichung in diesem Fall gut eignen.
Sie könnten zum Beispiel ein kurzes Programm implementieren, das einfach das kleine Einmaleins auf
der Konsole ausgibt.
Eventuell ist es notwendig, die Datei manuell zu *.py umzubenennen, wenn Sie ein Textdokument
bearbeiten (je nach Editor).
Anmerkung: Das Zeichen * wird in diesem Kontext auch Wildcard genannt, und kann für eine beliebige
Zeichenfolge stehen. Die Notation *.py steht also für einen beliebigen Dateinamen mit der Endung .py
Nun muss die Datei noch irgendwie ausgeführt werden. Dazu öffnen Sie nun ein Terminal (Jupyter oder
lokales System, je nachdem wo Sie Ihre Datei erstellt haben), navigieren mittels cd in das entsprechende
Verzeichnis und verwenden dort den Befehl python3 Dateiname.py.
Wenn Sie alles richtig gemacht haben, sollte Ihr Code nun ausgeführt werden und Sie sollten die
entsprechenden Ausgaben im Terminal sehen können.
b)
Man kann über die Kommandozeile auch Parameter an ein Programm übergeben. Diese folgen einfach
durch Leerzeichen getrennt auf den Dateinamen im Programmaufruf.
Im Code kann man dann mit diesen Parametern arbeiten. Alle Parameter sind in der Liste sys.argv
gespeichert. Diese ist eine gewöhnliche Liste, wie Sie sie bereits kennen. Um diese verwenden zu
können, müssen Sie allerdings das Modul sys importieren.
Veranschaulichen Sie sich dieses Prinzip, indem Sie ein Programm schreiben, das seine
Kommandozeilenargumente der Reihe nach auf der Konsole ausgibt. Dann führen Sie es mit
verschiedenen Parametern aus. Verwenden Sie auch verschiedene Typen.
c)
Schreiben Sie ein Programm, das zwei übergebene Zahlen addiert, wenn der letzte übergebene
Parameter False ist, oder diese multipliziert, falls er True ist. Das Ergebnis soll auf der Konsole
ausgegeben werden.
d)
Man kann nicht nur Python-Programme auf diese Weise ausführen. Auch Java lässt sich per Terminal
ausführen. Da Java allerdings im Gegensatz zu Python kompiliert werden muss, sind hier zwei Schritte
vonnöten.
Ihnen wurde mit dieser Präsenzübung eine Datei namens HelloWorld.java mitgeliefert. Diese
beinhaltet ein lauffähiges Java-Programm. Zunächst müssen Sie im Terminal mittels cd in das
entsprechende Verzeichnis navigieren, sofern Sie sich noch nicht dort befinden. Daraufhin können Sie die
Datei kompilieren, indem Sie den Befehl javac Dateiname.java aufrufen. Wie Sie sehen, befindet
sich jetzt im Ordner eine weitere Datei namens HelloWorld.class. Class-Dateien sind das
ausführbare Äquivalent zu Java-Dateien und können mittels java Dateiname ausgeführt werden.
Sie sollten bei Ausführung des Java-Programms die Ausgabe "Hello World" auf dem Terminal sehen.
e)
Sie stellen sich vermutlich die berechtigte Frage, weshalb man nicht einfach Java-Dateien ausführen
kann, sondern diese erst zu einer Class-Datei kompilieren muss. Dies hat technische Gründe. Java läuft
auf einer virtuellen Maschine, die nur Java-Bytecode ausführen kann. Sie können diesen betrachten,
indem sie den Befehl javap -c Dateiname verwenden. Dafür muss die Datei vorher
selbstverständlich kompiliert worden sein.
Aufgabe 3 (Tests/Fehlersuche)
Schreiben Sie umfangreiche Tests für den folgenden Code, in denen Sie auch möglichst viele Sonderfälle
prüfen. Finden Sie Fehler? Können Sie einige davon korrigieren? Verwenden Sie die Funktionen print
und assert um Fehler zu finden.
Fällt Ihnen merkwürdiges Verhalten auf? Wenn ja, versuchen Sie herauszufinden, welche Methode nicht
so arbeitet wie Sie es erwartet hätten.
In [ ]: class A:
"""Eine Art Warteschlange für Strings"""
def __init__(self, wait = [], now = ""):
self.wait = wait
self.now = now
def new_string(self, x):
"""Fügt einen String zur Warteschlange hinzu"""
self.wait.append(str(x))
def next_string(self):
"""Holt den nächsten String aus der Warteschlange, speicher
t ihn als aktuellen String"""
now = self.wait[0]
self.wait.pop(0)
def top(self):
"""Gibt den aktuellen String zurück"""
return self.now
Aufgabe 4 (Umgang mit "schwierigen"
Problemen)
Zur Bearbeitung dieser Aufgabe kann es hilfreich sein, online nach Lösungsansätzen zu suchen.
a)
Implementieren Sie eine Methode, die True zurückgibt, wenn sie am Klausurtermin von Gp1 aufgerufen
wird, und ansonsten immer False.
b)
Implementieren Sie eine Methode, die einen String übergeben bekommt und die Summe aller UnicodeInteger-Repräsentationen der einzelnen Zeichen in diesem String berechnet.
c)
Erklären Sie, weshalb der Code in Aufgabe 3 ein solch merkwürdiges Verhalten an den Tag legt.
Herunterladen