Sequence Strategy

For this assignment you will add code to an existing program which illustrates the strategy design pattern. As defined on this page, to use the strategy pattern we do the following:

The Sequence Class

The Sequence class is the “client” in the definition above. This is a flexible class that can be used to generate sequences of numbers in different ways. With a Sequence object you can get the next item in the sequence, get the current position in the sequence, and seek to a new position in the sequence. The class stores the numbers that have been generated so far in a list so that it can re-use those numbers after seeking backwards, but new numbers are generated when continually calling get_next() past the point where the sequence has been generated so far.

This class could be useful in a number of different programs. For example, in a video game you might generate a level in a random fashion, so you may need an unbounded sequence of random numbers. If the player dies in the level, you could re-use the same sequence of random numbers when they try again by seeking back to the beginning of the sequence. After seeking to the beginning, you will get the same sequence of numbers as you did before, and if the player gets farther in the level it will continue to generate more new numbers.

With this class, you can generate more than random numbers in a sequence, you just have to use a different generator for the numbers.

Abstract Base Class ItemGenerator

We want to have different kinds of Sequence objects which generate different kids of sequences. The only thing that differs among these different kinds of Sequence objects is the generator from which they get their numbers.

To accomplish this I created an ItemGenerator abstract base class which has a single method, get_next(). The Sequence class takes a ItemGenerator object in its initializer, stores it as an attribute, and uses this generator to get the values for the sequence. ItemGenerator is the abstract interface in the Strategy definition above.

We can say that a Sequence is composed of an ItemGenerator. Or that a Sequence has an ItemGenerator. We are leveraging polymorphism because we can pass in any concrete (non-abstract) ItemGenerator object to the Sequence constructor.

Here our family of algorithms are item generators. They are all interchangeable because they have all extend the same abstract base class (ItemGenerator), and thus have the same interface. The client using these algorithms is the Sequence class. We can create new kinds of sequence objects without changing the code of the Sequence class at all, we simply pass a different ItemGenerator object to the constructor to get different behavior.

From the perspective of the Sequence class, the implementation details of each separate number generator are irrelevant. As long as a Sequence object can call get_next() on the generator it is happy.

Existing Code

In sequence.py there are already two concrete implementations of ItemGenerator called OrderedIntGenerator and RandomIntGenerator. OrderedIntGenerator generates the sequence of increasing non-negative integers starting with 0 (0, 1, 2, 3, …). RandomIntGenerator generates a random sequence of integers within a given range.

Examine the Sequence class and the ItemGenerator classes and be sure you understand what is going on. You may want to read these instructions multiple times once you have looked at the code! For this assignment, understanding the relationships between these classes is as important as the code you will add.

main.py contains code to test sequences. These are not automated tests to run with pytest, but rather interactive tests. If you run main.py you will be presented with an interactive testing environment where you can try out sequences with the two existing generators. Play around with this a little so that you see what is going on with the sequences.

New ItemGenerator Class

Your task for this assignment is to create one more class in sequence.py named FromListGenerator. This class must extend ItemGenerator. Additionally you will add an object from your class to the generators list in main() so that you can test it with the interactive testing environment.

FromListGenerator

The FromListGenerator draws its numbers from a list, in order. Once all the numbers from the list have been used, it starts over from the beginning. So if we construct the object like this:

FromListGenerator([1, 2, 3])

and we pass this object to the initializer of a Sequence, then the sequence generated will look like this:

1, 2, 3, 1, 2, 3, 1, ...

You will need to keep track of the current position in the list as an attribute and update it accordingly when new items are generated.

There is a commented out line in the generators list in main() that adds a FromListGenerator object to the test list. Uncomment this line after you have created your class, and import FromListGenerator from the sequence module. Then re-run main.py so you can test your class.

Submission

Test your class to make sure it works and then push your submission. For full credit on this assignment your code must pass all the tests and be PEP 8 complient.