# Wheel Class¶

This chapter builds on the previous two chapters, creating a more complete composite object from the Outcome and Bin classes we have already defined. We’ll introduce some basic subclass constructor techniques, also.

## Wheel Overview¶

The wheel has two responsibilities: it is a container for the Bins and it picks one Bin at random. We’ll also have to look at how to initialize the various Bins that comprise a standard Roulette wheel.

### The Container Responsibility¶

Since the Wheel is 38 Bins, it is a collection. We can review our survey of available collections in Design Decision – Choosing A Collection for some guidance here.

In this case, the choice of the winning Bin will be selected by a random numeric index. We need some kind of sequential collection.

This makes an immutable tuple very appealing. This is a subclass of collections.Sequence and has the features we’re looking for.

One consequence of using a sequential collection is that we have to choose an index for the various Bins. Each Bin contains a variety of individual Outcomes. However, each single number Outcome will be unique to each Bin.

The index values of 1 to 36 become the index to their respective Bins. The Bin at index 1 is the only bin which contains Outcome( "1", 35 ).

We have a small problem, however, with 0 and 00: we need two separate indexes. While 0 is a valid index, what do we do with 00?

Enumerate some possible solutions before reading on.

Since the index of the Bin doesn’t have any significance at all, we can assign the Bin that has the 00 Outcome to position 37 in the Vector. This gives us a unique place for all 38 Bins.

### The Random Bin Selection Responsibility¶

In order for the Wheel to select a Bin at random, we’ll need a random number from 0 to 37 that we can use an an index.

Python programmers can use the random module. This module offers a Random.choice() function which picks a random value from a sequence. This is ideal for returning a randomly selected Bin from our list of Bins.

Testability. Note that testing a class using random numbers isn’t really the best policy. To do testing properly, we’ll need to create a non-random random number generator that we can use in place of the published library random number generator.

To create a non-random random-number generator, we can so something like the following.

1. Design our Wheel to accept a Random Number Generator that in inserted by the main program. For testing a non-random generator is used. For real simulation, a proper random generator is used.
2. Create a subclass of the system-supplied random number generator. One that Override a few methods required for testing.

### Constructing a Wheel¶

Each instance of Bin has a list of Outcomes. The 0 and 00 Bin s only have two Outcome s. The other numbers have anywhere from twelve to fourteen Outcomes.

Constructing the entire collection of Bins would be a tedious undertaking. We’ll apply a common OO principle of deferred binding and work on that algorithm later, after we have the basic design for the Wheel finished.

## Wheel Design¶

class Wheel

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.

### Fields¶

Wheel.bins

Contains the individual Bin instances.

This is a tuple of 38 elements. This can be built with tuple( Bin() for i in range(38) )

Wheel.rng

The random number generator to use to select a Bin from the bins collection.

This is not always simply random.Random(). For testing, we need to inject a non-random random number generator in place of the system random number generator.

### Constructors¶

Wheel.__init__(self, rng)
Parameter: rng (random.Random) – A “random” number generator. For testing, this may be a non-random number generator.

Creates a new wheel with 38 empty Bins. It will also create a new random number generator instance.

At the present time, this does not do the full initialization of the Bins. We’ll rework this in a future exercise.

### Methods¶

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

Parameters: bin (int) – bin number, in the range zero to 37 inclusive. outcome (Outcome) – The Outcome to add to this Bin
Bin.next() → Bin

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

The Random.choice() function of the random module will select one of the available Bin s from the bins list.

Returns: A Bin selected at random from the wheel. Bin
Bin.get(bin) → Bin

Returns the given Bin from the internal collection.

Parameter: bin (int) – bin number, in the range zero to 37 inclusive. The requested Bin. Bin

## Non-Random Design¶

We need a controlled kind of random number generation for testing purposes.

We’ll define a class NonRandom that extends random.Random, but provides a more testable sequence of values. One approach is to simply return a given integer value.

### Fields¶

NonRandom.value
The non-random value to return.

### Constructors¶

NonRandom.__init__(self)
Creates a non-random “random” number generator.

### Methods¶

NonRandom.setSeed(self, value)

Saves this value as the next value to return.

Parameter: value (long) – the value to return next.
NonRandom.choice(self, sequence) → item

Use the given seed value as an index and return the requested item from the sequence.

Parameter: sequence – the sequence of values from which a random value is selected.

## Wheel Deliverables¶

There are three deliverables for this exercise. The new class and the unit test will have Javadoc comments or Python docstrings.

• The Wheel class.
• A class which performs a unit test of building the Wheel class. The unit test should create several instances of Outcome, two instances of Bin, and an instance of Wheel. The unit test should establish that Bins can be added to the Wheel.
• A Non-Random Random Number Generator class, to be used for testing.
• A class which tests the Wheel and NonRandom class by selecting values from a Wheel object.