CS 312 - Programming Project 7
Practice with: File input and output, problem decomposition, arrays

For this project you will write a program that analyzes data from a personality test called the Keirsey Temperament Sorter (http://www.keirsey.com/). Your program will be stored in the file PersonalityTest.java.

Thank you to Mike Scott for the refinements he offered on this project.

This assignment is a pair programming assignment. You may work with one other person on this project using the pair programming technique. (You are not required to work with a partner - you may work alone). Read the pair programming requirements on the course webpage carefully before beginning work on this assignment. You are allowed to work with anyone in the class - your partner does not need to be in your discussion section. If you work as part of a pair, only one solution will be submitted for the pair. Once you start the assignment, you cannot switch partners. If you do not want to work with a partner after starting the assignment, you must both complete the lab individually, and you must both email the instructor to explain why you are not completing the assignment as a pair. Failure to follow the pair programming rules (and include the neccessary additional documentation in your files) will result in significant point deductions on your project.
Failure to follow the pair programming rules may also violate the academic honesty requirements for CS 312.

This is a pair assignment. All work on this project must be done by you alone, or by you and your partner alone, with help only from the instructor, TAs, and proctors for the class.

Before you start this project, review the project guidelines on the CS 312 assignments page.

For this assignment you are limited to the language features in chapters 1 through 7 of the textbook.

As for all CS 312 projects, your file comment header should look like this:
*  author: <Your Name Here>
*  date:  <Submission Date>
*  CS 312 Assignment 7
*  On my honor, <Your Name>,  (or <Your Name>, and <Your Partner's Name>) this programming assignment is my (our) own work.
*  EID: <Your EID> (include for both partners, if applicable)
*  Section: <Unique Number>, <Thursday discussion time> (include for both partners, if applicable)
* <Brief Description - what does the program do?>
* Slip Days I am using on this project: <Your Slip Days> (for you, and your partner, if applicable)
* Slip Days I have used this semester: <Your Total, including for this project> (you and your partner, if applicable)

Background Information:
The Keirsey Temperament Sorter (http://www.keirsey.com/) is a personality test that involves answering 70 questions.  Each question has two answer choices, which we will refer to as the "A" and "B" answer.  The person taking the test is allowed to leave a question blank, in which case the answer will be recorded with a dash ("-").

The Keirsey test measures four independent dimensions of personality:
1. Extrovert versus Introvert (E vs I): what energizes you
2. Sensation versus iNtuition (S vs N): what you focus on
3. Thinking versus Feeling (T vs F): how you interpret what you focus on
4. Judging versus Perceiving (J vs P): how you approach life

Individuals are categorized as being on one side or the other for each dimension.  The corresponding letters are put together to form a personality type.  For example, if you are an Extrovert, iNtuitive, Thinking, Perceiving person then you are referred to as an ENTP.  The "A" answers correspond to E, S, T, and J (the left-hand choices above).  The "B" answers correspond to I, N, F, and P (the right-hand choices above).  For each dimension, we determine a percentage of B answers the user gave for that dimension between 0 and 100, to indicate whether the person is closer to the "A" or "B" side.

Suppose that someone's answers are as follows (These are the answers given by "Betty Boop" later in this document).
Dimension            # of "A" answers    # of "B" answers    % of "B" answers    Result
Extrovert/Introvert      1                            9                                90%                I
Sensing/iNtuition        17                          3                                15%                S
Thinking/Feeling        18                          2                                10%                T
Judging/Perceiving     18                          2                                10%                J

We add up how many of each type of answer we got for each dimension.  Then we compute the percentage of B answers for each dimension.  Then we assign letters based on which side the person ends up on for each dimension.  In the Extrovert/Introvert dimension, for example, Betty gave 9 "B" answers out of 10 total (90%), which means she is on the B side, which is "Introvert" or I.  The overall percentages are (90, 15, 10, 10) which works out to a personality type of ISTJ.

Mechanics of the Personality Test:

Suppose that "Betty Boop" gave the following answers for the 70 questions, in order from 1 to 70:

The questions are organized into 10 groups of 7 questions, with the following repeating pattern in each group:

1. The first question in each group is an Introvert/Extrovert question (questions 1, 8, 15, 22, etc).
2. The next two questions are for Sensing/iNtuition (questions 2 and 3, 9 and 10, 16 and 17, 23 and 24, etc).
3. The next two questions are for Thinking/Feeling (questions 4 and 5, 11 and 12, 18 and 19, 25 and 26, etc).
4. The next two questions are for Judging/Perceiving (questions 6 and 7, 13 and 14, 20 and 21, 27 and 28, etc).

In other words, if we consider the I/E to be dimension 1, the S/N to be dimension 2, the T/F to be dimension 3, and the J/P to be dimension 4, the map of questions to their respective dimensions would look like this:

Notice that there are half as many Introvert/Extrovert questions as there are for the other three dimensions.

Program Behavior:
Your program will process a file of Keirsey test data.  The file will contain line pairs, one per person.  The first line has the person’s name, and the second has the person's 70 answers (all "A", "B" or "-").  The "A" and "B" in the file can be upper or lowercase.  A dash represents a question that was skipped.  The format will match the following example:

 Input file: personality.txt

Betty Boop
Bugs Bunny
Daffy Duck
The frumious bandersnatch
Minnie Mouse
Luke Skywalker
Han Solo
Princess Leia

Your program begins by asking for the input and output file names.  If the input file does not exist, prompt again until a valid file name is typed.  Each pair of lines from the input file is turned into a group of lines in the output file with the name, count of As and Bs for each dimension, % Bs for each dimension (rounded to the nearest whole percent), and personality type.  You must exactly reproduce the following output format.  If the person has the same number of As and Bs for a dimension, give them an "X" (as with Han Solo).  Assume the input file has no errors and that nobody has skipped all questions for a dimension.

Log of execution (user input underlined):
Input file name: notfound.txt
File not found. Try again: foo.txt
File not found. Try again: personality.txt
Output file name: output.txt
Notice that you must re-prompt the user when an invalid input file name is entered.    

Resulting output file output.txt:

Betty Boop: [90, 15, 10, 10] = ISTJ
Snoopy: [30, 45, 30, 70] = ESTP
Bugs Bunny: [20, 45, 15, 55] = ESTP
Daffy Duck: [100, 6, 20, 6] = ISTJ
The frumious bandersnatch: [86, 95, 75, 78] = INFP
Minnie Mouse: [67, 28, 32, 5] = ISTJ
Luke Skywalker: [89, 61, 26, 25] = INTJ
Han Solo: [80, 50, 45, 25] = IXTJ
Princess Leia: [80, 50, 50, 5] = IXXJ

Implementation Guidelines:

Remember that the user might leave a question blank, in which case you will find a dash in the input file for that question.  Dash answers are not included in computing the percentages.  For example, if for one of the dimensions you have 6 A answers, 9 B answers and 5 dashes, you would compute the percentage of B answers as 9 of 15, or 60%.

You should round percentages to the nearest integer.  You can round by adding one-half and casting to an integer.  For example, if you have a variable of type double named percentage, you can find the nearest integer as follows.

     int percent = (int)(percentage + 0.5);

Or you can use the Math.round method. The trouble with this is the round method that takes a double returns a long, so you would have to cast it to an int.

    int percent =(int)Math.round( percent );

You can read the user's answers from the input file by calling nextLine(). You can use the charAt() method to get characters from this String. You will take data and transform it from one form to another a number of times: you start with a String of 70 characters, and then convert it to an array of 70 characters, and then convert that array into 2 sets of counters (one for the number of A answers in each dimension, one for the number of B answers in each dimension). Then you convert to a collection of percentages, and then convert that to a String that represents the personality type. This is quite a few steps - do each in turn! Design (a method), code, test, and repeat. Write pseudo-code, and make sure that you have clearly defined the arguments and return values for all your methods before you write any Java code for that method. Do NOT write huge amounts of code, and then try to fiddle with it to get it working.

You can assume that the input file contains no errors. The file consists of pairs of lines - the first line in each pair contains a name, and the second line in each pair contains exactly 70 characters which can each be A, B, or - (the letters can be uppercase or lowercase, or a combination). Assume that no one's answers consist of all dashes for a given dimension, since then it wouldn't be possible to determine a percentage in that case.

The sample files above give you some examples of matching input and output. We will use a much more extensive file to test your program.

Stylistic Guidelines:
You should use arrays to store the various data for each of the four dimensions of the personality test.  You should also use a class constant for the number of dimensions (4) in the personality test.  It will not be possible to change this constant and have the program function properly, but it is helpful for readability purposes.
You should have at least three methods other than main that perform some nontrivial part of the problem.  Your main method should not directly perform file input/output.

For this assignment you are limited to language features in Chapters 1 through 7 of the textbook.  Follow past stylistic guidelines about removing redundancy, using proper data types, indentation, whitespace, identifier names, localizing variables, and commenting at the beginning of your program, on each method, and on complex sections of code. You must use good programming style and use descriptive, concise comments throughout your program.

I am not telling you how to decompose the problem into methods - you will be graded on the quality of your decomposition. You should avoid redundant code. No method should be really long. Break the problem into logical sub-steps, so that someone who is reading your program can easily follow the sub-problems that each method solves, and how the overall solution is formed from your sub-steps. As always, you should use parameters to pass information from one method to another, use meaningful variable and method names, use proper indentation, use comments and whitespace to enhance readability. Each method should be immediately preceded with a comment that describes what it does, including its arguments and return values.

Did you remember to:
Complete this project on your own, or with your partner only, following the pair programming rules, if you are working as a pair?
Use meaningful variable and method names?
Add comments that describe each method, and each block of code inside a method that carries out a complex operation?
Add whitespace (blank lines) to improve readability of your code?
Submit the file PersonalityTest.java by the due date?
Email the graders (Lisa, Hang, Monique and Daniel) after program submission, if you use slip days for this project?