MLTutorBeispielerstellung: Unterschied zwischen den Versionen

Aus Physik
Zur Navigation springen Zur Suche springen
Zeile 22: Zeile 22:
   
 
=== Kann man beim Ausführen eines Skriptes <tt>input</tt> umgehen bzw. Werte vordefinieren, die dann verwendet werden? ===
 
=== Kann man beim Ausführen eines Skriptes <tt>input</tt> umgehen bzw. Werte vordefinieren, die dann verwendet werden? ===
<span style="color:green"> JA; Die Lösung existiert auch schon. Es wird im before-script die Variable MLTutor_INPUT_ANSWERS gesetzt. Dies ist eine Zelle, die Strings der zu setzenden Werte enthält. Es muss allerdings die Reihenfolge der Abfrage vorgegeben sein. Will man tatsächlich einen String setzen so ist dieser in dreifache single-quotes einzuschließen. <br> Beispiel: <nowiki> MLTutor_INPUT_ANSWERS={'[1:5]','''Kegel''','[]'}. Bitte beachtet, wie wein leerer Input einzugeben ist.</nowiki></span>
+
<span style="color:green"> JA; Die Lösung existiert auch schon. Es wird im before-script die Variable MLTutor_INPUT_ANSWERS gesetzt. Dies ist eine Zelle, die Strings der zu setzenden Werte enthält. Es muss allerdings die Reihenfolge der Abfrage vorgegeben sein. Will man tatsächlich einen String setzen so ist dieser in dreifache single-quotes einzuschließen. </span>
  +
  +
Beispiel:
  +
MLTutor_INPUT_ANSWERS={'[1:5]','''Kegel''','[]'};
  +
