Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I randomize items in MultipleChoiceItem? [duplicate]

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!

like image 328
user3065296 Avatar asked Sep 14 '25 05:09

user3065296


2 Answers

  • 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.

like image 91
ziganotschka Avatar answered Sep 16 '25 22:09

ziganotschka


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());
  }
}
like image 28
pgSystemTester Avatar answered Sep 16 '25 23:09

pgSystemTester