Voraussetzungen
keine
Lerninhalte
Nutzung der Code-Boxen
Erstellen von Dateien
Verwendung dieses Buches#
Ganz einfach: Lesen. Es gibt aber ein paar zusätzliche Features, die hier erklärt werden. Es wird auch darauf eingegangen, welche Software für diese Features verwendet wird. Das soll nur als Zusatzinformationen dienen und ist für die Verwendung des Online Buches nicht relevant.
Auf allen Seiten, die Codeblöcke enthalten, verbergen sich hinter dem Raketen-Symbol in der Kopfzeile zwei Buttons, einen auf dem “Binder” steht und einen auf dem “Live Code” steht.
Beide Buttons bewirken auf unterschiedliche Weise, dass der Matlab-Code in den Code-Blöcken editier- und ausführbar wird. Im Hintergrund wird in einer virtuellen Maschine ein Octave-Kern gestartet. Octave ist ein freier Matlab-Klon, der weitestgehend mit Matlab kompatibel ist.
Es kann unter Umständen schon mal etwas dauern, bis im Hintergrund eine virtuelle Maschine mit Octave gestartet ist. Die Technologie baut auf dem kostenlosen Service Binder (ein Jupyter Projekt) auf, sodass auch bei der Ausführung der Code-Blöcke keine hohe Performanz erwartet werden sollte.
Rechts neben dem beschriebenen Raketen-Symbol befindet sich das GitHub-Logo (das mit der Katze). Über diesen Button ist es möglich Verbesserungsvorschläge oder Bugs selbst zu beheben und zur Verbesserung dieses Buches beizutragen. Falls die Verbesserung nicht selbst durchgeführt werden kann, ist es auch möglich auf GitHub einen Issue mit einer Kurzbeschreibung des Problems zu eröffnen. Dieser wird dann schnellstmöglich bearbeitet.
Live Code#
Die einfachste Möglichkeit, den Code auf dieser Seite zu editieren und auszuführen ist über den Button “Live Code”. Per Klick auf die Taste “run”, wird der Code ausgeführt, mit “restart” wird der im Hintergrund laufende Octave-Kernel neu gestartet.
Denken Sie daran, dass die Code-Zellen unter Umständen voneinander abhängig sein könnten. Wenn zum Beispiel in einer Code-Zelle auf eine Variable x
zugegriffen wird, muss diese auch im Workspace zur Verfügung stehen. Ist dies nicht der Fall, haben Sie wahrscheinlich die Code-Zelle weiter oben, in der x
initialisiert wird, nicht ausgeführt.
Achtung
Beim Aufrufen von Dateien mit der “Live Code”-Methode kann es zu Komplikationen kommen. Die Lösungen für viele bekannte Probleme sind hier beschrieben: Troubleshooting
Binder#
Der Nachteil von Binder ist, dass man von dieser Seite weggeführt wird. Der Vorteil ist, dass man auf die Inhalte über Jupyter Lab zugreifen kann, eine Art Entwicklungsumgebung die im Browser läuft.
Sie können nicht nur die Code-Blöcke editieren und ausführen, Sie können auch neue Dokumente, wie z.B. m-files, erstellen oder hochladen, Dokumente herunterladen und eine Linux-Konsole starten. Das Ganze funktioniert über einen Docker-Container, der über den Binder Service geladen wird.
Achtung
Das bedeutet insbesondere, dass alle erstellten Dateien und Änderungen nur temporär sind und nicht über eine Session hinaus erhalten bleiben! Laden Sie erstellte Dateien unbedingt runter, bevor Sie das Fenster schließen, oder noch besser, erstellen Sie Dateien offline auf Ihren Computer und laden Sie sie hoch, wenn Sie sie in einer interaktiven Session verwenden möchten.
Dateien erstellen#
In Jupyter Lab (“Binder” Button), lassen sich Dateien mithilfe des Launchers erstellen. Man kann aber auch Dateien mit der “Live Code”-Methode erstellen. Wenn ein Code-Block mit der Zeile %%file myfile.m
beginnt, wird der folgende Inhalt des Blocks in eine Datei myfile.m
geschrieben. Dies ist insbesondere nützlich um Funktionen zu schreiben, da Funktionen in Matlab immer in eigenen Dateien gespeichert werden müssen, oder erst am Ende eines Skriptes stehen dürfen.
%%file hello_world.m
function hello_world()
for i=1:5
disp('Hello World, how is your day?')
end
run hello_world
Hello World, how is your day?
Hello World, how is your day?
Hello World, how is your day?
Hello World, how is your day?
Hello World, how is your day?
Achtung
Auch hier gilt, dass nur temporäre Dateien angelegt werden können, die die aktuelle Session nicht überleben.
Unit Testing#
Unit Testing ist aus moderner Software-Entwicklung nicht mehr wegzudenken. Sobald ein Software-Paket etwas größer wird und aus einer Vielzahl von Modulen, Bibliotheken, Funktionen und Skripten besteht, sollte regelmäßig getestet werden, ob die Module noch so funktionieren wie erwartet. Unit Tests sind im wesentlichen kleine Programme, die diese Module auf ihre Funktionsfähigkeit prüfen. Ein weit verbreitetes Programmierparadigma besagt sogar, dass man erst die Unit Tests schreiben soll, bevor man das Modul erstellt.
Unit Tests sind nicht Teil dieses Kurses und es wird nicht von Ihnen verlangt, dass Sie Unit Tests für Ihre Programme schreiben. Für die meisten Übungsaufgaben auf dieser Seite müssen Matlabfunktionen erstellt werden. Für diese Übungsaufgaben werden bereits fertige Unit Tests zur Verfügung gestellt, mit der die eigens erstellten Funktionen auf ihre Richtigkeit überprüft werden können.
Unit Tests auf dieser Seite ausführen#
Hinweis
Wie Sie Unit Tests zusammen mit Versionskontrolle verwenden, lernen Sie in Einführung in GitHub.
Sowohl Matlab als auch Octave bieten Werkzeuge für Unit Tests an. Leider sind die jeweiligen Toolboxen von Octave und Matlab nicht kompatibel zu einander. Daher wird an dieser Stelle MOxUnit verwendet. MoXUnit ist ein freies open source unit testing Framework, das sowohl mit Matlab als auch Octave funktioniert. Beachten Sie die Hinweise auf der Matlab Seite: Sie können den Code nicht direkt installieren, sondern müssen die Installationsanweisungen auf dem zugehörigen GitHub repository befolgen.
Wenn für eine Übungsaufgabe ein Unit Test zur Verfügung steht, dann wird das an der entsprechenden Stelle explizit erwähnt. Angenommen die Übungsaufgabe besteht darin, eine Funktion fac
zu schreiben, die die Fakultät \(n!\) einer Zahl \(n\) berechnet. Der Einfachheit halber schreiben wir einen Wrapper für die von Matlab zur Verfügung gestellt Funktion factorial
, ungeachtet dessen, dass es dem Zweck der Übungsaufgabe nicht so richtig gerecht wird:
%%file fac.m
function r = fac(n)
% wrapper for Matlabs factorial function
r = factorial(n);
Die bereitgestellten Unit Tests befinden sich in der Datei test_fac.m
. Diese Tests überprüfen, ob die Funktion sich so verhält wie erwartet. Den Code hinter test_fac.m
können Sie hier ausklappen.
Show code cell source
%%file test_fac.m
function test_suite=test_fac
% initialize unit tets
try
test_functions=localfunctions();
catch
end
initTestSuite;
%%%%%%%%%%%%%%%%%%%%%%%
% Basic tests %
%%%%%%%%%%%%%%%%%%%%%%%
function test_fac_0
% test if fac(0)==1
assertEqual(fac(0),1);
function test_fac_1
% test if fac(1)==1
assertEqual(fac(1),1);
function test_fac_5
% test if fac(5)==120
assertEqual(fac(5),120);
%%%%%%%%%%%%%%%%%%%%%%%
% More advanced tests %
%%%%%%%%%%%%%%%%%%%%%%%
function test_fac_exception_negative
% test if exceptions are thrown for negative values
assertExceptionThrown(@()fac(-1));
function test_fac_exception_noninteger
% test if exceptions are thrown for noninteger values
assertExceptionThrown(@()fac(1.5),'*');
function test_fac_array
% test if fac works on array inputs
assertEqual(fac([0 1 2; 3 4 5]),[1 1 2; 6 24 120]);
Der Test wird mit folgendem Befehl ausgeführt:
moxunit_runtests test_fac.m
suite: 6 tests
......
--------------------------------------------------
OK (passed=6)
ans = 1
Aha, es gab also sechs Tests, und die werden von fac
, bzw. der von Matlab zur Verfügung gestellten Funktion factorial
, alle erfüllt. Super!
Das war allerdings auch etwas geschummelt. Wir probieren eine etwas andere Implementierung der Funktion:
%%file fac.m
function r = fac(n)
% calculates the factorial of the input n
r = prod(1:n);
Created file 'fac.m'.
Mal sehen, ob immer noch alle Tests durchlaufen:
moxunit_runtests test_fac.m
suite: 6 tests
...FFF
--------------------------------------------------
failure: No exception was raised
assertExceptionThrown:84 (/home/user/MOxUnit/MOxUnit/assertExceptionThrown.m)
test_fac>test_fac_exception_negative:31 (/home/user/Modellbildung-und-Simulation/content/00_einleitung/test_fac.m)
failure: No exception was raised
assertExceptionThrown:84 (/home/user/MOxUnit/MOxUnit/assertExceptionThrown.m)
test_fac>test_fac_exception_noninteger:35 (/home/user/Modellbildung-und-Simulation/content/00_einleitung/test_fac.m)
failure: inputs are not of the same size
First input: 1x1 double
1
Second input: 2x3 double
[1 1 2;6 24 120]
assertEqual:70 (/home/user/MOxUnit/MOxUnit/assertEqual.m)
test_fac>test_fac_array:39 (/home/user/Modellbildung-und-Simulation/content/00_einleitung/test_fac.m)
--------------------------------------------------
FAILED (passed=3, failure=3)
ans = 0
Ok, drei der Tests sind erfolgreich, drei schlagen fehl. Die Test Suite gibt Auskunft darüber, welche der Tests fehlschlagen. Die Ausgabe
suite: 6 tests
...FFF
--------------------------------------------------
bedeutet, dass die letzten drei Tests fehlgeschlagen sind. Zusätzlich gibt jeder fehlgeschlagene Test Informationen darüber aus, welches Verhalten erwartet wurde und welches tatsächlich eingetroffen ist. Manchmal sind diese Ausgaben etwas kryptisch, dann lohnt es sich einen Blick in die Implementierung der Tests zu werfen. Mit dem Befehl type
lässt sich der Inhalt einer Datei in Matlab wiedergeben. Das können wir benutzen um uns die sechs Tests in test_fac.m
genauer anzuschauen:
type test_fac.m
test_fac.m is the user-defined function defined from: /home/jovyan/test_fac.m
function test_suite=test_fac
% initialize unit tets
try
test_functions=localfunctions();
catch
end
initTestSuite;
%%%%%%%%%%%%%%%%%%%%%%%
% Basic tests %
%%%%%%%%%%%%%%%%%%%%%%%
function test_fac_0
% test if fac(0)==1
assertEqual(fac(0),1);
function test_fac_1
% test if fac(1)==1
assertEqual(fac(1),1);
function test_fac_5
% test if fac(5)==120
assertEqual(fac(5),120);
%%%%%%%%%%%%%%%%%%%%%%%
% More advanced tests %
%%%%%%%%%%%%%%%%%%%%%%%
function test_fac_exception_negative
% test if exceptions are thrown for negative values
assertExceptionThrown(@()fac(-1));
function test_fac_exception_noninteger
% test if exceptions are thrown for noninteger values
assertExceptionThrown(@()fac(1.5),'*');
function test_fac_array
% test if fac works on array inputs
assertEqual(fac([0 1 2; 3 4 5]),[1 1 2; 6 24 120]);
Aha! Prinzipiell funktioniert die Funktion für nicht-negative ganzzahlige skalare Eingaben. Der Test erwartet aber zusätzlich, dass Fehler ausgegeben werden, wenn die Eingabe negativ oder nicht ganzzahlig ist. Außerdem soll die Funktion für matrixwertige Eingaben funktionieren. Es wird erwartet, dass die Fakultät elementweise berechnet wird.
Unit Tests offline ausführen.#
Wenn Sie möchten, können Sie die Unit Tests auch offline ausführen. Dazu müssen Sie die jeweilige Test Suite, in diesem Fall test_fac.m
, herunterladen und das MOxUnit Framework lokal installiert haben.
Installieren Sie MOxUnit. Beachten Sie die Hinweise auf der Matlab Seite: Sie können den Code nicht direkt installieren, sondern müssen die Installationsanweisungen auf dem zugehörigen GitHub repository befolgen.
Laden Sie sich den entsprechenden Unit Test von dieser Seite herunter. Wenn die Funktion, die getestet werden soll,
myFunction
heißt, ist der Unit Test in der Dateitest_myFunction.m
gespeichert. Sie können sich mit dem Befehltype test_myFunction.m
den Inhalt der Datei wiedergeben lassen, oder mit dem “Interact”-Button eine interaktive Session starten und die Datei per Mausklick herunterladen.Führen Sie den Unit Test mit
moxunit_runtests test_myFunction.m
aus.
Schwierigkeitsgrade, Voraussetzungen und Lernziele#
Jedes Kapitel enthält eine kurze Übersicht zu den Inhalten und Schwierigkeitsgraden der Aufgaben. Dabei wird zwischen Aufwand und Anspruch unterschieden. Zu jedem Themenblock ist außerdem ein Kahoot-Quiz verlinkt. Am Anfang jeder Aufgabe sind zusätzlich kurz die Voraussetzungen und Lernziele aufgelistet.
Schwierigkeitskategorien#
Modellbildung: Die Schwierigkeit, von der Realität auf die Formel zu kommen / das Modell nachzuvollziehen. Zum Beispiel: Man hat Problem A und muss bei der Modellbildung auf eine ganze Reihe von Formeln aus der technischen Mechanik zurückgreifen.
Implementierung: Der Anspruch an die Kenntnis der Syntax und Verständnis der zugrundeliegenden Rechenoperationen. Beispielsweise die Kombination verschiedener schleifen, die Verwendung von Funktionen oder eigene Implementierung komplexer Routinen.
Mathematik: Die Komplexität der zu verstehenden Mathematik. Zum Beispiel vertieftes Verständnis von Funktionen, Ableitungs-/Integrationsregeln oder Matrizenrechnungen.
Physikalische Zusammenhänge: Die Schwierigkeit, die physikalischen Formeln zu verstehen. Zum Beispiel: Drallsatz oder Schwingungen sind schwierige Formeln, dagegen ist D‘Alembert oder Energieerhaltung eher einfach nachzufollziehen.
Sterne#
★ ☆ ☆ ☆ ☆ Es gibt praktisch keine eigene Leistung.
★ ★ ☆ ☆ ☆ Man muss etwas tun.
★ ★ ★ ☆ ☆ Nichts besonderes, aber auch nicht trivial.
★ ★ ★ ★ ☆ Man muss evtl. etwas Zeit investieren, sollte aber für alle machbar sein.
★ ★ ★ ★ ★ Eine Aufgabe, die intensiveres Nachdenken/Knobeln erfordern kann. Möglicherweise muss recherchiert oder Hilfe geholt werden.
Voraussetzungen und Lernziele#
Die beiden Boxen zu Beginn jeder Aufgabe sollen eine Orientierungshilfe für Studierende und Lehrende geben. Sollte die Aufgabe eingangs zu schwer erscheinen, können in den Voraussetzungen Anhaltspunkte gefunden werden, welche Themen nochmal wiederholt werden sollten. Andererseits zeigen die Lerninhalte auf, welche Aufgaben besonders gut für die Stärkung bestimmter Kompetenzen geeignet sind.
Troubleshooting#
Wenn ich auf
run
klicke, steht da nurWaiting for kernel...
und nichts passiert.Lösung: Geduld. Wahrscheinlich wurden gerade Änderungen an diesem Buch vorgenommen und Sie sind die erste Person, die seitdem interaktive Inhalte nutzen will. Damit haben Sie ein rebuild des binder image getriggert. Das kann schon mal eine Weile dauern. Dasselbe gilt für die “Interact” Funktion. Hier erhält man aber ausführlichere Informationen über eine Konsolenausgabe beim Start.
Wenn ich einen Code-Block starte, erhalte ich eine seltsame Fehlermeldung, die nicht nach Octave oder Matlab aussieht.
Lösung: Aktuell wird der Code fälschlicherweise an einen Python-Interpreter übergeben. Öffnen Sie die Seite in Binder oder führen Sie den Code offline aus.
Ich bin mir sicher, dass ich die Übungsaufgabe richtig bearbeitet habe, aber der Unit Test gibt Fehler aus.
Lösung: Möglicherweise wurde für die Bearbeitung der Übungsaufgabe Matlab-Code geschrieben, der nicht mit Octave kompatibel ist. In diesem Fall sollte es schon helfen, den Unit Test lokal in der eigenen Matlab Installation laufen zu lassen.
Beim Ausführen des Unit Tests mit der “Live Code”-Methode erhalte ich folgende Fehlermeldung:
moxunit_runtests test_fac.m
error: Parameter not recognised or file missing: test_fac.m
error: called from
moxunit_runtests>get_params at line 365 column 21
moxunit_runtests at line 72 column 11
Das ist ein bekanntes Problem, an dem gerade gearbeitet wird. Die Dateien sollten beim Start von “Live Code” oder spätestens beim ersten Ausführen der Code-Box mit %%file (...).m
erstellt werden. Wo die Datei liegt, wird im Ausgabefenster angezeigt. Wo Sie sich befinden, erfahren Sie mit dem Befehl pwd()
.
Um auf von uns hinterlegte Dateien zuzugreifen, ist die einfachste Lösung, die Binder- statt der “Live Code”-Methode zu verwenden. Ein alternativer Workaround ist, den relativen Pfad der aktuellen Seite explizit im Befehl zu verwenden. Dieser setzt sich zusammen aus /home/jovyan/content
sowie dem akutellen Unterordner dieser Seite, der sich aus der URL ablesen lässt. Für diese Seite lautet er 00_einleitung
. Der Befehl
moxunit_runtests /home/jovyan/content/00_einleitung/test_fac.m
sollte funktionieren.