0

So I'm trying to randomize the questions but i kept on failing. i tried to use this code to add but there are some issues with it. i changed currentQuestion to randomQuiz and it worked but again there are issues that needed to be fix.

var randomQuiz = Math.floor(Math.random()*quiz.length);

.js file

    var quiz = [{
      "question": "What is the full form of IP?",
      "choices": ["Internet Provider", "Internet Port", "Internet Protocol"],
      "correct": "Internet Protocol"
    }, {
      "question": "Who is the founder of Microsoft?",
      "choices": ["Bill Gates", "Steve Jobs", "Steve Wozniak"],
      "correct": "Bill Gates"
    }, {
      "question": "1 byte = ?",
      "choices": ["8 bits", "64 bits", "1024 bits"],
      "correct": "8 bits"
    }, {
      "question": "The C programming language was developed by?",
      "choices": ["Brendan Eich", "Dennis Ritchie", "Guido van Rossum"],
      "correct": "Dennis Ritchie"
    }, {
      "question": "What does CC mean in emails?",
      "choices": ["Carbon Copy", "Creative Commons", "other"],
      "correct": "Carbon Copy"
    } , {
      "question": "wsxwsxwsxwsxwsxwsx?",
      "choices": ["wsx", "edc", "qaz"],
      "correct": "wsx"
    } , {
      "question": "qazqazqazqazqazqaz?",
      "choices": ["qaz", "wsx", "edc"],
      "correct": "qaz"
    } , {
      "question": "asdasdasdasdasdasd?",
      "choices": ["asd", "qwe", "zxc"],
      "correct": "asd"
    } , {
      "question": "zxczxczxczxczxczxc?",
      "choices": ["zxc", "asd", "qwe"],
      "correct": "zxc"
    } , {
      "question": "qweqweqweqweqweqwe?",
      "choices": ["qwe", "asd", "zxc"],
      "correct": "qwe"
    }];


    // define elements
    var content = $("content"),
      questionContainer = $("question"),
      choicesContainer = $("choices"),
      scoreContainer = $("score"),
      submitBtn = $("submit");

    // init vars
    var currentQuestion = 0,
      score = 0,
      askingQuestion = true;

    function $(id) { // shortcut for document.getElementById
      return document.getElementById(id);
    }

    function askQuestion() {
      var choices = quiz[currentQuestion].choices,
        choicesHtml = "";

      // loop through choices, and create radio buttons
      for (var i = 0; i < choices.length; i++) {
        choicesHtml += "<input type='radio' name='quiz" + currentQuestion +
          "' id='choice" + (i + 1) +
          "' value='" + choices[i] + "'>" +
          " <label for='choice" + (i + 1) + "'>" + choices[i] + "</label><br>";
      }

      // load the question
      questionContainer.textContent = "Q" + (currentQuestion + 1) + ". " +
        quiz[currentQuestion].question;

      // load the choices
      choicesContainer.innerHTML = choicesHtml;

      // setup for the first time
      if (currentQuestion === 0) {
        scoreContainer.textContent = "Score: 0 right answers out of " +
          quiz.length + " possible.";
        submitBtn.textContent = "Submit Answer";
      }
    }

    function checkAnswer() {
      // are we asking a question, or proceeding to next question?
      if (askingQuestion) {
        submitBtn.textContent = "Next Question";
        askingQuestion = false;

        // determine which radio button they clicked
        var userpick,
          correctIndex,
          radios = document.getElementsByName("quiz" + currentQuestion);
        for (var i = 0; i < radios.length; i++) {
          if (radios[i].checked) { // if this radio button is checked
            userpick = radios[i].value;
          }

          // get index of correct answer
          if (radios[i].value == quiz[currentQuestion].correct) {
            correctIndex = i;
          }
        }

        // setup if they got it right, or wrong
        var labelStyle = document.getElementsByTagName("label")[correctIndex].style;
        labelStyle.fontWeight = "bold";
        if (userpick == quiz[currentQuestion].correct) {
          score++;
          labelStyle.color = "green";
        } else {
          labelStyle.color = "red";
        }

        scoreContainer.textContent = "Score: " + score + " right answers out of " +
          quiz.length + " possible.";
      } else { // move to next question
        // setting up so user can ask a question
        askingQuestion = true;
        // change button text back to "Submit Answer"
        submitBtn.textContent = "Submit Answer";
        // if we're not on last question, increase question number
        if (currentQuestion < quiz.length - 1) {
          currentQuestion++;
          askQuestion();
        } else {
          showFinalResults();
        }
      }
    }

    function showFinalResults() {
      content.innerHTML = "<h2>You've complited the quiz!</h2>" +
        "<h2>Below are your results:</h2>" +
        "<h2>" + score + " out of " + quiz.length + " questions, " +
        Math.round(score / quiz.length * 100) + "%<h2>";
    }

    window.addEventListener("load", askQuestion, false);
    submitBtn.addEventListener("click", checkAnswer, false);

