Problem
Sie haben Code, den Sie von mehr als einer Stelle aus aufrufen möchten, möglicherweise mit unterschiedlichen Argumenten.
Lösung
Verwenden Sie eine vom Benutzer geschriebene Funktion mit Parametern, lokalen Variablen, um sie von anderem Code fernzuhalten, und einer Return-Anweisung, um eine Antwort zurückzusenden.
// this example shows how to write a user written function to roll
// ndice with nsides
// a user written function is created with an assignment statement
// to a variable that will be the name of the function. rollDice
// seems a good name to explain what this function does.
rollDice = Function( {ndice = 2, nsides = 6}, // parameters
{i, sum = 0}, // local variables
For( i = 1, i <= ndice, i++, // loop to add up the rolls
sum += Random Integer( 1, nsides ) // one roll
); // end of the loop
Return( sum ); // value to return
); // end of the definition
// make table and distributions. the number of dice
// and the number of sides is chosen to make the
// average roll be 36
dt = New Table( "Untitled",
Add Rows( 10000 ),
// each column has a formula that calls the function...
New Column( "one", Formula( rollDice( 1, 71 ) ) ),
New Column( "two", Formula( rollDice( 2, 35 ) ) ),
New Column( "three", Formula( rollDice( 3, 23 ) ) ),
New Column( "four", Formula( rollDice( 4, 17 ) ) )
);
// check the Std Dev in the 4 reports...
// it gets smaller with more dice
dt << Distribution(
Continuous Distribution( Column( :one ) ),
Continuous Distribution( Column( :two ) ),
Continuous Distribution( Column( :three ) ),
Continuous Distribution( Column( :four ) ),
SendToReport(
Dispatch( {"one"}, "Distrib Histogram", FrameBox, {DispatchSeg( Hist Seg( 1 ), Bin Span( 24, 0 ) )} ),
Dispatch( {"two"}, "Distrib Histogram", FrameBox, {DispatchSeg( Hist Seg( 1 ), Bin Span( 24, 0 ) )} ),
Dispatch( {"three"}, "Distrib Histogram", FrameBox, {DispatchSeg( Hist Seg( 1 ), Bin Span( 24, 0 ) )} ),
Dispatch( {"four"}, "Distrib Histogram", FrameBox, {DispatchSeg( Hist Seg( 1 ), Bin Span( 24, 0 ) )} )
)
);<BR />
More dice, smaller standard deviationMore dice, smaller standard deviationMehr Würfel, kleinere Standardabweichung
Diskussion
Die Funktion Function() gibt eine Funktion zurück. Das erste Argument für Function() ist eine Liste von Parametern und ist erforderlich. Verwenden Sie {}, wenn Sie keine Parameter haben. Die Parameter können wie oben gezeigt Standardwerte haben; rollDice() verwendet zwei 6-seitige Würfel. rollDice(3) verwendet drei 6-seitige Würfel und rollDice(1,7) verwendet einen 7-seitigen Würfel.
Das zweite Argument der Funktion ist eine optionale Liste lokaler Variablen, die Anfangswerte haben können. Durch die Verwendung lokaler Werte können Sie Funktionen dazu veranlassen, andere Funktionen aufzurufen, ohne sich Gedanken über die Wiederverwendung von „i“ in einer for-Schleife machen zu müssen. Wenn Sie keine lokalen Werte angeben müssen, geben Sie den Funktionskörper einfach als zweites Argument und nicht als drittes ein.
Das letzte Argument (2. oder 3.) ist der Funktionskörper. Bei Bedarf kann es auf globale Werte verweisen. Sie können eine Return-Anweisung an einer beliebigen Stelle im Textkörper verwenden, um einen Wert anzugeben, der an den Aufrufer zurückgesendet werden soll. Wenn keine Return-Anweisung vorhanden ist, wird der Wert der zuletzt ausgeführten Anweisung zurückgegeben.
Die Funktion rollDice wird bei der ersten Definition nicht ausgeführt. Es wird ausgeführt, wenn es mit Argumenten aufgerufen wird, z
rollDice(3,6)
was das Beispiel in den Spaltenformeln tut.
Siehe auch
http://www.jmp.com/support/help/Advanced_Programming_Concepts.shtml
@Craige_Hales
FWIW, ich bin froh, dass Sie in Ihrem Beispiel die Standardwerte beibehalten haben.Ich bin auf diesen Beitrag gestoßen, als ich nach Informationen zu Function() gesucht habe, und er war sehr hilfreich!
Danke! @Juda
Ich würde wahrscheinlich eine Regel für einen fehlenden Wert erstellen und eine if-Anweisung hinzufügen, um „missing“ durch „default“ zu ersetzen. rollDice( . , 5 ); was wahrscheinlich zwei Kopien des Standardwerts in der Funktion bedeutet ...
Es gibt mehrere Gründe für die Verwendung von Standardwerten, und einige davon können manchmal schlechte Gründe sein.
- Aufrufcode kürzer machen
- Sie können die Standardeinstellung später an einer Stelle ändern
- weil die Funktion nach der ersten Veröffentlichung geändert wurde
- ?
Die Standardparameter sind wahrscheinlich nicht schneller als ihre Angabe (ungeprüfte Vermutung). Es könnte besser aussehen, wenn die Standardwerte dem entsprechen, was ein vernünftiger Codeprüfer erwarten würde. Eine spätere Änderung der Standardeinstellung kann zu Problemen führen. Es könnte nützlich sein, einen neuen Parameter für einen neuen Aufrufer hinzuzufügen und die alten Aufrufer nicht zu berühren.
Ich wünschte vielleicht, ich hätte die Standardwerte in diesem Beispiel weggelassen; Sie machen es nicht immer einfacher, dem Code zu folgen. Elektrowerkzeuge!
Danke dafür, @Craige_Hales .Beim Aufruf der rollDice-Funktion, d Gibt es eine Möglichkeit, ndice auf seinem Standardwert zu halten und nsides auf einen nicht standardmäßigen Wert zu setzen, ohne den Standardwert von ndice zu übergeben?
Zum Beispiel:
ndice = 3, nsides = 5 ==> rollDice( 3, 5 )
ndice = 3, nsides = 6 (Standardwert) ==> rollDice( 3 )
ndice = 2 (Standardwert), nsides = 5 ==> rollDice( ?? )
Natürlich könnte ndice angegeben werden ( rollDice( 2, 5 ) ), aber muss es so sein, damit ein nicht standardmäßiger Wert für nsides verwendet werden kann?