Генераторы заданий MyTestXPro: различия между версиями

Материал из MyTestXPro Wiki Help
Перейти к навигации Перейти к поиску
(не показаны 34 промежуточные версии этого же участника)
Строка 6: Строка 6:
  
 
Например, вопрос может быть записан так:  
 
Например, вопрос может быть записан так:  
<pre>"Переведите десятичное число {%число%} в двоичную систему счисления."</pre>
+
 
 +
"Переведите двоичное число '''{%дв_число%}'''<sub>2</sub> в десятичную систему счисления."
 +
 
 +
[[File:gen1.png|200px]]
  
 
Если задание с вариантами ответа, то в тексте вариантов ответов можно тоже сделать шаблоны. Если задание на ручной ввод ответа и ответ генерируется автоматически, то в поле ответа ничего писать не нужно - им соответствуют уже как бы заданные шаблоны ответов {%answer1%}, {%answer2%}... {%answer10%}, а если ответ только один можно использовать шаблон {%answer%}.
 
Если задание с вариантами ответа, то в тексте вариантов ответов можно тоже сделать шаблоны. Если задание на ручной ввод ответа и ответ генерируется автоматически, то в поле ответа ничего писать не нужно - им соответствуют уже как бы заданные шаблоны ответов {%answer1%}, {%answer2%}... {%answer10%}, а если ответ только один можно использовать шаблон {%answer%}.
  
Скрипт-генератор должен вернуть для шаблонов конкретные задания, которые будут подставлены в соответствующие места.
+
<spoiler text="Автоматические шаблоны">
 +
Шаблоны ответов answer1, answer2... answer10 для заданий на ручной ввод ответа (числа или текста) и перестановку букв задают ответ, для заданий с вариантами ответа указывают должен ли быть выбран или нет этот вариант (одиночный и множественный выбор), порядок, с чем сопоставлять....
 +
 
 +
Для числовых ответов answerDx1, ..., answerDx10 задают значение погрешности.
 +
 
 +
answerCaption1, ..., answerCaption10 - подписи полей ответа.
 +
 
 +
taskTitle - название задания 
 +
</spoiler>
 +
Скрипт-генератор должен вернуть для шаблонов конкретные значения, которые будут подставлены в соответствующие места при генерации новых заданий.
  
 
== Скрипт ==
 
== Скрипт ==
Строка 16: Строка 28:
 
Скрипт-генератор пишется на языке программирования JavaScript.
 
Скрипт-генератор пишется на языке программирования JavaScript.
  
В скрипте может быть несколько функций, для генерации заданий вызывается функция '''main()'''. Она должна вернуть данные в виде объекта - ассоциативный массив (в примере это ''var m = {};''). Заполняем его в формате ''m['шаблон'] = 'значение';''.  
+
В скрипте может быть несколько функций, для генерации заданий вызывается функция '''main()'''. Она должна вернуть данные в виде объекта - ассоциативный массив (в примере это ''var m = {};''). Заполняем его в формате ''m['шаблон'] = 'значение';''. Для возврата значений можно использовать переменную _result (её объявлять ну нужно, это делается автоматически), тогда возвращаемое значение будет return _result.  
  
 
<pre>
 
<pre>
Строка 29: Строка 41:
 
</pre>
 
</pre>
  
У функции main() есть параметр, например, если написать main(index), то при создании 10 заданий переменная index будет последовательно принимать значения 0, 1, ... 9 для каждой генерации. Вы можете использовать и другое имя параметра. Для возврата значений можно использовать и переменную _result (её объявлять ну нужно, это делается автоматически), тогда возвращаемое значение будет return _result. Если функция main() возвращает false (или не возвращает нужных данных), то задание не создается.
+
или
  
 +
<pre>
 +
function main(index){
 +
  //... 
 +
  _result['шаблон'] = 'значение';
 +
  _result['answer'] = 3.14; 
 +
  //...
 +
  return _result;
 +
}
 +
</pre>
  
 +
[[File:gen2.png|200px]]
  
1) Например, нужно сделать задания типа для какой-то страны указать её столицу. В одном массиве пишем страны, в другом столицы. Переменная index изменяется от 0 до N-1 (где N - сколько заданий сделать). Берем из массива нужные элементы и заполняем данные для замены.
+
Если функция main() возвращает false (или не возвращает нужных данных), то задание не создается.  
 +
 
 +
У функции main() есть параметр, например, если написать main(index), то при создании 10 заданий переменная index будет последовательно принимать значения 0, 1, ... 9 для каждой генерации. Вы можете использовать и другое имя параметра.
 +
 
 +