.html file

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">

<meta name="robots" content="noindex">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Quiz app</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" href="quiz.css">


</head>
  <body>
    <div id="container">
      <h1>Quiz app</h1>
      <p>There will be no points awarded for unanswered questions.</p>
      <div id="content">
        <h3 id="question"></h3>
        <div id="choices"></div>
        <p><button id="submit"></button></p>
        <p id="score"></p>
      </div>
    </div>
    <script src="quiz.js"></script>


</body>
</html>
Noobie
  • 55
  • 2
  • 10

7 Answers7

2

Just shuffle the question array and pick one after the other. In a simplified version:

var questions = [1,2,3,4,5,6,7,8,9,10];

function shuffle(a) {
  var cidx, ridx,tmp;
  cidx = a.length;
  while (cidx != 0) {
    ridx = Math.floor(Math.random() * cidx);
    cidx--;
    tmp = a[cidx];
    a[cidx] = a[ridx];
    a[ridx] = tmp;
  }
  return a;
}

function* get_one(arr){
  var idx = arr.length;
  while(idx != 0)
    yield arr[idx--];
}

questions = shuffle(questions);
console.log(questions);

var nextq = get_one(questions);
var alen = questions.length -1;
while(alen--)
  console.log(nextq.next().value);

You don't need that fancy generator, you can just get one after the other in a simple loop if you prefer that.

deamentiaemundi
  • 5,502
  • 2
  • 12
  • 20
1

Depending on what you're doing at the end of the quiz, the easiest thing might be to just remove the question from the array once it's been answered.

Brent Waggoner
  • 548
  • 3
  • 14
1

I have another very small solution:

It copies the array of possible values and removes the ones, that are added to the new array.

function pickFrom(n, list) {
  const copy = Array.from(list);
  return Array.from(Array(n), () => copy.splice(Math.floor(copy.length * Math.random()), 1)[0]);
}

var quiz = [{
  "question": "What is the full form of IP?",
  "choices": ["Internet Provider", "Internet Port", "Internet Protocol"],
  "correct": "Internet Protocol"
}, {
  "question": "Who is the founder of Microsoft?",
  "choices": ["Bill Gates", "Steve Jobs", "Steve Wozniak"],
  "correct": "Bill Gates"
}, {
  "question": "1 byte = ?",
  "choices": ["8 bits", "64 bits", "1024 bits"],
  "correct": "8 bits"
}, {
  "question": "The C programming language was developed by?",
  "choices": ["Brendan Eich", "Dennis Ritchie", "Guido van Rossum"],
  "correct": "Dennis Ritchie"
}, {
  "question": "What does CC mean in emails?",
  "choices": ["Carbon Copy", "Creative Commons", "other"],
  "correct": "Carbon Copy"
}, {
  "question": "wsxwsxwsxwsxwsxwsx?",
  "choices": ["wsx", "edc", "qaz"],
  "correct": "wsx"
}, {
  "question": "qazqazqazqazqazqaz?",
  "choices": ["qaz", "wsx", "edc"],
  "correct": "qaz"
}, {
  "question": "asdasdasdasdasdasd?",
  "choices": ["asd", "qwe", "zxc"],
  "correct": "asd"
}, {
  "question": "zxczxczxczxczxczxc?",
  "choices": ["zxc", "asd", "qwe"],
  "correct": "zxc"
}, {
  "question": "qweqweqweqweqweqwe?",
  "choices": ["qwe", "asd", "zxc"],
  "correct": "qwe"
}];

