Graded Quiz Challenge

Hello all, this is my first post in the forums! I have worked through this book (which I love so far, it’s a beautiful tool) and didn’t have any misunderstanding until I came across this challenge.

I created two array lists(correct answers and incorrect answers) through which the user’s answer would be appended to the list in the form of a tally.

private ListCorrect = new ArrayList<>();
private ListIncorrect = new ArrayList<>();

Each correct answer would add a tally to the “correct answers” array and an incorrect answer would add a tally to the “incorrect answers” array, then I created a new method called “check percent” that should be able to compare the two arrays and return the result of the arithmetic.

if (userPressedTrue == answerIsTrue) {
messageResId = R.string.correct_toast;
Correct.add(1);
} else {
messageResId = R.string.incorrect_toast;
Incorrect.add(1);
}

public int sum_correct; {
    int sum = 0;

    for (int i : Correct)
        sum = sum + i;
}

public int sum_incorrect; {
    int sum = 0;

    for (int i : Incorrect)
        sum = sum + i;
}

public void checkPercent() {
    if (sum_correct + sum_incorrect == 6) {
        int percent_correct = (sum_correct / 6) * 100;
    }

    Toast.makeText(this, R.string.score_toast, Toast.LENGTH_LONG).show();

I then created a string resource called “score_toast” that is supposed to show the percentage correct in decimal format:

Score: %1$d percent.

There are no apparent bugs in my code but the proper percentage does not show up in the toast nor does the toast display at the end of the program.

Is this a legitimate way to go about this problem and I’m making some small mistake, or is there a completely different, more efficient way to solve this and I’m missing it completely?

Thanks in advanced.

There are a few bugs in this code:

  • It looks like you intended to create sum_correct and sum_incorrect as methods which read your Correct and Incorrect lists. Instead, you made them fields which are never set. The block of code following each one is an initializer block, which runs whenever an instance of this class is created. The result of this block of code is absolutely nothing, because the local variable sum falls out of scope immediately after you’re done counting the empty list.

  • When dividing two ints, the result will be an int. As a result, (sum_correct / 6) will always be either 1 (if the player got a perfect score) or 0 (if the player missed at least one question), and multiplying this by 100 will give either 0 or 100. What you probably meant would be written as (sum_correct * 100) / 6.

  • Toast.makeText does not look for recently declared int variables in the surrounding code, especially ones that have already fallen out of scope. To get the percentage to display in the toast, you would need to use the multiple argument version of getString, and pass the resulting string as the second argument to Toast.makeText.

  • The toast is set to display whenever checkPercent() is called, whether the user has answered all 6 questions or not. If the toast does not display at the end of the program, that also means you aren’t calling checkPercent() from anywhere.

In addition, some stylistic considerations:

  • The fields Correct and Incorrect should be lowercase. Only classes and interfaces should begin with a capital letter.

  • Creating a list just to keep a tally is needlessly complicated. It is much simpler to keep the count in an int and increment it when appropriate.

  • The number 6 should not be hard coded. Since this is meant to be the number of questions, mQuestionBank.length would better express what you want, and would always be correct even if the code is later updated to have more, fewer, or a variable number of questions.

1 Like

Thank you for your response. Your explanations were helpful and thorough, and I was able to solve the problem by changing the following to my code:

  1. I removed the tally-holding lists and counted the correct answers within two variables: correct and incorrect which were set to 0.
  2. I changed the way these variables are counted:

if (userPressedTrue == answerIsTrue) {
messageResId = R.string.correct_toast;
correct = (correct + 1);
} else {
messageResId = R.string.incorrect_toast;
incorrect = (incorrect + 1);

  1. I changed the checkPercent() method in the way that you described and then called the method at the very end of the checkAnswer() method:

private void checkPercent() {
if (mQuestionBank.length == correct + incorrect) {
int percent_correct = (correct *100) / mQuestionBank.length;
Toast.makeText(this, this.getString(R.string.score_toast,percent_correct), Toast.LENGTH_LONG).show();
}
}

Now the toast displays correctly at the end of the quiz. Thanks again for the suggestions. Cheers!