== Генерация ==
 +
 
 +
Например, нужно сделать задания на перевод чисел из одной системы счисления в другую для чисел от 25 до 125. Скрипт может быть такой:
  
 
<pre>
 
<pre>
 
function main(index){
 
function main(index){
   var country = ['России', 'Китая', 'Франции', 'Японии', 'США'];
+
   var a10 = 25 + index;
   var capital = ['Москва', 'Пекин', 'Париж', 'Токио', 'Вашингтон'];
+
   var a2 = a10.toString(2);
 
    
 
    
 
   var m = {};   
 
   var m = {};   
   m['страна'] = country[index];
+
   m['дв_число'] = a2;
   m['answer'] = capital[index];
+
   m['answer'] = a10;
  
 
   return m;
 
   return m;
Строка 48: Строка 76:
 
</pre>
 
</pre>
  
или так
+
[[File:gen3.png|200px]]
 +
 
 +
Перед генерацией следует выполнить проверку Проверить скрипт. Если не будет обнаружено ошибок, то в поле "Результат работы скрипта" появятся вычисленные значения. Например,
 +
<pre>
 +
дв_число=11001
 +
answer=25
 +
</pre>
 +
 
 +
[[File:gen4.png|200px]]
 +
 
 +
Выбираем группу для новых заданий. Указываем количество итераций (в этом примере это 100) и нажимаем Создать задания. Запускается процесс генерации заданий.
 +
 
 +
[[File:gen5.png|200px]] [[File:gen6.png|200px]]
 +
 
 +
В указанной группе получили 100 новых заданий на основе задания-шаблона. При этом затратили всего пару минут.
 +
 
 +
[[File:gen7.png|200px]]
 +
 
 +
Скорее всего, тестируемому из этих заданий будет предложено выполнить только несколько случайно выбранных, для этого не забудьте указать этот параметр в свойствах группы (настроить [[Создание_выборки_в_MyTestXPro|выборку]]).
 +
 
 +
Так же не забудьте удалить из готового теста файлы заданий-шаблонов или переместить их в отдельную группу и настроить выборку 0.
 +
 
 +
Для повторного использования скрипта его можно не только скопировать и куда-либо вставить как текст, но и сохранить в файл. Команды Открыть, Сохранить как... доступны в контекстном меню (правой кнопкой) поля скрипта. Так же из этого меню можно вставить название шаблона.
 +
 
 +
== Еще несколько примеров ==
 +
 
 +
1) Например, нужно сделать задания типа для какой-то страны указать её столицу. В одном массиве пишем страны, в другом столицы. Переменная index изменяется от 0 до N-1 (где N - сколько заданий сделать). Берем из массива нужные элементы и заполняем данные для замены.
  
 
<pre>
 
<pre>
Строка 54: Строка 108:
 
   var country = ['России', 'Китая', 'Франции', 'Японии', 'США'];
 
   var country = ['России', 'Китая', 'Франции', 'Японии', 'США'];
 
   var capital = ['Москва', 'Пекин', 'Париж', 'Токио', 'Вашингтон'];
 
   var capital = ['Москва', 'Пекин', 'Париж', 'Токио', 'Вашингтон'];
 
+
 
   _result['страна'] = country[index];
+
  var m = {}; 
   _result['answer'] = capital[index];
+
   m['страна'] = country[index];
 +
   m['answer'] = capital[index];
  
   return _result;
+
   return m;
 
}
 
}
 
</pre>
 
</pre>
Строка 65: Строка 120:
  
  
Можно сделать еще проще - списки как строки:
+
Можно сделать списки как строки:
  
 
<pre>
 
<pre>
Строка 118: Строка 173:
 
</pre>
 
</pre>
  
Т.к. в шестнадцатеричной сист. счисления могут быть буквы от A до F, то тип задания ввод текста, а то потеряется третий вариант ответа.
+
Т.к. в шестнадцатеричной системе счисления могут быть буквы от A до F, то тип задания ввод текста, а то потеряется третий вариант ответа.
  
3) В командах для Чертежника задать случайные значения, вычислить результат... Можно использовать генератор и для заданий с вариантами заданий, т.к. если включить перемешивание вариантов, то можно считать что первый (или другой) верный, все равно перемешаются...
+
3) Пример с шаблонами в вариантах заданий. Можно использовать генератор и для заданий с вариантами заданий, т.к. если включить перемешивание вариантов, то можно считать что первый (или другой) верный, все равно перемешаются... Так же с помощью шаблонов 'answer1'... указывать верный вариант из скрипта.
  
 
<pre>
 