console.log(pickFrom(3, quiz));

Reduced example:

function pickFrom(n, list) {
  const copy = Array.from(list);
  return Array.from(Array(n), () => copy.splice(Math.floor(copy.length * Math.random()), 1)[0]);
}

list = [1, 2, 3];

console.log("Pick 1:", pickFrom(1, list).toString());
console.log("Pick 2:", pickFrom(2, list).toString());
console.log("Pick 3:", pickFrom(3, list).toString());
console.log("Pick 3:", pickFrom(3, list).toString());
console.log("Pick 3:", pickFrom(3, list).toString());
Sebastian Speitel
  • 7,166
  • 2
  • 19
  • 38
0

You can use a array for storing question that have been asked Check array every time during randomization and then select question

var track=new Array();

while(true)//loop until Unique number
{
    var randomQuiz=Math.floor(Math.random()*quiz.length);

     if(track.indexOf(randomQuiz)==-1)//if you have got your unique random number
     {
        track.push(random);
        break;
     }
}

Edit: as Stephen P pointed out it may lead to performance issue, removing element from array is more logical thing to do as suggested by Brent Waggoner.

Code Warrior
  • 438
  • 6
  • 14
  • 1
    This is a bad idea. "loop until Unique number" has the potential to loop forever, or a least for minutes, if it keeps hitting numbers that are used. Hitting an already used number is more and more likely as you work further through the questions, so the test/quiz will get slower and slower as it goes on. Shuffle the array once, randomizing it as deamentiaemundi answers, then just step through it start to end. People often make this same mistake when trying to randomly deal from a deck of cards. – Stephen P Jan 27 '16 at 05:38
  • @StephenP so removing an element is more logical and performance friendly? as suggested by Brent Waggoner – Code Warrior Jun 11 '18 at 19:56
  • @Waggoner - If you've shuffled the array into a random order you don't have to remove elements from the array, just start at index `int i = 0` and increment `i` each time: `nextQuestion = questions[i++]` – Stephen P Jun 11 '18 at 21:32
0

You need to write some logic. Below is one sample example.

    var list = [1, 2, 3, 4, 5];
    var listDone = [];        
    var inProcess = true;
    while(inProcess){
        var randomQuiz = Math.floor(Math.random() * list.length);

        var isDone = false;
        for (var j = 0; j < listDone.length; j++) {
            if (listDone[j] === randomQuiz)
                isDone = true;
        }
        if (!isDone) {
            console.log(list[randomQuiz]);//Display if not Done.
            listDone.push(randomQuiz);
        }

        if (list.length == listDone.length)
            inProcess = false;

    }
rishikesh tadaka
  • 483
  • 1
  • 6
  • 18
0

I added a questionCounter variable to be incremented when your ask question function is called. I also changed your if then statement to use the question counter to set the text of your submit button. Live Preview: http://codepen.io/larryjoelane/pen/yeKwqO

JavaScript:

var questionCounter = 0;

var quiz = [{
  "question": "What is the full form of IP?",
  "choices": ["Internet Provider", "Internet Port", "Internet Protocol"],
  "correct": "Internet Protocol"
}, {
  "question": "Who is the founder of Microsoft?",
  "choices": ["Bill Gates", "Steve Jobs", "Steve Wozniak"],
  "correct": "Bill Gates"
}, {
  "question": "1 byte = ?",
  "choices": ["8 bits", "64 bits", "1024 bits"],
  "correct": "8 bits"
}, {
  "question": "The C programming language was developed by?",
  "choices": ["Brendan Eich", "Dennis Ritchie", "Guido van Rossum"],
  "correct": "Dennis Ritchie"
}, {
  "question": "What does CC mean in emails?",
  "choices": ["Carbon Copy", "Creative Commons", "other"],
  "correct": "Carbon Copy"
}, {
  "question": "wsxwsxwsxwsxwsxwsx?",
  "choices": ["wsx", "edc", "qaz"],
  "correct": "wsx"
}, {
  "question": "qazqazqazqazqazqaz?",
  "choices": ["qaz", "wsx", "edc"],
  "correct": "qaz"
}, {
  "question": "asdasdasdasdasdasd?",
  "choices": ["asd", "qwe", "zxc"],
  "correct": "asd"
}, {
  "question": "zxczxczxczxczxczxc?",
  "choices": ["zxc", "asd", "qwe"],
  "correct": "zxc"
}, {
  "question": "qweqweqweqweqweqwe?",
  "choices": ["qwe", "asd", "zxc"],
  "correct": "qwe"
}];

