Автоматическое создание тестов с несколькими вариантами ответов на формах Google

Я учитель, и мне нужно создавать множество тестов с несколькими вариантами ответов для своих учеников.

Вы увидите, что каждый вопрос с несколькими вариантами ответов имеет одинаковый формат - вопрос, который нужно загрузить в виде изображения, а затем 4 варианта с несколькими вариантами ответов - A, B, C и D.

У меня вопрос, есть ли способ автоматизировать этот процесс?

Каждый пакет вопросов находится в папке googledrive и называется "1.png", "2.png", "3.png" и т. Д. - они должны быть загружены в виде изображений в форму Google.

В отдельной папке у меня есть googlesheet, в котором перечислены все ответы на каждый вопрос, это выглядит так.

Таким образом, числа, которые соответствуют ответам (буквам) в электронной таблице, соответствуют файлам изображений (например, первая строка таблицы выше показывает, что ответом на вопрос 1.png является A)

В отдельной папке у меня есть еще одна таблица googles с отзывами о неправильных и правильных ответах, которая выглядит следующим образом. Не на все вопросы есть отзывы.

Есть ли способ автоматически генерировать тесты из этих таблиц Google и png-файлов?

Спасибо, что нашли время, чтобы прочитать все это, и отдельное спасибо, если вы можете предложить решение?

1 ответ

Вот решение для спрашивающего, который хотел случайным образом выбрать заданное количество вопросов из банка вопросов. Это не использует формы Google, а использует HTML-формы.

Вот код (вы можете его адаптировать):

function onOpen()
{
    SpreadsheetApp.getUi().createMenu('Questions Menu')
      .addItem('Questions', 'questionsToHtml')
      .addToUi();
}

function selectTest()
{
  var qA=selectQuestions(5,24);
  Logger.log(qA);
}

function selectQuestionIndexes(n,m)
{
  var set=[];
  do
  {
    var i=getRandomIntInclusive(0,m);
    if(set.indexOf(i)<0)
    {
      set.push(i);
    }
  }while(set.length<n);
  return set;
}

function getRandomIntInclusive(min, max) 
{
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min; //The maximum is inclusive and the minimum is inclusive 
}

function getCpData()
{
  var ss=SpreadsheetApp.getActive();
  var cpSh=ss.getSheetByName('ControlPanel');
  var cpRg=cpSh.getDataRange();
  var cpVa=cpRg.getValues();
  var qsrcSh=ss.getSheetByName(cpVa[1][0]);
  var adesSh=ss.getSheetByName(cpVa[1][1]);
  var qnum=cpVa[1][2];
  var cpData={'qSrc':cpVa[1][0],'aDes':cpVa[1][1],'qNum':cpVa[1][2]};
  return cpData;
}

function getAnswerIndexes()
{
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getSheetByName(getCpData().qSrc);
  var rg=sh.getRange(1,1,1,sh.getLastColumn());
  var vA=rg.getValues();
  var re=/Answer \d{1,2}/i;
  var fidx=0;
  var lidx=0;
  var first=true;
  for(var i=0;i<vA[0].length;i++)
  {
    if(String(vA[0][i]).match(re))
    if(first)
    {
      fidx=i;
      first=false;
    }
    else
    {
      lidx=i;
    }
  }
  return {'firstIdx':fidx,'lastIdx':lidx};
}

function testResp()
{
  var row = [[1,'What is the question?','no'],[2,'What is the question?','no'],[3,'What is the question?','no']];
  recordData(row);

}


function recordData(responses)
{
  if(responses)
  {
    var ss=SpreadsheetApp.getActive();
    var sheetname=getCpData().aDes;
    var sh=ss.getSheetByName(sheetname);
    var ts=Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yyyy HH:mm:ss"); 
    for(var i=0;i<responses.length;i++)
    {
      responses[i].splice(0,0,ts);
      sh.appendRow(responses[i]);
    }
  }
  return true;
}

