Problème
Vous souhaitez appeler du code depuis plusieurs endroits, peut-être avec des arguments différents.
Solution
Utilisez une fonction écrite par l'utilisateur, avec des paramètres, des variables locales pour les éloigner des autres codes et une instruction return pour renvoyer une réponse.
// 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 deviationPlus de dés, plus petit écart type
Discussion
La fonction Function() renvoie une fonction. Le premier argument de Function() est une liste de paramètres et est obligatoire. Utilisez {} si vous n'avez aucun paramètre. Les paramètres peuvent avoir des valeurs par défaut comme indiqué ci-dessus ; rollDice() utilisera deux dés à 6 faces. rollDice(3) utilisera trois dés à 6 faces et rollDice(1,7) utilise un dé à 7 faces.
Le deuxième argument de la fonction est une liste facultative de variables locales, qui peuvent avoir des valeurs initiales. En utilisant des valeurs locales, vous pouvez demander à des fonctions d'appeler d'autres fonctions sans vous soucier de la réutilisation de "i" dans une boucle for. Si vous n'avez pas besoin de spécifier de paramètres locaux, placez simplement le corps de la fonction comme deuxième argument plutôt que comme troisième.
Le dernier argument (2e ou 3e) est le corps de la fonction. Il peut référencer des valeurs globales si nécessaire. Vous pouvez utiliser une instruction return n'importe où dans le corps pour spécifier une valeur à renvoyer à l'appelant. S'il n'y a pas d'instruction return, la valeur de la dernière instruction exécutée est renvoyée.
La fonction rollDice n'est pas exécutée lors de sa première définition. Il est exécuté lorsqu'il est appelé avec des arguments, comme
rollDice(3,6)
ce que fait l'exemple dans les formules de colonnes.
Voir également
http://www.jmp.com/support/help/Advanced_Programming_Concepts.shtml
@Craige_Hales
FWIW, je suis heureux que vous ayez laissé les valeurs par défaut dans votre exemple.Je suis tombé sur ce post alors que je cherchais des informations sur Function(), et cela a été très utile !
Merci! @Juda
Je ferais probablement une règle pour une valeur manquante et ajouterais une instruction if pour remplacer manquant par défaut. rollDice( . , 5 ); ce qui signifie probablement deux copies de la valeur par défaut dans la fonction...
Il existe plusieurs raisons d’utiliser des valeurs par défaut, et certaines d’entre elles peuvent parfois être de mauvaises raisons.
- rendre le code d'appel plus court
- pouvoir modifier la valeur par défaut plus tard, en un seul endroit
- parce que la fonction a été modifiée après sa première publication
- ?
Les paramètres par défaut ne sont probablement pas plus rapides que leur spécification (estimation non testée.) Cela peut sembler meilleur si les valeurs par défaut correspondent à ce qu'un réviseur de code raisonnable s'attendrait. Changer la valeur par défaut ultérieurement pourrait casser quelque chose. Ajouter un nouveau paramètre pour un nouvel appelant et ne pas toucher aux anciens appelants peut être utile.
J'aurais peut-être souhaité laisser les valeurs par défaut en dehors de cet exemple ; ils ne rendent pas toujours le code plus facile à suivre. Outils électroportatifs!
Merci pour cela, @Craige_Hales .Lors de l'appel de la fonction rollDice, je Existe-t-il un moyen de conserver ndice égal à sa valeur par défaut et de définir nsides sur une valeur autre que celle par défaut sans transmettre la valeur par défaut de ndice ?
Par exemple:
ndice = 3, nsides = 5 ==> rollDice( 3, 5 )
ndice = 3, nsides = 6 (valeur par défaut) ==> rollDice( 3 )
ndice = 2 (valeur par défaut), nsides = 5 ==> rollDice( ?? )
Bien sûr, ndice pourrait être spécifié ( rollDice( 2, 5 ) ), mais doit-il l'être pour autoriser l'utilisation d'une valeur autre que celle par défaut pour nsides ?