Problema
Tiene algún código que desea llamar desde más de un lugar, tal vez con diferentes argumentos.
Solución
Utilice una función escrita por el usuario, con parámetros, variables locales para mantenerlas alejadas de otro código y una declaración de devolución para enviar una respuesta.
// 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 deviationMás dados, menor desviación estándar
Discusión
La función Function() devuelve una función. El primer argumento de Function() es una lista de parámetros y es obligatorio. Utilice {} si no tiene parámetros. Los parámetros pueden tener valores predeterminados como se muestra arriba; rollDice() utilizará dos dados de 6 caras. rollDice(3) usará tres dados de 6 caras y rollDice(1,7) usará un dado de 7 caras.
El segundo argumento para funcionar es una lista opcional de variables locales, que pueden tener valores iniciales. Al usar valores locales, puede hacer que las funciones llamen a otras funciones y no preocuparse por reutilizar "i" en un bucle for. Si no necesita especificar valores locales, simplemente coloque el cuerpo de la función como segundo argumento en lugar del tercero.
El argumento final (segundo o tercero) es el cuerpo de la función. Puede hacer referencia a valores globales si es necesario. Puede utilizar una declaración de devolución en cualquier parte del cuerpo para especificar un valor para enviarlo a la persona que llama. Si no hay una declaración de devolución, se devuelve el valor de la última declaración ejecutada.
La función rollDice no se ejecuta cuando se define por primera vez. Se ejecuta cuando se llama con argumentos, como
rollDice(3,6)
lo que hace el ejemplo en las fórmulas de la columna.
Ver también
http://www.jmp.com/support/help/Advanced_Programming_Concepts.shtml
@Craige_Hales
FWIW, me alegra que hayas dejado los valores predeterminados en tu ejemplo.Encontré esta publicación cuando estaba buscando información sobre Function(), ¡y fue muy útil!
¡Gracias! @Judá
Probablemente crearía una regla para un valor faltante y agregaría una declaración if para reemplazar el valor faltante por el valor predeterminado. tirarDados( . , 5 ); lo que probablemente significa dos copias del valor predeterminado en la función...
Hay varias razones para utilizar valores predeterminados y, en ocasiones, algunas de ellas pueden ser malas razones.
- acortar el código de llamada
- poder cambiar el valor predeterminado más tarde, en un solo lugar
- porque la función cambió después de su primera publicación.
- ?
Los parámetros predeterminados probablemente no sean más rápidos que especificarlos (suposición no probada). Puede verse mejor si los valores predeterminados son los que esperaría un revisor de código razonable. Cambiar el valor predeterminado más adelante podría dañar algo. Puede resultar útil agregar un nuevo parámetro para una nueva persona que llama y no tocar a las personas que llaman anteriormente.
Quizás desearía haber dejado los valores predeterminados fuera de este ejemplo; no siempre hacen que el código sea más fácil de seguir. ¡Herramientas eléctricas!
Gracias por esto, @Craige_Hales .Al llamar a la función rollDice, i ¿Hay alguna manera de mantener ndice igual a su valor predeterminado y establecer nsides igual a un valor no predeterminado sin pasar el valor predeterminado de ndice?
Por ejemplo:
ndice = 3, nsides = 5 ==> tirarDado( 3, 5 )
ndice = 3, nsides = 6 (valor predeterminado) ==> rollDice( 3 )
ndice = 2 (valor predeterminado), nsides = 5 ==> rollDice( ?? )
Por supuesto, se podría especificar ndice ( rollDice( 2, 5 ) ), pero ¿tiene que ser así para permitir que se utilice un valor no predeterminado para nsides?