Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript JavaScript Loops, Arrays and Objects Tracking Multiple Items with Arrays Build a Quiz Challenge, Part 2

Dan MacDonagh
Dan MacDonagh
4,615 Points

Here's what I ended up with.

I set up a quiz with three questions of my own, if you want to test it out, the correct answers are 7, idaho, honda

What do you guys think?

function print(message) {
  var outputDiv = document.getElementById('output');
  outputDiv.innerHTML += message;
}


var questions = [
  ['What is three plus four?', '7'],
  ['Where is Boise located?', 'idaho'],
  ['Who makes the Civic?', 'honda']
];

var correctAnswers = [];
var incorrectAnswers = [];

for(i = 0; i < questions.length; i++) {
  var answer = prompt(questions[i][0]);
  answer = answer.toLowerCase();
  if( answer === questions[i][1] ) {
    correctAnswers.push([questions[i][0], questions[i][1]]);
  } else {
    incorrectAnswers.push([questions[i][0], questions[i][1]]);
  }
}

function printCorrect() {
  print('<p><strong>You got ' + correctAnswers.length + ' question(s) right!</strong></p>');
  var correctHTML = '<ol>';
  for( i = 0; i < correctAnswers.length; i++ ) {
    correctHTML += '<li>' + correctAnswers[i][0] + '<ul><li>You answered ' + correctAnswers[i][1] + ', which was correct!</li></ul></li>';
  }
  correctHTML += '</ol>';
  print(correctHTML);
}

function printIncorrect() {
  var incorrectHTML = '<p><strong>You answered these questions incorrectly.</strong></p><ol>';
  for ( i = 0; i < incorrectAnswers.length; i++ ) {
    incorrectHTML += '<li>' + incorrectAnswers[i][0] + '<ul><li>The correct answer is ' + incorrectAnswers[i][1] + '</li></ul></li>';
  }
  incorrectHTML += '</ol>';
  print(incorrectHTML);
}

printCorrect();
printIncorrect();

1 Answer

Good idea with appending to the innerHTML property of the outputDiv, though if you have to change the DOM a lot, you are better of storing all of the HTML in a variable and then only changing it once, for performance reasons.

I like the fact that you're indicating what the actual answers were, and with correctly nested lists. The two functions you use to print the lists are quite similar though, so I wonder if you'd be better of rewording them both in a way that would allow you to use one function to print the list, with each list being the argument to the function when called?

Oh and you didn't use the var keyword for your loop index variable i. I'd recommend declaring it at the top, without assigning a value, and then just leaving it as you have it in your loops.

Here's my take on it:

var i;
var numCorrect = 0;
var minResponseLength = 5;
var questions = [
  ["What is the largest living land animal?", "african elephant"],
  ["What is the largest living reptile?", "saltwater crocodile"],
  ["What is the largest living fish?", "whale shark"],
  ["What is the largest living bird?", "common ostrich"],
  ["What is the tallest living animal?", "giraffe"]
];
var answeredCorrect = [];
var answeredIncorrect = [];
var html = '';

function print(message) {
  // old school
  // document.write(message);

  // new school
  var outputDiv = document.getElementById('output');
  outputDiv.innerHTML = message;
}

// create and return the HTML for an ordered list from an array
function buildOrderedList(list) {
  var listHTML = '<ol>';
  for (i=0; i<list.length; i++) {
    listHTML += '<li>' + list[i] + '</li>';
  }
  listHTML += '</ol>';
  return listHTML;
}

// a function to ask the question and return true if answered correctly
function quizQuestion(questions, questionNumber) {
  // get the user's response to the question being asked, convert to lowercase
  var response = prompt(questions[questionNumber][0]).toLowerCase();
  /* return true if the user's response exists within
     or is equal to the actual answer
     AND the response is greater than or equal to the min characters
     (so they can't cheat with a random letter or two)
     - this allows for responses that aren't the full string in the answer */
  return (
    questions[questionNumber][1].indexOf(response) >= 0
    &&
    response.length >= minResponseLength
  )
}

for (i=0; i<questions.length; i++) {
  if (quizQuestion(questions, i)) {
    numCorrect++;
    answeredCorrect.push(questions[i][0]);
  } else {
    answeredIncorrect.push(questions[i][0]);
  }
}

html += '<p>Out of ' + questions.length + ' questions, you got ' + numCorrect + ' correct and ' + (questions.length - numCorrect) + '  incorrect.</p>';
// only add the HTML for the list of correct questions if there were some
if (numCorrect > 0) {  
  html += '<h2>You got these questions correct:</h2>' + buildOrderedList(answeredCorrect);
}
// only add the HTML for the list of inccorrect questions if there were some
if (numCorrect < questions.length) {
  html += '<h2>You got these questions incorrect:</h2>' + buildOrderedList(answeredIncorrect);
}

print(html);