Design

We'll present the design modification for Wheel first. This will be followed by design information for NonRandom in both Java and Python.

Wheel Rework

Wheel contains the 38 individual bins on a Roulette wheel, plus a random number generator. It can select a Bin at random, simulating a spin of the Roulette wheel.

Note that we will be rewriting these methods to change their implementation. The definitions of the methods don't change, but the implementations can (and do) change. This is the real strength of OO design. Once we have a well-defined interface (defined by the public methods and attributes), we are free to change the implementation as necessary.

This kind of rework — making a fundamental change to the implementation without touching the interface — is essential to successful OO programming.

Fields

  • Java: java.util.Vector bins = new Vector( 38 );

    Python: bins = 38*[None] 

    Contains the individual Bin instances.

  • Java: java.util.Random rng = new java.util.Random();

    Python: rng = random.Random() 

    Generates the next random number, used to select a Bin from the bins collection.

Constructors

  • Wheel();

    This will also create a new random number generator instance. It will then use the other constructor to do the rest of the initialization.

  • Wheel(Random rng);

    Creates a new wheel with 38 empty Bins. It will use the given random number generator instance.

Methods

  • addOutcome(int number,
               Outcome outcome);

    Adds the given Outcome to the Bin with the given number.

  • next();

    Generates a random number between 0 and 37, and returns the randomly selected Bin.

    Java: Be sure to note that the java.util.Random nextInt method uses the size of the bins collection to return values from 0 to the size of the collection. Typically there are 38 values, numbered from 0 to 37.

    Python: the choice function will select one of the available Bins from the bins list.

  • Bin getBin(int aBin);

    Returns the given Bin from the internal collection.

Java NonRandom Class

We need a controlled kind of random number generation for testing purposes. We'll define a class NonRandom that extends java.util.Random, but provides a more testable sequence of values. One approach is to simply count through a range of integer vales.

The API documentation gives us the advice that the protected int next(int bits); generates the next pseudorandom number. It says that any subclass should override this, as this is used by all other methods.

Fields

  • int value = 0;

    This will be used to count through the non-random sequence of values.

Constructors

  • NonRandom();

    This is the default constructor, and will initialize value to zero.

  • NonRandom(long seed);

    This constructor ignores the seed value. It initializes value to zero.

Methods

  • next(int bits);

    This method is the heart of the generator. In our case, we simply add one to value and return the new value. This provides a predicable sequence of values.

Python NonRandom Class

Nonrandom module provides the same interface as random.Random, but merely counts through a range of integer vales.

The API documentation gives us the advice that a subclass should override the random(), seed(), getstate(), setstate() and jumpahead() methods. However, we can safely ignore all but the random() method itself.

Fields

  • value = 0 

    This will be used to count through the non-random sequence of values.

Constructors

  • def NonRandom(self):

    This is the default constructor, and will initialize value to zero.

  • def NonRandom(self, seed):

    This constructor ignores the seed value. It initializes value to zero.

Methods

  • def random(self):

    This method is the heart of the generator. In our case, we simply add 1 to the value and return (value % 38)/38.0 . This provides a predicable sequence of values that is suitable for our testing.

    The return value does two things. First, it computest the remainder when the value is divided by 38. This will be a value from 0 to 37. Then it divides this by 38 to return a floating-point number in the half-open range [0.0, 1.0), as required by the API. This means that 0.0 is included, but 1.0 is not included.