<pre>
Строка 157: Строка 212:
 
</pre>
 
</pre>
  
В версии 11.0.0.44 добавлена функция function _randomInteger(min, max), поэтому свою описывать не обязательно.
+
В данном примере скрипт содержит еще одну дополнительную (вспомогательную) функцию для получения случайного значения. Правда, делать было не обязательно, т.к. уже имеется функция function _randomInteger(min, max), поэтому свою описывать не обязательно.
  
 
[[File:3-3.png|200px]] [[File:3.png|200px]] [[File:3-1.png|200px]] [[File:3-2.png|200px]]
 
[[File:3-3.png|200px]] [[File:3.png|200px]] [[File:3-1.png|200px]] [[File:3-2.png|200px]]
  
 
+
<!--
 
Файлы-примеры (для версии .44 еще не адаптированы) с этой страницы доступны по ссылке https://yadi.sk/d/y25HEFmXrKqPL
 
Файлы-примеры (для версии .44 еще не адаптированы) с этой страницы доступны по ссылке https://yadi.sk/d/y25HEFmXrKqPL
 
Команды Открыть, Сохранить скрипты доступны в контекстном меню (правой кнопкой) поля скрипта.
 
 
Для обмена данными между запусками (в пределах одной сессии, например, создавая 100 заданий) можно использовать глобальный массив ''gData''.
 
  
 
Видео-примеры:
 
Видео-примеры:
Строка 172: Строка 223:
 
* https://vk.com/mytestxpro?z=video-57959169_456239018%2F8e199bcebd99bf9ac6%2Fpl_wall_-57959169
 
* https://vk.com/mytestxpro?z=video-57959169_456239018%2F8e199bcebd99bf9ac6%2Fpl_wall_-57959169
 
* https://vk.com/video-57959169_456239019
 
* https://vk.com/video-57959169_456239019
 +
-->
  
Создавая множество заданий с помощью генератора, вы, скорее всего, желаете что бы задавались не все задания, а только часть из них. В настройках группы заданий не забываем ставить ограничение по количеству заданий и перемешивание.
+
== Сохранение данных между итерациями генератора ==
  
Сохранение данных между итерациями генератора.
+
Для передачи данных между итерациями можно использовать встроенный объект _o или массив _a. Объявлять их не нужно, они объявляются автоматически как var _o = {} и var _a=[]. Можно проверить, есть ли там нужный ключ, получить значение, записать значение.
  
Имитация генератора с вложенным циклом.
+
<pre>
 +
function main(index){
 +
 
 +
  if('k' in _o){
 +
    _o['k'] = _o['k'] + 10;
 +
  }else{
 +
    _o['k'] = 5;
 +
  }
 +
 
 +
  var m = {};
 +
  m['шаблон'] = 'значение';
 +
  m['answer'] = _o['k'];
 +
  //...
 +
  return m;
 +
}
 +
</pre>
 +
 
 +
Выше уже было сказано, что используя параметр index функции main() можно перебирать значения. Что аналогично коду:
 +
 
 +
<pre>
 +
для index от 0 до n-1
 +
  генерировать задание (index)
 +
</pre>
 +
 
 +
Но как быть если нужно перебрать, например, все пары значений двух переменных? Т.е. имитировать код:
 +
<pre>
 +
для i от a до b
 +
  для j от c до d
 +
    генерировать задание (i, j)
 +
</pre>
 +
 
 +
Ответ ниже - пример генерации теста для проверки таблицы умножения. Нужно создать 100 заданий от 1*1=... до 10*10=.
  
 
<pre>
 
<pre>
function main(index){
+
function main(){
 
   var i = 1;
 
   var i = 1;
 
   var j = 1;
 
   var j = 1;
Строка 205: Строка 288:
 
}
 
}
 
</pre>
 
</pre>
 
 
  
 
<pre>
 
<pre>
function main(index){
+
function main(){
 
   var i = 1;
 
   var i = 1;
 
   var j = 1;
 
   var j = 1;
Строка 234: Строка 315:
 
}
 
}
 
</pre>
 
</pre>
 +
 +
Про работу с объектами и массивами на JavaScript можно почитать, например, на сайте
 +
 +
https://learn.javascript.ru/object
 +
 +
https://learn.javascript.ru/array

Версия 16:06, 7 февраля 2020