Bitte beachtet, wie ein leerer Input einzugeben ist (<nowiki>'[]'<\nowiki>.
   
 
=== Können wir die korrekte Handhabung von <tt>rand</tt> überprüfen? ===
 
=== Können wir die korrekte Handhabung von <tt>rand</tt> überprüfen? ===

Version vom 10. Februar 2006, 10:08 Uhr

Allgemeine Fragen und Antworten zum Adaptieren der Übungsbeispiele

Soll jedes Beispiel einer Übung ein eigenes Projekt sein? Wenn nicht sollen wir die Benennung so wie auf Angabe für Referenzprogramm übernehmen?

  • JA, jedes Beispiel als eigenes Projekt; Referenzprogramm heißt immer main.m. Das gilt nur für ein eventuell notwendiges Script. Funktionen werden gleich benannt wie in der Angabe, und ein Projekt kann mehr als eine Funktion enthalten.
    • ÄNDERUNG: Sogar jede Funktion soll ein eigenes Projekt werden. Eine Übung besteht dann aus der Aufgabe mehrere Projekte zu programmieren! Deshalb bitte merken, welche Projekte zu welcher Übung gehören!
      • Wenn in der Übung gefordert wird, eine Funktion und ein Script zu schreiben wobei in diesem Script die Funktion aufgerufen wird, da sollte ein Projekt reichen? Wenn die Funktion in einem anderen Projekt sein sollte, dann ist sie auch in einem anderen Verzeichniss. Das Script könnte dann die Funktion nur mit dem entsprechenden Pfad aufrufen...
        • Die Funktion soll trotzdem ein eigenes Projekt sein. Es wird dann im XML-File möglich sein die Abhängigkeiten zu definieren. Damit wird die Funktion, obwohl sie in einem anderen Verzeichnis ist, automatisch gefunden

Wie werden Funktionen getestet?

Es wird eine Referenzfunktion geschrieben und beide Funktionen werden aufgerufen. Danach werden die Variablen verglichen.

Ist Laden von Übungsdaten noch notwendig?

NEIN

Die Datenfiles sollen einfach im gleichen Verzeichnis wie der Matlab-File liegen. Sie werden dann automatisch an die entsprechende Stelle kopiert damit der Test funktioniert.

Wie werden Variablen gesetzt?

  • ENTWEDER es wird ganz klar gefordert welche Werte den Variablen zugewiesen werden müssen,
  • ODER es werden Variablen im Praescript definiert und in der Angabe wird mitgeteilt, dass diese Variablen existieren.


Kann man beim Ausführen eines Skriptes input umgehen bzw. Werte vordefinieren, die dann verwendet werden?

JA; Die Lösung existiert auch schon. Es wird im before-script die Variable MLTutor_INPUT_ANSWERS gesetzt. Dies ist eine Zelle, die Strings der zu setzenden Werte enthält. Es muss allerdings die Reihenfolge der Abfrage vorgegeben sein. Will man tatsächlich einen String setzen so ist dieser in dreifache single-quotes einzuschließen.

Beispiel:

MLTutor_INPUT_ANSWERS={'[1:5]',Kegel,'[]'};

Bitte beachtet, wie ein leerer Input einzugeben ist ('[]'<\nowiki>. === Können wir die korrekte Handhabung von <tt>rand</tt> überprüfen? === <span style="color:green"> JA, vor dem Ausführen muss der SEED des Zufallszahlengenerators gesetzt werden. Dazu existiert die Variable <tt> MLTutor_RANDOM_SEED </tt>. Das Setzen des SEEDS erfolgt im before-Skript durch den Aufruf von <tt> rand('state',MLTutor_RANDOM_SEED) </tt>. Wichtig ist, dass danach die Reihenfolge in der Variablen erzeugt werden vorgegeben wird und AUF ALLE FÄLLE einzuhalten ist. </span> === Was passiert wenn jemand "clear all" in seinem Script stehen hat? Ist ja ansich lobenswert wenn man es verwendet, nur wird dann die Initialisierung durch ml_test1_before Beispiele: .m gelöscht. === <span style="color:green"> Naja, ich sehe das als Fehler des Benutzers, da er ja weiß dass Variablen vorgegeben werden. <br> Eine andere Möglichkeit wäre das aufmerksam machen des Benutzers auf seinen Fehler. Muss man noch entscheiden..</span> Kein Problem. Alle kritischen Aktionen des Benutzers (Studenten) werden abgefangen. Na ja, das Problem ist Folgendes: Ich habe jetzt clear abgefangen, wenn etwas von den Studenten laufen kann. Damit beschütze ich auch meine Infrastruktur von MLTutor-Variablen. Damit läuft aber u.U. ein Programm im Testbetieb, das ausserhalb nicht laufen würde. Ich sehe dafür aber jetzt keine bessere Lösung. In der Variablen MLTutor_CLEAR_COUNT wird mitgezählt wie oft clear aufgerufen wird. Man kann es in den Test aufnehmen, dann bekommt man einen Fehler, wenn clear verwendet wird, weil MLTutor_CLEAR_COUNT dann nicht Null ist. === Soll die Abgabe generel mit Regulären Ausdrücken überprüft werden? Etwa wenn etwas ohne for Schleifen programmiert werden sollte. === <span style="color:green"> Nein, es gibt einen Punkt in der XML-Datei, die zum Test gehört, wo man einfach angibt, welche Funktionen der Benutzer nicht verwenden darf. Wenn du kompliziertere Tests des Script schreiben willst, könnte man natürlich in ml_test?_after.m eine Variable ausrechnen und diese mit ml_test?_check.m überprüfen </span> === Wie wird das mit der [[LaTeX]]-Angabe geregelt? (Referenzen, Kurzbefehle die für das Skriptum definiert wurden...)=== <span style="color:green"> Es existiert ein Projekt <tt> kernbich.testbeispiele.shorts.de </tt> in dem hilfreiche Kurzbefehle definiert sind. Dieses kann am Beginn eines Dokuments folgendermaßen eingebunden werden: </span> \documentclass[12pt,a4paper]{article} \input{../kernbich.testbeispiele.shorts.de/shorts} <span style="color:green"> Wobei der Pfad zum Projekt (hier ..) jeweils angepasst werden muss. Diese Angabe hier sollte aber funktionieren, wenn sich alle Projekte im gleichen Workspace befinden. </span> === Überprüfung ob eine Funktion eine Fehlermitteilung produziert. === <span style="color:green"> Im before- oder after-Skript wird definiert ob die gesamte Fehlermitteilung einer Vorgabe entsprechen soll, oder ob es genügt, dass sie eine gewisse Zeichenfolge enthält. Im after-script wird anschließend die Variable MLTutor_ERROR_CORRECT abgefragt. Diese ist 1 wenn die Fehlermitteilungen die gewünschten Kriterien erfüllt.</span> Weitere Möglichkeiten gibt es auch unter [[#Regular Expressions bei Fehlern]]. % func.m function [x,y] = func(t) if nargin < 1; error('time vector is undefined'); end x = t; y = t.^2; % ml_test1_before.m % request an exact error message MLTutor_ERROR_REQUEST.message = 'time vector is undefined'; MLTutor_ERROR_REQUEST.type = 'e'; % alternative 'n' means - not exact %MLTutor_ERROR_REQUEST.message = 'time vector'; %MLTutor_ERROR_REQUEST.type = 'n'; % ml_test1_check.m MLTutor_ERROR_CORRECT % ml_test1_after.m func() Das Gleiche funktioniert nicht nur für message sondern auch für identifier: MLTutor_ERROR_REQUEST.message MLTutor_ERROR_REQUEST.type mit der Antwort in MLTutor_ERRORID_CORRECT ==== Regular Expressions bei Fehlern ==== Darüberhinaus gibt es auch noch eine bessere Variante, die sich bei der Überprüfung der sogenannten "Regular Expressions" bedient. Man hat im simplen Fall die Möglihkeit zu schreiben MLTutor_ERROR_REGEXP.message = 'time vector is undefined'; und die Variablen MLTutor_ERROR_REGEXP_CORRECT MLTutor_ERROR_REGEXP_ALL_CORRECT wären dann entweder 1 (richtig) oder 0 (falsch). Ein Unterschied zur ersten Methode besteht aber, da man jetzt die Antwort 1 bekommt, wenn die Zeichenfolge 'time vector is undefined' genau so in der Fehlermitteilung vor kommt, auch wenn vorher oder nachher etwas anderes steht (eigentlich wie <tt>type 'n'</tt>). Um den <tt>type 'e'</tt> zu simulieren, müsste man eigentlich MLTutor_ERROR_REGEXP.message = '^time vector is undefined$'; schreiben. Das Zeichen <tt>^</tt> steht für Anfang und <tt>$</tt> steht für Ende. Details zu [http://itp.tugraz.at/matlab/techdoc/matlab_prog/ch_com15.html Regular Expressions] in Matlab geben weitere Hinweise. Einige Möglichkeiten wären MLTutor_ERROR_REGEXP.message = '^[T|t]ime'; % Time oder time am Anfang MLTutor_ERROR_REGEXP.message = {'^[T|t]ime'}; % gleich wie vorige Zeile MLTutor_ERROR_REGEXP.message = {'time', 'vector', 'undefined'}; % beliebige Reihenfolge der drei Worte MLTutor_ERROR_REGEXP.message = {'time.+vector.+undefined'}; % die drei Worte mit zumindest einem Zeichen dazwischen Bei der dritten Zeile würde, wenn alles richtig ist, MLTutor_ERROR_REGEXP_CORRECT = 1 1 1 MLTutor_ERROR_REGEXP_ALL_CORRECT = 1 sein. Wäre vector falsch oder fehlend, dann hätte man MLTutor_ERROR_REGEXP_CORRECT = 1 0 1 MLTutor_ERROR_REGEXP_ALL_CORRECT = 0 als Resultat. Die Variable <tt>MLTutor_ERROR_REGEXP_ALL_CORRECT</tt> ist somit eine endgültige Antwort, ob etwas falsch oder richtig ist. Das Ganze funktioniert auch für Error Identifier, die Variablen heissen dann MLTutor_ERROR_REGEXP.identifier MLTutor_ERRORID_REGEXP_CORRECT MLTutor_ERRORID_REGEXP_ALL_CORRECT === Überprüfung von Warnungen === Funktioniert "gleich" wie bei Fehlermitteilungen. <br> Request:<br> MLTutor_WARNING_REQUEST.message MLTutor_WARNING_REQUEST.type Überprüfung:<br> MLTutor_WARNING_CORRECT Interessiert man sich (auch) für den Idetifier der Warnung, dann kann man das gleiche mit MLTutor_WARNING_REQUEST.identifier MLTutor_WARNING_REQUEST.type mit der Antwort in MLTutor_WARNINGID_CORRECT machen. ==== Regular Expressions bei Warnungen ==== Wie bei den Fehlern gibt es auch noch eine bessere Variante, die sich bei der Überprüfung der sogenannten "Regular Expressions" bedient (siehe [[#Regular Expressions bei Fehlern]], [http://itp.tugraz.at/matlab/techdoc/matlab_prog/ch_com15.html Regular Expressions]). Die Definitions-Variablen sind jetzt einfach MLTutor_WARNING_REGEXP.message MLTutor_WARNING_REGEXP.identifier und die Lösung der Überprüfung steht in MLTutor_WARNING_REGEXP_CORRECT MLTutor_WARNING_REGEXP_ALL_CORRECT MLTutor_WARNINGID_REGEXP_CORRECT MLTutor_WARNINGID_REGEXP_ALL_CORRECT === Überprüfung von Ausgaben von disp === Funktioniert ebenfalls wie bei Fehlermitteilungen. <br> MLTutor_DISP_REQUEST.message MLTutor_DISP_REQUEST.type Überprüfung:<br> MLTutor_DISP_CORRECT Beispiel:<br> a = pi; b = [1:4]; disp(['Variable a: ',num2str(a)]) disp(['Variable b: ',mat2str(b)]) disp(a) disp(b) MLTutor_DISP_REQUEST.message = { ... ['Variable a: ',num2str(a)], ... ['Variable b: ',mat2str(b)], ... a, ... b ... }; MLTutor_DISP_REQUEST.type = {'e','e','e','e'}; Die Anweisung für <tt>MLTutor_DISP_REQUEST.message</tt> und <tt>MLTutor_DISP_REQUEST.type</tt> können in <tt>test_before</tt> oder <tt>test_after</tt> stehen. Das Problem besteht aber darin, dass man u.U. die Variablennamen nicht kennt. Wenn man z.B. den Studenten nicht anweist, dass der Variablenname <tt>a</tt> ist, dann kann man im <tt>test_after</tt> nicht <tt>num2str(a)</tt> verwenden. Ausserdem geht es bei Funktionen auch nicht, da alle internen Variablen der Funktion im <tt>test_after</tt> nicht sichtbar sind. Insgesamt empfiehlt es sich immer Strings wie <tt>['a = ',num2str(a)]</tt> zu verwenden und nicht einfach <tt>a</tt>. Bei Zahlen funktioniert, die nichtexakte Überprüfung nämlich nicht. Was immer möglich ist, ist <tt>MLTutor_DISP_RESULTS</tt>. Diese Größe enthält, das Ergebnis der Ausgabe, wobei noch keine Überprüfung durchgeführt wird. Die Überprüfung liegt dann wie bei allen anderen Variablen in den Händen von David. Damit müssen die Strings aber exakt übereinstimmen. Eine nichtexakte Überprüfung ist da nicht möglich. ==== Regular Expressions bei disp ==== Auch bei disp (oder fprintf) kann man jetzt [http://itp.tugraz.at/matlab/techdoc/matlab_prog/ch_com15.html Regular Expressions] (siehe auch [[#Regular Expressions bei Fehlern]]) verwenden. Auch hier ist vorausgesetzt, dass man die Variablen <tt>a</tt> und <tt>b</tt> im after-Skript kennt: astr = num2str(a); astr = strrep(astr(1:5),'.','\.'); bstr = mat2str(b); bstr=strrep(bstr,'[','\['); bstr=strrep(bstr,']','\]'); MLTutor_DISP_REGEXP = { ... {'Variable\s+a\s*[:|-]',astr}, ... {'Variable','b:',bstr}, ... {astr}, ... {b}, ... }; Beim ersten Ergebnis wird überprüft, ob die Antwort besteht aus dem Wort Variable zumindest einem Whitespace-Character (z.B. Leerzeichen) \s+ dem Buchstaben a beliebig vielen Whitespace-Characters (auch Null) \s* einem Doppelpunkt oder einem Bindestrich [:|-] und dann, ob das Ergebnis von a vorkommt, und zwar die ersten fünf Zeichen, wobei . durch \. ersetzt wurde Bei der zweiten Zeile wird überprüft, ob die Antwort besteht aus dem Wort Variable der Kombination b: dem Ergebnis von mat2str(b), wobei [ durch \[ und ] durch \] ersetzt wurde Bei der dritten Zeile wieder astr aus num2str mit dem Dezimalpunkt ersetzt Bei der vierten Zeile b hier erfolgt automatisch eine Umwandlung mit num2str(b). Dies funktioniert klaglos aber nur, weil b ein Zeilenvektor aus Integerzahlen ist. Im Prinzip ist das keine gute Idee, viel besser ist die Überprüfung, wenn die Variablen schon vorher in Strings umgewandelt wurden. Die Ergebnisse stehen dann in MLTutor_DISP_REGEXP_CORRECT MLTutor_DISP_REGEXP_ALL_CORRECT MLTutor_DISP_REGEXP_REALALL_CORRECT wobei <tt>MLTutor_DISP_REGEXP_ALL_CORRECT</tt> für jedes disp 0 oder 1 enthält und das Gesamtergebnis in <tt>MLTutor_DISP_REGEXP_REALALL_CORRECT</tt> steht. ==== Zählen von disp-Aufrufen ==== Der Zähler für die Aufrufe von disp ist MLTutor_DISP_COUNT Damit kann man feststellen, wie oft die Funktion disp oder fprintf (mit fid 1 oder 2) aufgerufen wurde. === Haben wir eine Möglichkeit Plots zu vergleichen? === <span style="color:green">JA; Es funktioniert ähnlich wie das Testen von Fehlermeldungen. Im before-script wird mit Hilfe von MLTutor_GRAPHICS_REQUEST festgelegt, welche Eigenschaften des Plots überprüft werden sollen. Darin kann jedes Element das im [http://itp.tugraz.at/matlab/techdoc/infotool/hgprop/doc_frame.html Handle Graphics Property Browser] zu finden ist überprüft werden. Die Numerierung (siehe Beispiel) in der Anforderung der Ergebnisse ergibt sich aus der Reihenfolge in der die Objekte im Plot erzeugt werden. Somit muss diese in der Angabe zu einem Projekt fix vorgegeben sein. Beispiele: </span> * <span style="color:green"> siehe unten </span> * <span style="color:green"> kernbich.testbeispiele.sgraph* </span> <pre> % main.m x = -2:0.1:3; g1 = normpdf(x,0,1); g2 = normpdf(x,1,0.5); plot(x,g1,x,g2,'r'); %line1 & line2 hold on plot(x,g1+g2,'k'); %line 3 hold off line(x,g1-g2,'color','green'); %draw line in current axes without the use of hold on .... hold off xlabel('x'); ylabel('y'); title('Just an example') % end main.m </pre> <pre> % ml_test1_before.m % check properties of axes MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.request = {'xlabel','ylabel','title'}; % check data of line 1 (g1) MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_1.request = {'xdata','ydata'}; % check data and color of line 2 (g2) MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_2.request = {'xdata','ydata','color'}; % check data and color of line 3 (g1 + g2) MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_3.request = {'xdata','ydata','color'}; % check data and color of line 4 (g1 - g2) MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_4.request = {'xdata','ydata','color'}; </pre> <pre> % ml_test1_check.m MLTutor_GRAPHICS_RESULTS </pre> <pre> % ml_test1_after.m % nothing to do </pre> ==== Eigenheiten bei <nowiki>errorbar ==== Bei errorbar und bei anderen Befehlen, welche die neuen Gruppierungsfeatures von Matlab verwenden, gibt es das Problem, dass die Reihenfolge der Linien nicht so ist wie erwartet.

x = linspace(0,pi,100)
y = sin(x);
xd = x(1:5:end);
yd = sin(xd);
y1 = cos(x);
yd1 = cos(xd);

sig = 0.2;
rd = rand(size(xd))*sig

figure
plot(x,y,'r-')

hold on
errorbar(xd,yd,rd,'ob')
plot(x,y1,'k-')
errorbar(xd,yd1,rd,'og')
hold off

legend({'Fit1','Data1','Fit2','Data2'},'Location','sw')

Normalerweise würde man erwarten, dass

MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_1.request = {'xdata','ydata','color'};   % sin(x)
MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_2.request = {'xdata','ydata','color'};   % sin(xd)
MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_3.request = {'xdata','ydata','color'};   % Fehler zu sin(xd)
MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_4.request = {'xdata','ydata','color'};   % cos(x)
MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_5.request = {'xdata','ydata','color'};   % cos(xd)
MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_6.request = {'xdata','ydata','color'};   % Fehler zu cos(xd)

liefert. In der Realität ist die Reihenfolge aber

MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_1.request = {'xdata','ydata','color'};   % Fehler zu sin(xd) - Erste hggroup
MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_2.request = {'xdata','ydata','color'};   % sin(xd) - Erste hggroup
MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_3.request = {'xdata','ydata','color'};   % Fehler zu cos(xd) - Zweite hggroup
MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_4.request = {'xdata','ydata','color'};   % cos(xd) - Zweite hggroup
MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_5.request = {'xdata','ydata','color'};   % sin(x) - Erster Plotbefehl
MLTutor_GRAPHICS_REQUEST.figure_1.axes_1.line_6.request = {'xdata','ydata','color'};   % cos(x) - Zeiter Plotbefehl

Seid also bitte vorsichtig, welche Linien ihr überprüft. Ich habe keine Möglichkeit, dass zu korrigieren, jedenfalls nicht mit vertretbarem Aufwand.

Legende

Beim Befehl legend gibt es eine neue Syntax:

legend({'Fit1','Data1','Fit2','Data2'},'Location','nw')

Es ist gut wenn man die Liste der Beschriftung jetzt in einer Zelle {} schreibt und dann den Ort in der neuen Syntax. Siehe dazu legend.

Will man auch Fehler in der Legende ehen, dann muss man obiges Beispiel so ändern:

figure
lh1 = plot(x,y,'r-')

hold on
ebh1 = errorbar(xd,yd,rd,'ob') % hggroup
ebh1_ch = get(ebh1,'children');
lh2 = plot(x,y1,'k-')
ebh2 = errorbar(xd,yd1,rd,'og') % hggroup
ebh2_ch = get(ebh2,'children');
hold off

legend([lh1;ebh1_ch;lh2;ebh2_ch],{'Fit1','Data1','Fehler1','Fit2','Data2','Fehler2'},'Location','sw')

Dazu muss man die Handles auf alle gewünschten Graphikobjekte verwenden und daraus einen Vektor formen. Die Handles ebh1 und ebh2 sind Handles auf hggroup und man muss daher zuerst auch noch ihre Kinder (children) abfragen.

Polarplot

Der Befehl polar funktioniert wie erwartet. De extra Linien, die den Polarplot schmücken (Kreise, radiale Linien) sind alle versteckt (hidden) und machen daher keine Probleme. Die Abfrage nach den Linien geht daher wunderbar und es gibt auch kein Problem mir der Reihenfolge.

Figure

Während der Tests werden für figure noninteger-Handles verwendet. Daher sieht man, auch wenn man es z.B. mit figure(1) versucht keine Zeichnung mit dem Handle 1 sondern mit einem anderen Handle. Daher funktioniert auf keinen Fall:

figure(1);
set(1,'Color','red')

Will man so etwas, muss man schreiben

fh=figure;
set(fh,'Color','red')

Ein anfänglicher Fehler sollte mit einem Update behoben sein.

Wie wird dem Benutzer der Testaufruf der Funktion mitgeteilt?

Alles was in einem Script von %### eingeschlossen ist, ist dem Benutzer zugänglich.

 %ml_test1_after.m
 %###
 t = linspace(0,10,100)
 [x,y] = foo(t,[],4)
 %###

 test_size = size(x);

Hier sieht der Benutzer also, welche Werte t zugewiesen werden, und wie die Funktion foo aufgerufen wird. Er sieht allerdings nicht, dass anschließend auch ncoh eine Variable test_size erzeugt wird.

Beispiel2

Projektverzeichnissname: andrej.sommer2005.aufgabe2a
Weis nicht ob es so gedacht war, aber jedenfalls die erste aufgabe mit Testscript:

Nur eine Anmerkung: Das Überprüfen des Ergebnisses vom Studenten übernimmt das MLTutor-Programm, aber im Prinzip läuft es genau so ab, wie du es geschrieben hast. Wenn du selber die Überprüfung übernehmen willst, dann kannst du natürlich gerne deine eigene Routine schreiben, aber im ml_test1_check.m würde bei diesem Test nur

V2,F2,R2,r2 

drinnenstehen, damit das Programm weiß, welche Variablen überprüft werden sollten. Im XML-File, dass man dazu erstellt, kann man dann definieren, mit welcher Genauigkeit der Check abläuft und ähnliches. --Camhy 15:39, 3 Nov 2005 (CET)

Ich bin total dagegen, dass jemand eigene Überprüfungsroutinen schreibt. Das gehört total zum mlTutor und hat überhaupt nichts mit den Beispielen selbst zu tun. Bitte unbedingt nur die Syntax von David verwenden. Wenn irgendetaws für den gewünschten Test nicht ausreicht, dann unbedingt als Anregung an David und mich leiten. Dann müssen wir uns auf Seite des mlTutor darum kümmern. --Winny 16:40, 8 Nov 2005 (CET)

Die Variablen würden dann beim Scriptausführen als Text ausgegeben werden um vom ml_tutor weiterverarbeitet zu werden? Habe das Beispiel jatzt umgeschrieben: --Golubkov 13:03, 10 November 2005 (CET)

Nein, der MLTutor muss nur wissen, welche Variablen überprüft werden sollen. Dh. es soll wirklich wie oben nur z.B.

V2,F2,R2,r2 

drinnenstehen, od. ähnliches. z.B. würde ich in diesem Fall aus dieser for Schleife mit typ einfach mehrere Tests machen, da ja unterschiedliche Eigenschaften der vom Studenten geschriebenen Funktion überprüft werden. Die StudentIn soll ja wissen, bei welchem Typ es funktioniert und bei welchem nicht. Diese Syntax wurde nur deswegen gleich gewählt wie eine Ausgabe, um das Testen ohne fertigen MLTutor leichter zu machen. In den Beispielen camhy.testbeispiele.* ist es eh vorgeführt. Siehe auch Erstellen eines MLTutor Beispiels mit Eclipse. Von der technischen Seite läuft es dann so ab, dass der MLTutor aus dieser Datei herausliest, welche Variablen überprüft werden sollen, dann die Variablen als XML aus Matlab ausgibt, dieses XML von der MLTutor Oberfläche geparst wird und mit dem Ergebnis der StudentIn verglichen wird. Mit einer Ausgabe als Text wäre das Parsen komplexerer Datentypen wie Structures od. Cells, die aus verschachtelten Matrizen bestehen nicht möglich. --Camhy 13:19, 11 November 2005 (CET)


main.m

function [V,F,R,r]=main(typ,a)

switch lower(typ(1))
     case 't'
		V=a^3/12*sqrt(2);
		F=a^2*sqrt(3);
		R=a/4*sqrt(6);
		r=a/12*sqrt(6);
     case 'w'
		V=a^3;
		F=6*a^2;
		R=a/2*sqrt(3);
		r=a/2;
	case 'o'
		V=a^3/3*sqrt(2);
		F=2*a^2*sqrt(3);
		R=a/2*sqrt(2);
		r=a/6*sqrt(6);
	case 'd'
		V=a^3/4*(15+7*sqrt(5));
		F=3*a^2*sqrt(5*(5+2*sqrt(5)));
		R=a/4*(1+sqrt(5))*sqrt(3);
		r=a/4*sqrt((50+22*sqrt(5))/5);
	case 'i'
		V=5*a^3/12*(3+sqrt(5));
		F=5*a^2*sqrt(3);
		R=a/4*sqrt(2*(5+sqrt(5)));
		r=a/2*sqrt((7+3*sqrt(5))/6);
end

ml_test1_after.m

typ = {'t','w','o','d','i'};
a=2;
[V,F,R,r] = regpol(typ(1),a);

ml_test2_after.m

ptyp = {'t','w','o','d','i'};
a=[1:10];
[V,F,R,r] = regpol(typ(2),a);

ml_test3_after.m

typ = {'t','w','o','d','i'};
a=4;
[V,F,R,r] = regpol(typ(3),a);

ml_test4_after.m

typ = {'t','w','o','d','i'};
a=2;
[V,F,R,r] = regpol(typ(4),a);

ml_test5_after.m

typ = {'T','w','O','d','I'};
a=3;
[V,F,R,r] = regpol(typ(5),a);

Als Referenz müsste nun ml_tutor hier statt regpol auch mal main einsetzen. War das so gedacht?

Nein, du kannst die Funktion nennen, wie du willst, nur bei Skriptbeispielen muss das Hauptskript main.m heißen, damit das Programm weiß, welches das Hauptskript ist. Generell muss der Student alle *.m Dateien schreiben, die nicht mit ml_ beginnen. Siehe Erstellen eines MLTutor Beispiels mit Eclipse. Dort gibt es auch ein Funktionsbeispiel. camhy.testbeispiele.function1 In der MLTutor-Oberfläche gibt es mittlerweile auch einen Menüpunkt, der das richtige "Layout" eines Beispiels überprüft. Macht zwar noch ein paar Schwierigkeiten, aber diese sind mittlerweile behoben und stehen am Montag allen zur Verfügung. --Camhy 16:39, 17 November 2005 (CET)


ml_test1_check.m

V,F,R,r

Mit ml_test1_check.m bis ml_test5_check.m sind identisch.

Dokumentation

document.tex: Entsprechendes pdf
Statt \matref habe ich vorerst einfach matref stehen gelassen, bis sich eine Lösung für die definierten Kurzbefehle findet.

\documentclass[12pt,a4paper]{article}
\usepackage[german,english]{babel}
\usepackage[latin1]{inputenc}
\usepackage{palatino}
\usepackage{verbatim}
\usepackage{typearea}
\usepackage{graphicx}
\usepackage[usenames]{color}
\usepackage{ifthen}
\usepackage{longtable} 
\usepackage{makeidx} 
\usepackage{float}
\usepackage{alltt}
\usepackage{amsmath,amssymb,amsthm}
\usepackage[colorlinks,breaklinks,backref,pdfstartview=FitH]{hyperref}
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt}
\usepackage[top=1mm,left=5mm,right=0mm,bottom=5mm]{geometry}
\pagestyle{empty} 
\newcommand{\bsp}{\vspace{1em}\hrulefill\\[1em]\underline{Anschauungsbeispiel:}\\[0.5em]}
\newcommand{\zus}{\vspace{1em}\hrulefill\\[1em]\underline{Zusammenfassung:}\\[0.5em]}
\newcommand{\hw}{\vspace{1em}\underline{Hinweis:}\\[0.5em]}
\newcommand{\geg}{Gegeben: }
\newcommand{\ges}{Gesucht: }
\newcommand{\ii}{\textrm{i}}
\newcommand{\define}{\stackrel{\textrm{\tiny def}}{=}}
\newcommand{\field}[1]{\mathbb{#1}}
\newcommand{\R}{\field{R}}
\newcommand{\corrs}{\stackrel{\textrm{\tiny $\wedge$}}{=}}

\begin{document}
\section{Aufgabe}
Schreiben Sie eine \verb°regpol.m°, die folgende Aufgaben
erfüllt:
\begin{enumerate}
\item Für eine vorgegebene Kantenlänge $a$ soll das Volumen $V$, die
	Oberfläche $F$, der Radius der umbeschriebenen Kugel $R$ und der Radius der
	einbeschriebenen Kugel $r$ wahlweise für einen der 5 regulären konvexen
	Polyeder (Tetraeder, Würfel, Oktaeder, Dodekaeder, Ikosaeder) berechnet werden.
\item Mit der String-Variablen {\tt typ} soll der Typ des regulären Polyeders
	übergeben werden. Verwenden sie die Buchstaben 't','w','o','d' bzw. 'i' um einen der Polyeder auszuwählen.
\item Das Programm soll für einen Vektor von $a$-Werten funktionieren und
	gleichlange Vektoren mit den Resultaten für $V$, $F$, $R$ und $r$
	zurückgeben. 
\item Im Programm soll zur Unterscheidung der Fälle die 
	matref{switch}{switch}-Konstruktion verwendet werden:
	\begin{verbatim}
	  switch lower(typ(1))
	     case 't'
	        ...
	     case 'w'
	        ...
	     ...
	  end
	\end{verbatim}
	Überlegen Sie, welche Zeichenkette man als {\tt typ} eingeben kann, was {\tt
	  typ(1)}  bewirkt, und was
	der Befehl matref{lower}{lower} dabei bewirkt.
\item
	Stellen Sie auch den Unterschied zwischen folgenden Aufrufen der
	Funktion fest und versuchen Sie das Verhalten zu verstehen.
	\begin{verbatim}
	  regpol(typ,a)
	  V = regpol(typ,a)
	  [V,F] = regpol(typ,a)
	  [V,F,R] = regpol(typ,a)
	  [V,F,R,r] = regpol(typ,a)
	\end{verbatim}
\end{enumerate}


\section{Mathematische Grundlagen}
\begin{enumerate}
  \item Tetraeder
    \begin{align*}
      &V = \frac{a^3}{12} \sqrt{2} 
      &F = a^2 \sqrt{3} \\
      &R = \frac{a}{4} \sqrt{6} 
      &r = \frac{a}{12} \sqrt{6} 
    \end{align*}
  \item Würfel
    \begin{align*}
      &V = a^3 
      &F = 6a^2 \\
      &R = \frac{a}{2} \sqrt{3} 
      &r = \frac{a}{2} 
    \end{align*}
  \item Oktaeder
    \begin{align*}
      &V = \frac{a^3}{3} \sqrt{2} 
      &F = 2a^2 \sqrt{3} \\
      &R = \frac{a}{2} \sqrt{2} 
      &r = \frac{a}{6} \sqrt{6} 
    \end{align*}
  \item Dodekaeder
    \begin{align*}
      &V = \frac{a^3}{4} \left(15 + 7\sqrt{5}\right) 
      &F = 3a^2 \sqrt{5\left(5 + 2\sqrt{5}\right) } \\
      &R = \frac{a}{4} \left( 1 + \sqrt{5} \right) \sqrt{3} 
      &r = \frac{a}{4} \sqrt{ \frac{50 + 22\sqrt{5}}{5} } 
    \end{align*}
  \item Ikosaeder
    \begin{align*}
      &V = \frac{5a^3}{12} \left(3 + \sqrt{5}\right) 
      &F = 5a^2 \sqrt{3} \\
      &R = \frac{a}{4} \sqrt{ 2 \left( 5 + \sqrt{5} \right) } 
      &r = \frac{a}{2} \sqrt{ \frac{7 + 3\sqrt{5}}{6} } 
    \end{align*}
\end{enumerate}


\ges Funktion \verb°regpol.m° mit Inputparametern: Polyeder-typ \verb°typ° und Polyeder-kantenlänge \verb°a°.
Rückgabewerte: Kantenlänge \verb°a°, Volumen \verb°V°, Oberfläche \verb°F°, 
Radius der umbeschriebenen Kugel \verb°R°, Radius der einbeschriebenen Kugel \verb°r°

\bsp
\begin{verbatim}
[V,F,R,r] = regpol('w',3)
V = 27
F = 54
R = 2.5981
r = 1.5000

\end{verbatim}

\end{document}