CIT 590 Makeup: Credit Card Checker
Spring 2009, David Matuszek

This is a makeup assignment, which I am providing because many of you are are unhappy with your grade on the Traffic assignment. However, if you do this makeup assignment, the grade you get on it will replace the lowest grade you got on any of the assignments 1 through 9. It will not be used to replace the grade on any later assignment.

Please note: If you do this assignment, the grade you get will replace the lowest grade you got on any of the assignments 1 through 9. This will be true even if you get a still lower grade on this makeup assignment. The purpose of this rule is to keep you from doing the assignment "just in case" you get a higher grade on it. We don't want to have to grade a lot of unnecessary makeup assignments.

The grade for this assignment will occur in its own column on Blackboard. We will not be changing the visible grade for the previous assignment; the actual substitution will be done when the grades are totalled.

You will not have a partner for this assignment. You will have nearly three weeks to do the assignment, in order to minimize the impact on your other assignments. If you plan to do this assignment, it would be wise not to leave it until the last minute.

Purposes of this assignment:

You are probably familiar with most of the Sun-supplied methods you will need, but it would be a good idea to look over the above-mentioned classes to be sure. You don't want to re-invent the wheel.

General idea of the assignment:

You work for a company that takes credit card orders. You have a database of credit card numbers for known customers. Unfortunately, your coworkers sometimes enter a credit card number incorrectly, and it is your job to determine which credit card number was most likely meant.

Note: Credit card numbers are sixteen digits, and do not begin with a zero. ints have a maximum of 12 digits, but longs have a maximum of 19 digits. So use longs.

Details

class CreditCardChecker extends JFrame (the GUI)

The GUI for this assignment will be particularly simple. You will need:

class NumberChecker (the "Database")

The "database" will just be an array of 1000 randomly generated long values, in the range 1000 0000 0000 0000 to 9999 9999 9999 9999.

Because it is difficult to test programs that have unpredictable results, the random number generator can be started with a seed. If you use the same seed, you will get the same sequence of "random" numbers. Also, you probably want to use many fewer numbers in your database for testing purposes. Since I also need to be able to control what numbers are in your database, please use exactly the following code:

    /**
     * Returns an array of size "random" long integers,
     * in the range 1000000000000000L to 9999999999999999L.
     * The seed parameter allows you to generate the same
     * array each time you use the same seed.
     * 
     * @param size The number of "random" long integers to generate.
     * @param seed A starting value for the random number generator.
     * @return An array of "random" 16-digit longs.
     */
     public static long[] createDatabase(int size, long seed) {
        long[] database = new long[size];
        long maximum = 9999999999999999L;
        long minimum = 1000000000000000L;
        long modulus = maximum - minimum + 1;
        Random rand = new Random(seed);
        for (int i = 0; i < size; i++) {
            database[i] = Math.abs(rand.nextLong()) % modulus + minimum;
        }
        return database;
    }

If you run the above code with a small size (say, 10) and a fixed seed, and print out the results, you will know what numbers to use in your tests.

The constructors

The NumberChecker class will have two constructors:

public NumberChecker()
This constructor creates the "real" database, the one that is used by the GUI. It will have 1000 16-digit random numbers in it.
public NumberChecker(int size, long seed)
This constructor is for creating a much smaller, known database, for testing purposes.

The methods

When you get a "number" from the text input field, trim() leading and trailing blanks from it.

Write and JUnit test the following methods:

static int countSubstitutions(String badNumber, long goodNumber)

The parameters are a 16-character "badNumber" String (assert that the String is exactly this long), and a 16 digit long "goodNumber". Turn the "goodNumber" into a 16-character String and compare the two Strings, position by position, counting the number of places where they differ (maximum of 16 places). Return this count.

static int countAfterDeletions(String badNumber, long goodNumber)

The parameters are a 17-character "badNumber" String (assert that the String is exactly this long), and a 16 digit long "goodNumber". Turn the "goodNumber" into a 16-character String.

The badNumber String has one extra character, but you don't know which one. Try deleting each one in turn, and use countSubstitutions to see which deletion gives you the best (smallest) value. Return as a result the smallest number you got from countSubstitutions, plus one for the insertion error.

static int countAfterInsertions(String badNumber, long goodNumber)

The parameters are a 15-character "badNumber" String (assert that the String is exactly this long), and a 16 digit long "goodNumber". Turn the "goodNumber" into a 16-character String.

The badNumber String one missing character, but you don't know which one was omitted--it might be the first, the last, or one in the middle. Turn your badNumber" into a 16-character String by inserting some nondigit character at each possible position, and calling countSubstitutions to see what the best (smallest) value is that you can find. Return this number, plus one for the deletion error.

static int countDifferences(String badNumber, long goodNumber)

Given a 15-, 16-, or 17-character "badNumber", use one of the above methods to count the differences between the badNumber and the goodNumber. Return the result.

long findBestMatch(String badNumber)

If the trimmed badNumber is from 15 to 17 characters long, finds and returns the closest match in the database. However, if there is more than one "best" match, the method returns the negative of the number of best matches (for example, if there is a three-way tie for best number, -3 is returned). Finally, if the parameter has fewer than 15 or more than 17 characters, return the number of characters in it.

Note: If a negative or small positive number is returned, the GUI should display an interpretation of the number (for example, 3-way tie or 14 digits) rather than the number itself.

Structure of the assignment:

The above are requirements. You may have additional classes and methods as needed, and they should be documented and unit tested as appropriate.

Due date:

Monday, April 27, before midnight, via Blackboard. No late assignments will be accepted!