var currentQuestion = Math.floor(Math.random() * quiz.length);



// define elements
var content = $("content"),
  questionContainer = $("question"),
  choicesContainer = $("choices"),
  scoreContainer = $("score"),
  submitBtn = $("submit");


  score = 0,
  askingQuestion = true;

function $(id) { // shortcut for document.getElementById
  return document.getElementById(id);
}

function askQuestion() {

 //increment the counter
    questionCounter++;

  var choices = quiz[currentQuestion].choices,
    choicesHtml = "";

  // loop through choices, and create radio buttons
  for (var i = 0; i < choices.length; i++) {
    choicesHtml += "<input type='radio' name='quiz" + currentQuestion +
      "' id='choice" + (i + 1) +
      "' value='" + choices[i] + "'>" +
      " <label for='choice" + (i + 1) + "'>" + choices[i] + "</label><br>";
  }

  // load the question
  questionContainer.textContent = "Q" + (questionCounter) + ". " +
    quiz[currentQuestion].question;

  // load the choices
  choicesContainer.innerHTML = choicesHtml;

  // setup for the first time
  if (questionCounter === 1) {
    scoreContainer.textContent = "Score: 0 right answers out of " +
      quiz.length + " possible.";
    submitBtn.textContent = "Submit Answer";


  }

}

function checkAnswer() {




  // are we asking a question, or proceeding to next question?
  if (askingQuestion) {
    submitBtn.textContent = "Next Question";
    askingQuestion = false;

    // determine which radio button they clicked
    var userpick,
      correctIndex,
      radios = document.getElementsByName("quiz" + currentQuestion);
    for (var i = 0; i < radios.length; i++) {
      if (radios[i].checked) { // if this radio button is checked
        userpick = radios[i].value;
      }

      // get index of correct answer
      if (radios[i].value == quiz[currentQuestion].correct) {
        correctIndex = i;
      }
    }

    // setup if they got it right, or wrong
    var labelStyle = document.getElementsByTagName("label")[correctIndex].style;
    labelStyle.fontWeight = "bold";
    if (userpick == quiz[currentQuestion].correct) {
      score++;
      labelStyle.color = "green";
    } else {
      labelStyle.color = "red";
    }

    scoreContainer.textContent = "Score: " + score + " right answers out of " +
      quiz.length + " possible.";
  } else { // move to next question
    // setting up so user can ask a question
    askingQuestion = true;
    // change button text back to "Submit Answer"
    submitBtn.textContent = "Submit Answer";
    // if we're not on last question, increase question number
    if (currentQuestion < quiz.length - 1) {
      currentQuestion++;
      askQuestion();
    } else {
      showFinalResults();
    }
  }
}

function showFinalResults() {
  content.innerHTML = "<h2>You've complited the quiz!</h2>" +
    "<h2>Below are your results:</h2>" +
    "<h2>" + score + " out of " + quiz.length + " questions, " +
    Math.round(score / quiz.length * 100) + "%<h2>";
}

window.addEventListener("load", askQuestion, false);
submitBtn.addEventListener("click", checkAnswer, false);
Larry Lane
  • 2,141
  • 1
  • 12
  • 18
0

I'd just shuffle this list - then take the first x questions:

var shuffled = quiz.map(x => { return {data: x, srt: Math.random()}})
.sort((a,b) => {return a.srt - b.srt})
.map(x => x.data);
PaulB
  • 23,264
  • 14
  • 56
  • 75