How2pass.com Forums
Randomize Multiple Choice Questions - Printable Version

+- How2pass.com Forums (https://www.how2pass.com/forum)
+-- Forum: CCNP (https://www.how2pass.com/forum/forum-6.html)
+--- Forum: CCNP ENARSI 300-410 Forum (https://www.how2pass.com/forum/forum-15.html)
+--- Thread: Randomize Multiple Choice Questions (/thread-2379.html)



Randomize Multiple Choice Questions - jupertino - 09-08-2024

Hi everyone, so I had a problem - I found that I was memorizing the position of the answer, rather than the answer itself. As a result, I'd like to share a script I made that randomizes order of the answers in the multiple choice questions. You'll need to download a chrome plugin to use it, and I never encourage anyone to copy code off of the internet without reading it manually first. Please read the code for yourself, it's very short. 

This script does the following:

It selects all elements with the class quesContainer, which corresponds to your question containers.
For each question, it selects all <p> elements, which contain the answer options.
It shuffles the order of these options.
Finally, it re-appends the shuffled options back to the question container.

1. Install the Tampermonkey extension for Chrome (if you haven't already).
2. Open Tampermonkey in Chrome and create a new script.
3. paste the script (after you've vetted it) into the script editor.
4. Save the script.
5. Go to chrome://extensions/ and click "developer mode" on the top right in order to enable script injection. Mine didn't work until I did this. 

Script is below:
---------------------------------------------------------------------------------------------------------------------------------------

// ==UserScript==
// @name         Improved Randomize Multiple Choice Options for How2Pass
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  Randomize the order of multiple choice options for How2Pass website with improved logging
// @match        https://www.how2pass.com/emembers/enarsi410/onlinetest/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    let hasRun = false;

    function shuffleArray(array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
    }

    function randomizeOptions() {
        if (hasRun) {
            console.log("Script has already run once, skipping...");
            return;
        }

        console.log("Starting randomization process...");
        const questions = document.querySelectorAll('.quesContainer');
        console.log(`Found ${questions.length} questions`);

        questions.forEach((question, index) => {
            const options = Array.from(question.querySelectorAll('p > label.black'));
            console.log(`Question ${index + 1} has ${options.length} options`);

            if (options.length > 0) {
                const optionsContainer = options[0].parentNode.parentNode;
                const originalOrder = options.map(opt => opt.textContent.trim());
                console.log(`Original order for Q${index + 1}:`, originalOrder);

                shuffleArray(options);
                options.forEach(option => optionsContainer.appendChild(option.parentNode));

                const newOrder = Array.from(question.querySelectorAll('p > label.black')).map(opt => opt.textContent.trim());
                console.log(`New order for Q${index + 1}:`, newOrder);

                if (JSON.stringify(originalOrder) !== JSON.stringify(newOrder)) {
                    console.log(`Question ${index + 1} options were successfully randomized`);
                } else {
                    console.log(`Warning: Question ${index + 1} options remained in the same order`);
                }
            } else {
                console.log(`No options found for question ${index + 1}`);
            }
        });

        console.log("Randomization process complete");
        hasRun = true;
    }

    // Wait for the page to load and then run the script
    window.addEventListener('load', function() {
        console.log("Page loaded, waiting 3 seconds before randomizing...");
        setTimeout(randomizeOptions, 3000);
    });
})();

---------------------------------------------------------------------------------------------------------------------------------------

Line-by-Line Explanation of the Multiple-Choice Randomizer Script

---------------------------------------------------------------------------------------------------------------------------------------
[align=left]// ==UserScript==
// @name         Improved Randomize Multiple Choice Options for How2Pass
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  Randomize the order of multiple choice options for How2Pass website with improved logging
// @match        https://www.how2pass.com/emembers/enarsi410/onlinetest/*
// @grant        none
// ==/UserScript==
---------------------------------------------------------------------------------------------------------------------------------------
This is the metadata block for Tampermonkey. It defines the script's name, version, description, and which websites it should run on.

---------------------------------------------------------------------------------------------------------------------------------------
(function() {
    'use strict';
---------------------------------------------------------------------------------------------------------------------------------------
This creates an Immediately Invoked Function Expression (IIFE) to avoid polluting the global scope. 'use strict' enables strict mode for better error catching.

---------------------------------------------------------------------------------------------------------------------------------------
let hasRun = false;
---------------------------------------------------------------------------------------------------------------------------------------
This variable keeps track of whether the script has already run to prevent multiple executions.

---------------------------------------------------------------------------------------------------------------------------------------
function shuffleArray(array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
    }
---------------------------------------------------------------------------------------------------------------------------------------
This function implements the Fisher-Yates shuffle algorithm to randomize the order of elements in an array.

---------------------------------------------------------------------------------------------------------------------------------------
function randomizeOptions() {
        if (hasRun) {
            console.log("Script has already run once, skipping...");
            return;
        }
---------------------------------------------------------------------------------------------------------------------------------------
This is the main function that randomizes the options. It first checks if the script has already run to avoid repeated randomization.

---------------------------------------------------------------------------------------------------------------------------------------
console.log("Starting randomization process...");
        const questions = document.querySelectorAll('.quesContainer');
        console.log(`Found ${questions.length} questions`);
---------------------------------------------------------------------------------------------------------------------------------------
This logs the start of the process and finds all question containers on the page.

---------------------------------------------------------------------------------------------------------------------------------------
questions.forEach((question, index) => {
            const options = Array.from(question.querySelectorAll('p > label.black'));
            console.log(`Question ${index + 1} has ${options.length} options`);
---------------------------------------------------------------------------------------------------------------------------------------
For each question, this finds all the answer options and logs how many there are.

---------------------------------------------------------------------------------------------------------------------------------------
if (options.length > 0) {
                const optionsContainer = options[0].parentNode.parentNode;
                const originalOrder = options.map(opt => opt.textContent.trim());
                console.log(`Original order for Q${index + 1}:`, originalOrder);
---------------------------------------------------------------------------------------------------------------------------------------
If options are found, it stores the original order for logging purposes.

---------------------------------------------------------------------------------------------------------------------------------------
shuffleArray(options);
                options.forEach(option => optionsContainer.appendChild(option.parentNode));
---------------------------------------------------------------------------------------------------------------------------------------
This shuffles the options and reappends them to the container, effectively randomizing their order.

---------------------------------------------------------------------------------------------------------------------------------------
const newOrder = Array.from(question.querySelectorAll('p > label.black')).map(opt => opt.textContent.trim());
                console.log(`New order for Q${index + 1}:`, newOrder);
---------------------------------------------------------------------------------------------------------------------------------------
This logs the new order of options after randomization.

---------------------------------------------------------------------------------------------------------------------------------------
if (JSON.stringify(originalOrder) !== JSON.stringify(newOrder)) {
                    console.log(`Question ${index + 1} options were successfully randomized`);
                } else {
                    console.log(`Warning: Question ${index + 1} options remained in the same order`);
                }
---------------------------------------------------------------------------------------------------------------------------------------
This checks if the order actually changed and logs the result.

---------------------------------------------------------------------------------------------------------------------------------------
} else {
                console.log(`No options found for question ${index + 1}`);
            }
        });
---------------------------------------------------------------------------------------------------------------------------------------
If no options were found for a question, this logs a message.

---------------------------------------------------------------------------------------------------------------------------------------
console.log("Randomization process complete");
        hasRun = true;
    }
---------------------------------------------------------------------------------------------------------------------------------------
This logs the completion of the process and sets the hasRun flag to true.

---------------------------------------------------------------------------------------------------------------------------------------
window.addEventListener('load', function() {
        console.log("Page loaded, waiting 3 seconds before randomizing...");
        setTimeout(randomizeOptions, 3000);
    });
})();
---------------------------------------------------------------------------------------------------------------------------------------
This adds an event listener to run the randomization function 3 seconds after the page has fully loaded and closes the IIFE.
---------------------------------------------------------------------------------------------------------------------------------------



Let me know if you have any questions. I hope this helps anyone else!