CIT 591 Assignment 4: Squarelotron
Fall 2010, David Matuszek

# Purpose of this assignment

• To give you experience with unit testing and TDD (Test-Driven Design)

# General idea of the assignment

Anita is the baby sitter of Baron Von Hauser’s kids. Von Hauser is a famous physics professor, so the Von Hauser kids have weird toys, all of which Anita has to master to be able to effectively entertain the kids.

While Anita was cleaning the bathtub she found a new toy, a Squarelotron game. It is extremely weird, and posses a lot of mathematical symmetry. She is determined to understand this new toy, otherwise she won´t be able to play with Von Hauser’s kids. However the complexity of such an extreme toy makes it difficult to play.

A Squarelotron consist basically of a matrix of numbers. This matrix can be decomposed as square rings which can rotate independently in 4 different ways: Upside-Down (↕), Left-Right (↔), through the Main Inverse Diagonal (↙), and through the Main Diagonal (↘).

For example, consider the following Squarelotrons. Squarelotron a) has 2 rings. The outer ring contains the numbers 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 16, while the inner ring contains the numbers 6, 7, 10, 11.

Squarelotron b) has two rings and a center piece. The outer ring contains the numbers 1, 2, 3, 4, 5, 6, 10, 11, 15, 16, 21, 25, 22, 19, 24, 20, while the inner ring contains 7, 8, 9, 12, 14, 17, 18, 23. The number 13 is by itself in the center.

A Upside-Down Flip of the outer ring of Squarelotron a) yields: A Left-Right Flip of the inner ring of squarelotron b) yields: A Flip through the Main Inverse Diagonal of the inner ring of squarelotron a) yields: A Flip through the Main Diagonal of the outer ring of squarelotron b) yields: Anita wants you to do a program which performs the following. It will ask you whether to use a 4x4 or a 5x5 squarelotron, then print out the initial squarelotron (with the numbers in order, as in (a) above; (b) is slightly jumbled). Then the program will let you tell it which flips to perform, and it will print out the new squarelotron after each flip. Finally, the program will let you start with a new squarelotron, or quit.

# Details

Write and unit test the following functions. You should try using TDD, Test-Driven Design, as illustrated in class:

2. Write a test for the function.
3. Run the test, and make sure it fails.
4. Add code to the function to try to make the test pass.
5. Run the test again.
1. If the test fails, debug the function (or the test) until the test passes.
2. If the test passes, continue.
6. Is the function complete (does it do everything it should do)?
1. If the function isn't complete, add code to the test to check the new functionality. Go to step 3.
2. If the function is complete, you are done with this function.

As before, follow the specifications exactly, because we will also be using my unit tests to check your work. Also as before, the design of the user interface is up to you--but the program must provide clear instructions on how to use it. As before, write a `start()` function that we can use to begin your program.

Especially if you are an experienced programmer, you may be tempted to write the functions first, and only afterwards write the unit tests. Please don't. You are in this class to learn new things, and one of the things I want you to learn is whether TDD works for you. I know it will be awkward and seems backward at first, but please give it an honest try. Who knows? You might like it.

# Functions

Notice that in both the 4x4 and the 5x5 squarelotron, there are two rings that can be flipped (the center of the 5x5 ring is immobile). In each of the following functions, the `ring` should be one of the two strings `'outer'` and `'inner'`, all lowercase, with the obvious meanings.

`make_squarelotron(list)`
returns A "squarelotron"
Given a "flat" list of either 16 or 25 numbers, make and return a squarelotron. You probably want to represent the squarelotron as a list of lists, but that's up to you: Represent it however you like. It could even be just the list given as an argument. The first 4 (or 5) numbers are the top row of the squarelotron, the next 4 (or 5) numbers are the second row, etc. You can check the length of the list to decide whether to make a 4x4 squarelotron or a 5x5 squarelotron. Calling this function should not result in any input/output.
```make_list(squarelotron) ``` returns A "flat" list of numbers
This function is the inverse of `make_squarelotron`. Given a 4x4 squarelotron, it returns a list of 16 numbers. Given a 5x5 squarelotron, it returns a list of 25 numbers. (Note: Since I have not specified how to represent your squarelotron, I will depend heavily on the `make_squarelotron` and `make_list` functions to check all the rest of your functions; so get them right!) Calling this function should not result in any input/output.
```upside_down_flip(squarelotron, ring) ``` returns A new squarelotron.
This function performs the Upside-Down Flip of the squarelotron, as described above, and returns the new squarelotron. The original squarelotron should not be modified (I will check for this). Calling this function should not result in any input/output.
```left_right_flip(squarelotron, ring) ``` returns A new squarelotron.
This function performs the Left-Right Flip of the squarelotron, as described above, and returns the new squarelotron. The original squarelotron should not be modified (I will check for this). Calling this function should not result in any input/output.
```inverse_diagonal_flip(squarelotron, ring) ``` returns A new squarelotron.
This function performs the Main Inverse Diagonal of the squarelotron, as described above, and returns the new squarelotron. The original squarelotron should not be modified (I will check for this). Calling this function should not result in any input/output.
```main_diagonal_flip(squarelotron, ring) ``` returns A new squarelotron.
This function performs the Main Diagonal Flip of the squarelotron, as described above, and returns the new squarelotron. The original squarelotron should not be modified (I will check for this). Calling this function should not result in any input/output.

Since each of the above functions has to deal with two different sizes of squarelotron, I strongly suggest that you write "helper" functions, such as (for example) `make_4x4_squarelotron` and `make_5x5_squarelotron`, to be called from the required function `make_squarelotron`.

The helper functions should also do no input/output. For each such helper function, use TDD and write unit tests first.

The functions that primarily interact with the user (and do no significant computation) do not need to be unit tested, and can do any required input/output.

# Reference

This assignment is a modified version of the problem "10016 - Flip-Flop the Squarelotron," from Online Judge.

# Due date

Thursday, October 7, before midnight. Since you are working with a partner, one of you should turn in the assignment; just make sure that both your names are in comments right at the top of the program.

Since this is a single file, it is slightly easier for us if you just turn in the unzipped `.py` file (but it's okay if you zip it).  I screwed up--the program and the test files really need to be separate. So two files, zipped together, please. Review these instructions, and turn in your assignment via Blackboard. Again let me emphasize that I do not, under any circumstances, accept assignment submissions by email.

If you turn in multiple submissions, the last one is the only one we will see at the time we download them (which will probably be Tuesday), so please be sure that this is the one you want to be graded.