Problema
Hai un codice che vuoi chiamare da più di un posto, magari con argomenti diversi.
Soluzione
Utilizza una funzione scritta dall'utente, con parametri, variabili locali per tenerli lontani da altro codice e un'istruzione return per inviare una risposta.
// 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 deviationPiù dadi, minore deviazione standard
Discussione
La funzione Function() restituisce una funzione. Il primo argomento di Function() è un elenco di parametri ed è obbligatorio. Utilizza {} se non hai parametri. I parametri possono avere valori predefiniti come mostrato sopra; rollDice() utilizzerà due dadi a 6 facce. rollDice(3) utilizzerà tre dadi a 6 facce e rollDice(1,7) utilizzerà un dado a 7 facce.
Il secondo argomento di function è un elenco facoltativo di variabili locali, che possono avere valori iniziali. Usando valori locali, puoi fare in modo che le funzioni chiamino altre funzioni e non preoccuparti di riutilizzare "i" in un ciclo for. Se non è necessario specificare le variabili locali, è sufficiente inserire il corpo della funzione come secondo argomento anziché come terzo.
L'argomento finale (2° o 3°) è il corpo della funzione. Se necessario, può fare riferimento a valori globali. È possibile utilizzare un'istruzione return in qualsiasi punto del corpo per specificare un valore da inviare al chiamante. Se non è presente alcuna istruzione return, viene restituito il valore dell'ultima istruzione eseguita.
La funzione rollDice non viene eseguita quando viene definita per la prima volta. Viene eseguito quando viene chiamato con argomenti, come
rollDice(3,6)
cosa che fa l'esempio nelle formule di colonna.
Guarda anche
http://www.jmp.com/support/help/Advanced_Programming_Concepts.shtml
@Craige_Hales
FWIW, sono felice che tu abbia lasciato i valori predefiniti nel tuo esempio.Mi sono imbattuto in questo post mentre cercavo alcune informazioni su Function(), e questo è stato molto utile!
Grazie! @Giuda
Probabilmente creerei una regola per un valore mancante e aggiungerei un'istruzione if per sostituire il valore mancante con quello predefinito. rollDice( . , 5 ); il che probabilmente significa due copie del valore predefinito nella funzione...
Esistono diversi motivi per utilizzare i valori predefiniti e alcuni di essi potrebbero essere, a volte, motivi errati.
- abbreviando il codice di chiamata
- poter modificare l'impostazione predefinita in un secondo momento, in un unico posto
- perché la funzione è stata modificata dopo la prima pubblicazione
- ?
I parametri predefiniti probabilmente non sono più veloci che specificarli (ipotesi non testata). Potrebbe sembrare migliore se i valori predefiniti fossero quelli che un revisore di codice ragionevole si aspetterebbe. La modifica dell'impostazione predefinita in un secondo momento potrebbe causare danni. Potrebbe essere utile aggiungere un nuovo parametro per un nuovo chiamante e non toccare i vecchi chiamanti.
Potrei desiderare di aver lasciato i valori predefiniti fuori da questo esempio; non sempre rendono il codice più facile da seguire. Utensili elettrici!
Grazie per questo, @Craige_Hales .Quando si chiama la funzione rollDice, i Esiste un modo per mantenere ndice uguale al suo valore predefinito e impostare nsides uguale a un valore non predefinito senza passare il valore predefinito di ndice?
Per esempio:
ndice = 3, nlati = 5 ==> rollDice( 3, 5 )
ndice = 3, nsides = 6 (valore predefinito) ==> rollDice( 3 )
ndice = 2 (valore predefinito), nsides = 5 ==> rollDice( ?? )
Naturalmente, ndice potrebbe essere specificato ( rollDice( 2, 5 ) ), ma deve essere necessario per consentire l'utilizzo di un valore non predefinito per nsides?