Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this questionI keep getting an exception in thread "main":
java.lang.ArithmeticException: / by zero
at PersonalityTest.percentage(PersonalityTest.java:85)
at PersonalityTest.main(PersonalityTest.java:19)
And I want to add the count every time the scanner reads A or B and get the percentage of B.
import java.io.*;
import java.util.*;
public class PersonalityTest {
public static final int dimen = 4;
public static void main(String [] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("personality.txt"));
PrintStream out = new PrintStream(new File("output.txt"));
int[] a = new int[4];
int[] b = new int[4];
welcome();
while (input.hasNextLine()) {
String letter = letter(input, out);
countNum(a, b, out, letter);
int[] percentage = percentage(a, b, out);
type(out, percentage);
out.println("");
}
}
public static void welcome () {
System.out.println("The Keirsey Temperament Sorter is a test that measures four independent dimensions of your personality: ");
System.out.println("1. Extrovert versus Introvert (E vs. I): what energizes you");
System.out.println("2. Sensation versus iNtuition (S vs. N): what you focus on");
System.out.println("3. Thinking versus Feeling (T vs. F): how you interpret what you focus on");
System.out.println("4. Judging versus Perceiving (J vs. P): how you approach life");
System.out.println("");
}
public static String letter (Scanner input, PrintStream out) {
String name = input.nextLine();
out.println(name + ":");
String letter = input.nextLine();
return letter;
}
public static void countNum(int[] a, int[] b, PrintStream out, String letter) {
int[] countA = new int[7];
int[] countB = new int[7];
int n = 0;
out.print("answers: [");
for (int i = 0; i < letter.length(); i++) {
int type = i % 7;
if (letter.charAt(i) == 'A' || letter.charAt(i) == 'a') {
n = 1;
}
else if (letter.charAt(i) == 'B' || letter.charAt(i) == 'b') {
n = 1;
}
countA[type] += n;
countB[type] += n;
if (type == 2 || type == 4 || type == 6) {
a[type / 2] = countA[type - 1]+ countA[type];
b[type / 2] = countB[type - 1]+ countA[type];
} else if (type == 0) {
a[0] = countA[0];
b[0] = countB[0];
}
for (int j = 0; j < dimen; j++) {
out.print(a[j] + "A-" + b[j] + "B," + " ");
}
}
out.print("]");
}
public static int[] percentage (int[] a, int[] b, PrintStream out) {
int[] percentage = new int [4];
out.print("percent B: [");
double n = 0.0;
for (int i = 0; i < dimen; i++) {
n = b[i] * 100 / (a[i] + b[i]); // <--- This is where I get error
percentage [i] = (int) Math.round(n);
out.print(percentage[i]);
}
out.print("]");
return percentage;
}
public static void type (PrintStream out, int[] percentage) {
String[] type = new String [4];
out.print("type: ");
for (int i = 0; i <= dimen; i++) {
while (percentage[i] > 50) {
if (i == 0) {
type[1] = "I";
}
else if (i == 1) {
type[2] = "N";
}
else if (i == 2) {
type[3] = "F";
}
else {
type[4] = "P";
}
}
while (percentage[i] < 50) {
if (i == 0) {
type[1] = "E";
}
else if (i == 1) {
type[2] = "S";
}
else if (i == 2) {
type[3] = "T";
}
else {
type[4] = "J";
}
}
out.print(Arrays.toString(type));
}
}
}
Your logic is very difficult to follow with all the a, b, +1, -1, /2, etc. You should try to reduce it to the smallest amount of code that demonstrates your problem. Odds are that you'll find the problem while you're doing that. You might also provide some sample input. Without one or both of these, it's very difficult to help with your problem.
Update: I'm seeing a number of things that look like problems now that I see what you're trying to do. Unless I'm mistaken, your input file has a name on the first line followed by 70 lines, each with a single letter on them?
For one thing, when read a letter and send it into countNum(), you only have one variable called "n" that you increment whether you see an A or a B, and then you add "n" to both A and B. That's not adding one to either the number of A's or the number of B's. It will always add one to both of them.
Next, since you only send a single letter into countNum(), the outer for loop will only execute one time. That means you'll only ever put a value into a[0] and b[0]. Further, because of the "n" problem, both values will always be 1. Thus the one time you get to the inner for loop, it will always print "1A-1B, 0A-0B, 0A-0B, 0A-0B" for the first part of the answer.
After that, it should be obvious why your percentage() method doesn't work. All but the first position of the array have zeroes in them.
Additional stuff: You define a constant "dimen" equal to 4 but you sometimes use the constant and sometimes use a literal "4". Pick one and stick with it. I'd recommend the constant, and I'd recommend naming it something meaningful, like "NUMBER_OF_PERSONALITY_DIMENSIONS", if that's what it is. For that matter, give all of your variables better names, and it will make things easier for you and me both. Also, in your type() method, you say for ( int i = 0; i <= dimen; i++ ) {
to iterate over an array which I think only has 4 elements. That's going to break. Finally, as you kind of mentioned elsewhere, don't pass arrays around, mutating them in multiple different methods. That's a good way to get lost. In general, make methods non-side-effecty. Instead of modifying the things you pass to them, return the important values from the method.
In general, I think you need to take a break and straighten out in your head what you're trying to do. The logic doesn't seem to make any sense.
I don't know if you've learned about this kind of thing yet, but you might consider splitting this into two classes: one to read in the data and one to tally it up. The tallying one might look something like:
class Tallier {
private int numberOfAs;
private int numberOfBs;
private int totalEntriesSoFar;
private int[] typeATotals;
private int[] typeBTotals;
public void gotNewA() {...}
public void gotNewB() {...}
}
You are dividing by zero, the problem is that. On the mentioned line, you have:
n = b[ i ] * 100 / ( a[ i ] + b[ i ] );
Sometimes, a[i]+b[i] is zero. Maybe the problem will be solved by a check like this:
for( int i = 0; i < dimen; i++ ) {
if (a[ i ] + b[ i ]!= 0)
n = b[ i ] * 100 / ( a[ i ] + b[ i ] );
else
//assign a number to n for this situation
percentage [ i ] = ( int ) Math.round( n );
out.print( percentage[ i ] );
}
But logically, you should not divide a number by zero. Then maybe you have to correct your algorithm.
精彩评论