В редактор тестов версии 11.0.0.41 добавлен генератор заданий (Задания → Генератор), который позволяет на основе задания-шаблона, используя скрипт на JavaScript, создать большое количество заданий. В процессе развития программы генератор изменялся, текущая страница описывает генератор в актуальной версии программы.

Шаблоны

Сначала необходимо создать задание-шаблон на основе которого будут создаваться новые задания автоматически. От обычного задания оно отличается тем, что вместо конкретных чисел или слов указаны шаблоны-подстановки. Шаблоны записываются в тексте как {%шаблон%}. Имя шаблона может содержать русские и латинские буквы, цифры и символ подчеркивания.

Например, вопрос может быть записан так:

"Переведите двоичное число {%дв_число%}2 в десятичную систему счисления."

Gen1.png

Если задание с вариантами ответа, то в тексте вариантов ответов можно тоже сделать шаблоны. Если задание на ручной ввод ответа и ответ генерируется автоматически, то в поле ответа ничего писать не нужно - им соответствуют уже как бы заданные шаблоны ответов {%answer1%}, {%answer2%}... {%answer10%}, а если ответ только один можно использовать шаблон {%answer%}.

Автоматические шаблоны

Скрипт-генератор должен вернуть для шаблонов конкретные значения, которые будут подставлены в соответствующие места при генерации новых заданий.

Скрипт

Скрипт-генератор пишется на языке программирования JavaScript.

В скрипте может быть несколько функций, для генерации заданий вызывается функция main(). Она должна вернуть данные в виде объекта - ассоциативный массив (в примере это var m = {};). Заполняем его в формате m['шаблон'] = 'значение';. Для возврата значений можно использовать переменную _result (её объявлять ну нужно, это делается автоматически), тогда возвращаемое значение будет return _result.

function main(index){ 
  //...  
  var m = {};
  m['шаблон'] = 'значение';
  m['answer'] = 3.14;    
  //...
  return m;
}

или

function main(index){ 
  //...  
  _result['шаблон'] = 'значение';
  _result['answer'] = 3.14;  
  //...
  return _result;
}

Gen2.png

Если функция main() возвращает false (или не возвращает нужных данных), то задание не создается.

У функции main() есть параметр, например, если написать main(index), то при создании 10 заданий переменная index будет последовательно принимать значения 0, 1, ... 9 для каждой генерации. Вы можете использовать и другое имя параметра.

Генерация

Например, нужно сделать задания на перевод чисел из одной системы счисления в другую для чисел от 25 до 125. Скрипт может быть такой:

function main(index){
  var a10 = 25 + index;
  var a2 = a10.toString(2);
  
  var m = {};  
  m['дв_число'] = a2;
  m['answer'] = a10;

  return m;
}

Gen3.png

Перед генерацией следует выполнить проверку Проверить скрипт. Если не будет обнаружено ошибок, то в поле "Результат работы скрипта" появятся вычисленные значения. Например,

дв_число=11001
answer=25

Gen4.png

Выбираем группу для новых заданий. Указываем количество итераций (в этом примере это 100) и нажимаем Создать задания. Запускается процесс генерации заданий.

Gen5.png Gen6.png

В указанной группе получили 100 новых заданий на основе задания-шаблона. При этом затратили всего пару минут.

Gen7.png

Скорее всего, тестируемому из этих заданий будет предложено выполнить только несколько случайно выбранных, для этого не забудьте указать этот параметр в свойствах группы (настроить выборку).

Так же не забудьте удалить из готового теста файлы заданий-шаблонов или переместить их в отдельную группу и настроить выборку 0.

Для повторного использования скрипта его можно не только скопировать и куда-либо вставить как текст, но и сохранить в файл. Команды Открыть, Сохранить как... доступны в контекстном меню (правой кнопкой) поля скрипта. Так же из этого меню можно вставить название шаблона.

Еще несколько примеров

1) Например, нужно сделать задания типа для какой-то страны указать её столицу. В одном массиве пишем страны, в другом столицы. Переменная index изменяется от 0 до N-1 (где N - сколько заданий сделать). Берем из массива нужные элементы и заполняем данные для замены.

function main(index){
  var country = ['России', 'Китая', 'Франции', 'Японии', 'США'];
  var capital = ['Москва', 'Пекин', 'Париж', 'Токио', 'Вашингтон'];
  
  var m = {};  
  m['страна'] = country[index];
  m['answer'] = capital[index];

  return m;
}

1.png 1-1.png 1-2.png


Можно сделать списки как строки:

function main(index){
  var countrys = 'России, Китая, Франции, Японии, США';
  var capitals = 'Москва, Пекин, Париж, Токио, Вашингтон';
  
  var country = countrys.split(', ');
  var capital = capitals.split(', ');
  
  var m = {};  
  m['страна'] = country[index];
  m['answer'] = capital[index];

  return m;
}

2) Переведите десятичное число {%дес_число%} в двоичную систему счисления. Нужно получить задания для числа от 25 до 125.

function main(index){
  var a10 = 25 + index;
  var a2 = a10.toString(2);
  
  var m = {};  
  m['дес_число'] = a10;
  m['answer'] = a2;

  return m;
}

2.png 2-1.png 2-2.png 2-3.png

Можно сделать с тремя полями для ответа:

function main(index){
  var a10 = 25 + index;
  var a2 = a10.toString(2);
  var a8 = a10.toString(8);
  var a16 = a10.toString(16).toUpperCase();
  
  var m = {};  
  m['дес_число'] = a10;
  m['answer1'] = a2;
  m['answer2'] = a8;
  m['answer3'] = a16;

  return m;
}

Т.к. в шестнадцатеричной системе счисления могут быть буквы от A до F, то тип задания ввод текста, а то потеряется третий вариант ответа.

3) Пример с шаблонами в вариантах заданий. Можно использовать генератор и для заданий с вариантами заданий, т.к. если включить перемешивание вариантов, то можно считать что первый (или другой) верный, все равно перемешаются... Так же с помощью шаблонов 'answer1'... указывать верный вариант из скрипта.

function randomInteger(min, max){
  var rand = min + Math.random() * (max + 1 - min);
  rand = Math.floor(rand);
  return rand;
}

function main(){
  var n = randomInteger(2, 4);
  
  var x1 = randomInteger(-5, 5);
  var y1 = randomInteger(-5, 5);
  var x2 = randomInteger(-5, 5);
  var y2 = randomInteger(-5, 5);

  var x = x1 + x2;
  x = n * x;
  var y = y1 + y2;
  y = n * y;   

  var m = {};  
  m['n'] = n;
  m['x1'] = x1;
  m['y1'] = y1;
  m['x2'] = x2; 
  m['y2'] = y2;
  m['x'] = x;
  m['y'] = y;
  m['mx'] = -x;
  m['my'] = -y;  
  
  return m;
}

В данном примере скрипт содержит еще одну дополнительную (вспомогательную) функцию для получения случайного значения. Правда, делать было не обязательно, т.к. уже имеется функция function _randomInteger(min, max), поэтому свою описывать не обязательно.

3-3.png 3.png 3-1.png 3-2.png


Сохранение данных между итерациями генератора

Для передачи данных между итерациями можно использовать встроенный объект _o или массив _a. Объявлять их не нужно, они объявляются автоматически как var _o = {} и var _a=[]. Можно проверить, есть ли там нужный ключ, получить значение, записать значение.

function main(index){

  if('k' in _o){
    _o['k'] = _o['k'] + 10;
  }else{
    _o['k'] = 5;
  }
  
  var m = {};
  m['шаблон'] = 'значение';
  m['answer'] = _o['k'];
  //...
  return m;
}

Выше уже было сказано, что используя параметр index функции main() можно перебирать значения. Что аналогично коду:

для index от 0 до n-1
  генерировать задание (index)

Но как быть если нужно перебрать, например, все пары значений двух переменных? Т.е. имитировать код:

для i от a до b
  для j от c до d
    генерировать задание (i, j)

Ответ ниже - пример генерации теста для проверки таблицы умножения. Нужно создать 100 заданий от 1*1=... до 10*10=.

function main(){
  var i = 1;
  var j = 1;
  if ('i' in _o) {i = _o['i']}
  if ('j' in _o) {j = _o['j']}

  var ij = i * j;

  var m = {};
  m['i'] = i;
  m['j'] = j;
  m['answer'] = ij;

  if (j == 10) {
    i++;
    j = 1;
  }else{
    j++
  }
  _o['i'] = i;
  _o['j'] = j;

  return m;
}
function main(){
  var i = 1;
  var j = 1;
  if (_a[0] > 0) {i = _a[0]}
  if (_a[1] > 0) {j = _a[1]}

  var ij = i * j;

  var m = {};
  m['i'] = i;
  m['j'] = j;
  m['answer'] = ij;

  if (j == 10) {
    i++;
    j = 1;
  }else{
    j++
  }
  _a[0] = i;
  _a[1] = j;

  return m;
}

Про работу с объектами и массивами на JavaScript можно почитать, например, на сайте

https://learn.javascript.ru/object

https://learn.javascript.ru/array