function questionsToHtml(web) 
{
  var web=(typeof(web)!='undefined')?web:false;
  var br='<br />';
  var cm=',';
  var ss=SpreadsheetApp.getActive();
  var cpData=getCpData();
  var qnum=cpData.qNum;
  var qa=getQAndA();
  var qi=getAnswerIndexes();
  var s='';
  for(var i=0;i<qa.length;i++)
  {
    var clr=['#f6d1ac','#c5e9bd']
    //s+='<table>';
    //s+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' , qa[i][0],qa[i][1],(qa[i][2])?qa[i][2]:'&nbsp;',(qa[i][3])?qa[i][3]:'&nbsp;',(qa[i][4])?qa[i][4]:'&nbsp;',(qa[i][5])?qa[i][5]:'&nbsp;');
    //s+='</table>';

    s+='<div id="d' + qa[i][0] + '" style="font-weight:bold;background-color:' + clr[i % 2] + ';padding:5px;">' + qa[i][1];
    s+='<input type="hidden" value="' + qa[i][0] + '" class="hiding" />';
    for(var j=qi.firstIdx;j<=qi.lastIdx;j++)
    {
      if(qa[i][j])
      {
        s+=br + '<input type="radio" name="n'+ qa[i][0] +'" value="' + qa[i][j] + '" />' + qa[i][j];
      }
    }
    s+='</div>'


  }
  s+='<div id="controls">';
  s+=br + '<input type="button" value="Submit" onClick="recordData();" />';
  //s+=br + '<input type="button" value="Do It Again" onClick="google.script.run.questionsToHtml();" />';
  s+='</div>';
  s+='</body></html>';
  //Logger.log(s);
  if(!web)
  {
    var userInterface=HtmlService.createHtmlOutputFromFile('htmlToBody').append(s).setWidth(600).setHeight(450);
    SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Random Questions from a Question Bank')
   }
   else
   {
     var output=HtmlService.createHtmlOutputFromFile('htmlToBody').append(s);
     return output.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
   }
}

function doGet()
{
  return questionsToHtml(true)
}

function getQAndA()
{
  var qa=[];
  var cma=',';
  var ss=SpreadsheetApp.getActive();
  var cpData=getCpData();
  var qsrcSh=ss.getSheetByName(cpData.qSrc);
  var qsrcRg=qsrcSh.getRange(2,1,qsrcSh.getLastRow()-1,qsrcSh.getLastColumn());
  var qsrcVa=qsrcRg.getValues();
  var qs=selectQuestionIndexes(cpData.qNum,qsrcVa.length-1);
  var aIdxs=getAnswerIndexes();
  for(var i=0;i<qsrcVa.length;i++)
  {
    var qas='';
    if(qs.indexOf(i)>-1)
    {
      qas+=qsrcVa[i][0] + cma + qsrcVa[i][1];
      for(j=aIdxs.firstIdx;j<=aIdxs.lastIdx;j++)
      {
        if(qsrcVa[i][j])
        {
            qas+= cma + qsrcVa[i][j];
        }
      }
      qa.push(qas.split(cma));
    }
  }
  return qa;
}

Вот файл htmlToBody.html:

<!DOCTYPE html>
<html>
<head>
 <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>
    $(function() {

      });
    function recordData()
    {
      var responses=[];
      var cm=',';
      var divs = document.getElementsByTagName("div");
      for(var i=0;i<divs.length;i++)
      {
        var id=divs[i].getAttribute(['id']);
        var qnum=$('div#' + id + ' ' + 'input.hiding').val();
        var question=document.getElementById(id).innerHTML;
        var answer=$('input[name="n' + qnum + '"]:checked').val();
        if(id!='controls')
        {
          if(!answer)
          {
            window.alert('You did not answer question number ' + Number(i+1) + '. It is a requirement of this survey that all questions must be answered.' );
            return;
          }
          else
          {
            var end='is near';
            var s=qnum + cm + question + cm + answer;
            responses.push(s.split(cm));
          }
        }
      }

      google.script.run
          .withSuccessHandler(displayThanks)
          .recordData(responses);
    }
    function displayThanks()
    {
       var divs = document.getElementsByTagName("div");
      for(var i=0;i<divs.length;i++)
      {
        divs[i].style.cssText="display:none;text-align:center";
      }
      var elemDiv = document.createElement('div');
      elemDiv.innerHTML="<br /><h1>Thank You For Your Participation in This Survey</h1>";
      document.body.appendChild(elemDiv);
    }
    console.log('My Code Here');
    </script>
    <style>
    #reply{display:none;}
    #collect{display:block;}
    body  {
    background-image: url("http://myrabridgforth.com/wp-content/uploads/blue-sky-clouds.jpg");
    background-color: #ffffff;
    background-repeat: no-repeat;
    background-position: left bottom;
}
    </style>
</head>  
<body>

Вот как выглядят различные вкладки в электронной таблице:

Вкладка ControlPanel:

Вкладка "Банк вопросов":

Вкладка Test1:

Надеюсь, что это будет иметь определенную ценность для вас.

Все остальное работает отлично, но знаете ли вы, почему я получаю это с ответом, представленным Test1?

Для решения проблемы в густонаселенной местности предлагается сверхплотная сеть. Сверхплотная сеть поддерживает постоянное соединение и скорость передачи данных в густонаселенной местности.

Другие вопросы по тегам