Skip to content

Writing Exercises :Variables

lextori edited this page Mar 13, 2012 · 14 revisions

Variables

Most mathematical problems that you generate will have some bit of randomness to them (in order to make for an interesting, not-identical, problem). You can generate these values up-front so that you can re-use them again in your problems.

To start you'll want to populate some variables inside the <div class="vars">...</div>. Variables are typically defined by using a <var>...</var> element. You'll want to specify an ID for the var as that'll be the name that you'll refer to in the future. The content of a <var>...</var> block will be executed as JavaScript, with access to to all the properties and methods provided by the JavaScript Math object, as well as all the properties and methods defined in the modules which you have included.

For example to make a variable named SPEED1 that is a number from 11 to 20 you would do:

	<!-- Random number 11 to 20. -->
	<var id="SPEED1">11 + rand(9)</var>

Since the content of <var>...</var> blocks is executed as JavaScript, you also have full access to the regular syntax of JavaScript, so you can do something slightly more complicated:

  <!-- Random number -10 to -1, 1 to 10. -->
  <var id="A">(random() > 0.5 ? -1 : 1) * (rand(9) + 1)</var>

Generating Random Numbers

If your goal is to generate a random number, there are various options; you can use random(), or one of the following methods defined in the math.js module (which should be included in all exercises):

  • randRange( min, max ) - Get a random integer in [min, max].
  • randRange( min, max, count ) - Get a random integer between min and max, inclusive. If count is specified, will return an array of random integers in the range.
  • randRangeUnique( min, max, count ) - Get an array of unique random numbers between min and max, inclusive.
  • randRangeWeighted( min, max, target, perc ) - Get a random integer between min and max, inclusive, with a perc chance of hitting target (which may or may not be in the range).
  • randRangeExclude( min, max, excludes ) - Get a random integer between min and max, inclusive, that is never any of the values in the excludes array.
  • randRangeWeightedExclude( min, max, target, perc, excludes ) - Get a random integer between min and max, inclusive, with a perc chance of hitting target (which may or may not be in the range). It will never return any of the values in the excludes array.
  • randRangeNonZero( min, max ) - Get a random integer between min and max that is never zero.
  • randFromArray( arr ) - Get a random member of arr.
  • shuffle( arr ) - Returns a copy of arr, shuffled.

Variable Reference

Inside of a <var>...</var> you can refer to other variables that you've already defined (order matters) by simply referencing their name. For example in the following we define two variables (AVG and TIME) and then multiply them together and store them in a third variable (DIST).

	<!-- Compute one value based upon two others. -->
	<var id="AVG">31 + rand(9)</var>
	<var id="TIME">1 + rand(9)</var>
	<var id="DIST">AVG * TIME</var>

Variable Constraints

If you want to make sure certain conditions are met when choosing variables, add a data-ensure attribute to the vars block. For example, if you want to choose two variables such that the first is greater than the second, you can write:

  <div class="vars" data-ensure="A > B">
      <var id="A">randRange(1, 10)</var>
      <var id="B">randRange(1, 10)</var>
  </div>

If the condition in the data-ensure block evaluates to false, the entire block will be re-evaluated until the data-ensure condition evaluates to true. Make sure the condition does not fail too often; if it does, then the variables will have to be re-chosen many times, slowing down the browser, and this is usually a sign that the variables could have been chosen more efficiently.

If only a certain subset of variables need to meet a condition, then you can use a data-ensure on a subset of variables with a div element.

<div class="vars">
    <var id="A">randRange(1, 10)</var>
    <div data-ensure="B < C">
        <var id="B">randRange(1, 10)</var>
        <var id="C">randRange(1, 10)</var>
    </div>
</div>

This is preferable to placing a data-ensure on the entire vars block when possible, since only the necessary variables will be re-evaluated.

There may also be cases where you want to make sure a certain condition is met when choosing a single variable; in this case, add a data-ensure attribute to the individual var element. For example, if you want to make sure two variables have different values, you can write:

  <div class="vars">
      <var id="A">randRange(1, 10)</var>
      <var id="B" data-ensure="A !== B">randRange(1, 10)</var>
  </div>

If you can, place data-ensure elements as deep into the tree of elements as you can; that is, avoid placing data-ensure elements on large groups of variables if it's not necessary. Not all behavior can be achieved by placing data-ensure elements on single variables (for example, choosing A and B such that A < B will produced a skewed distribution if you only place the condition only when choosing B). The idea is to have no "wasted" computation inside data-ensure elements, since all those computations must be repeated each time the data-ensure fails.

Back to Writing Exercises: Home