Google forms - Autofill a multiple choice survey

esh picture esh · Oct 22, 2014 · Viewed 30.9k times · Source

I've created this psychology survey out on a google form. It has about 20 multiple choice questions apart from the usual email, name etc. So you see there aren't any right/wrong answers as such.

How do I fake the results, or create, say, 50 form submissions? Forgive my ignorance but, will the results be in a Google spreadsheet? Should I just fill in 50 details on a Google spreadsheet then?

Answer

tehhowch picture tehhowch · Sep 18, 2018

@Mogsdad's answer references a url-based solution, in which your script has no idea what kind of answers can be made for a given question (or how many questions, etc), which could be problematic in certain use cases.

You can programmatically create responses for a Google Form, using the Forms Service, which allows you to randomly select possible answers from the available choices, among other things (such as referencing a predefined library of "written" answers, e.g. for text / paragraph answers).

An example, that assumes you have a multiple-choice-only test, with a non-constant number of choices for each question:

function foo() {
  const form = FormApp.openById("some form id");

  const randomSubs = [], nSubs = 50;
  while (randomSubs.length < nSubs)
    randomSubs.push(createRandomSubmission_(form).submit());

  // doAwesomeAnalysis(randomSubs); // etc.
}

// Constructs a random response for the given form, and returns it to the caller (e.g. for submission, etc).
function createRandomSubmission_(form) {
  const resp = form.createResponse();
  const questions = form.getItems().filter(isAnswerable_);
  questions.forEach(function (question) {
    var answer = getRandomAnswer_(question);
    resp.withItemResponse(answer);
  });
  return resp;
}

var iTypes = FormApp.ItemType;
function isAnswerable_(item, index, allItems) {
  const iType = item.getType();
  switch (iType) {
    case iTypes.MULTIPLE_CHOICE:
    case iTypes.CHECKBOX:
    /** add more type cases here as you implement the relevant answer generator */
      return true;
    default:
      return false;
  }
}

// Uses the item type to call the appropriate answer generator.
function getRandomAnswer_(q) {
  const qType = q.getType();
  switch (qType) {
    case iTypes.MULTIPLE_CHOICE:
      return getRandomMultipleChoiceAnswer_(q.asMultipleChoiceItem());
    /** add more type cases + handlers here as you implement the relevant answer generator */
    default:
      throw new TypeError("Answering questions of type '" + qType + "' is not yet implemented");
  }
}

// Uniformly samples possible choices (including the "other" option, if enabled).
// Returns the item's ItemResponse
function getRandomMultipleChoiceAnswer_(mcItem) {
  const choices = mcItem.getChoices();
  const i = Math.floor( Math.random() * (choices.length + mcItem.hasOtherOption()) );
  return mcItem.createResponse( (i < choices.length) ?
      choices[i] : getRandomMCOtherOption_(mcItem) 
  );
}
function getRandomMCOtherOption_(mcItem) {
  // This function will be highly dependent on your situation.
  // It's your choice how you identify the MC item to determine what an "other" option could
  // be for a given question. getTitle() and getIndex() may be useful too.
  switch (mcItem.getId()) { 
    default:
      throw new Error("Not Implemented Yet");
  }
}