4

I'm new to GoogleAppsScript and now making quizzes in google form and spreadsheet by using GAS.

I want to shuffle items in a MultipleChoiceItem when the google form is reloaded.

A part of my current scirpt, slightly modified form this code, is presented below.

//vars from spreadsheet
var form = FormApp.openById(id);
var ss = SpreadsheetApp.openById(question_bank_ID);
var text = sheet.getSheetValues(questions[i]+1, 2, 1, 1)[0][0];
var options = sheet.getSheetValues(questions[i]+1, 5, 1, 5)[0];
var ans = sheet2.getSheetValues(questions[i]+1, 5, 1, 5)[0];

//MultipleChoiceItem
var mc = form.addMultipleChoiceItem().setTitle(text);
        mc.setPoints(1) // set point 
         // add choices with isCorrect
        while (options[options.length - 1] === "") {
          options.pop();
        }
        mc.setChoices(options.map(function (options, i) {
          return mc.createChoice(options, ans[i]);
        }
                                 )
                      )

Could someone please tell me a solution? Thanks for your help!

  • "when the google form is reloaded" Do you mean when the editor version of the form is reloaded or when a user is refreshing the Form URL he received? The first is possible, the second not without the first one. – ziganotschka Feb 07 '20 at 14:18
  • Thanks for your reply! I hope to implement the second one in order to give each user (student) the same qiuz with different order of questions and choices. setShuffleQuestions() might be for randomizing question, but I couldn't find the similar function for shuffling items. – user3065296 Feb 08 '20 at 01:16
  • Unfortunately a similar method for shuffling items does not exist. I updated my answer with the best workaround I could come up with. – ziganotschka Feb 10 '20 at 10:00
  • 1
    I see. I'll try alternative solution you mentioned. Thank you so much for helping! – user3065296 Feb 12 '20 at 03:23
  • 1
    Thank you for taking the time to answer my question. Now, I use Moodle, a learning management system, in place of google forms for making tests with randomized items from quiz bank. Thanks again for your help. – user3065296 Jan 05 '22 at 02:19
  • By releasing Google Forms API on March 16, 2022, your goal can be directly achieved using it. [Ref](https://workspaceupdates.googleblog.com/2022/03/google-forms-api-generally-available.html) You can see the sample script at https://stackoverflow.com/a/71745819 – Tanaike Apr 05 '22 at 02:55

2 Answers2

2
  • In order to shuffle your values each time your form is reloaded, you need to bind to your form a script with an onOpen trigger
  • Retrieve all questions and for each question retrieve the choices
  • Use a shuffle function to randomize the choices
  • Assign the shuffled choices back to the question

Sample:

function onOpen(){
  form = FormApp.getActiveForm();
  var questions = form.getItems();
  for (var i =0; i < questions.length; i++){
    var question = questions[i];
    var choices = question.asMultipleChoiceItem().getChoices();
    var newChoices = shuffle(choices);
    question.asMultipleChoiceItem().setChoices(newChoices);
  }

}


function shuffle(array) {
  for (var i = array.length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}

UPDATE:

If you want to give to every user the same quiz but with randomized questions, there is no direct way to do it - so far there is no method of the kind setShuffleItems. All you can do for the moment is a workaround, e.g. you can bind to the sample above an installable time-driven trigger which would shuffle the items in desired intervals (the minimum is one minute). This does not guarantee that each user will see a different quiz, but at least each minute the quiz will be different.

ziganotschka
  • 25,866
  • 2
  • 16
  • 33
1

As explained there is no direct answer to this, which is rather surprising considering there is an option to Shuffle option order via the front end interface. (see here)

To me, the proposals of triggering reshuffles every 1 minute are too inefficient and it does not ensure that the order will change for each user. In my opinion, a less bad approach (though not a solution) would be to manually create a MultipleChoiceItem that has the Shuffle option order checked, then duplicate the MultipleChoiceItem, rather than create a new one.

You would need to have some hard-coded reference such as get the ID for the MultipleChoiceItem , but once you have that you could continually create as many questions as needed that would do exactly what this question asks.

Here's a sample item as well as a function to display the ID of all multiple-choice items in a form. It's not perfect, but perhaps an alternative.

function makeShuffledQuestion() {
  const theIDofShuffleQuestion = 2???????1; //<--- must find by getID()

  const theShuffleQuestion = form.getItemById(theIDofShuffleQuestion);

  //next line use duplicate, or start loops to duplicate types that
  var mc = theShuffleQuestion.duplicate();
  mc.setTitle("This one is new!");
  mc.setPoints(1);
  mc.setChoices([
    mc.createChoice("alpha", fale),
    mc.createChoice("bravo", false),
    mc.createChoice("charlie", true),
    mc.createChoice("delta", false)
  ])
}

function listAllItemsID() {
  //function will display all multiplie choice items with title and ID
  var allItems = form.getItems(FormApp.ItemType.MULTIPLE_CHOICE);
  for (var i = 0; i < allItems.length; i++) {
    Logger.log(allItems[i].getTitle() + "  ID:" + allItems[i].getId().toString());
  }
}
pgSystemTester
  • 8,979
  • 2
  • 23
  • 49