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

Материал из MyTestXPro Wiki Help
Перейти к навигации Перейти к поиску
 
(не показано 75 промежуточных версий этого же участника)
Строка 1: Строка 1:
В редактор тестов версии 11.0.0.41 добавлен генератор заданий (Задания → Генератор), который позволяет на основе задания-шаблона, используя скрипт на JavaScript, создать большое количество заданий. В процессе развития программы генератор изменялся, текущая страница описывает генератор в актуальной версии программы.
+
<font color='#aaaaaa'>Информация для версии 11.0.0.62, для версии 11.0.0.61 смотрите [[Генераторы заданий (старая версия)]].</font>
  
== Шаблоны в задании ==
+
'''Генератор заданий позволяет быстро на основе задания-шаблона создать большое количество подобных заданий.'''
  
Сначала необходимо создать задание на основе которого будут создаваться новые задания автоматически. От обычного задания оно отличается тем, что вместо конкретных чисел или слов указаны шаблоны-подстановки. Шаблоны записываются в тексте как {%шаблон%}. Шаблоны ответов (их в задании писать не нужно, они как бы есть) {%answer1%}, {%answer2%}... {%answer10%}, если ответ только один можно использовать шаблон {%answer%}.
+
== Шаблоны ==
  
В скрипте может быть несколько функций, для генерации заданий вызывается функция '''main()'''. Она должна вернуть данные в виде объекта - ассоциативный массив (в примере это ''var m = {};''). Заполняем его в формате ''m['шаблон'] = 'значение';''.  
+
Сначала необходимо создать задание-шаблон на основе которого будут автоматически создаваться новые задания. От обычного задания оно отличается тем, что вместо конкретных чисел или слов указаны шаблоны-подстановки. Шаблоны записываются в тексте как {%шаблон%}. Имя шаблона может содержать русские и латинские буквы, цифры и символ подчеркивания.
  
У функции main() есть параметр, например, если написать main(index), то при создании 10 заданий переменная index будет последовательно принимать значения 0, 1, ... 9 для каждой генерации. Вы можете использовать и другое имя параметра. Для возврата значений можно использовать и переменную _result (её объявлять ну нужно, это делается автоматически), тогда возвращаемое значение будет return _result. Если функция main() возвращает false (или не возвращает нужных данных), то задание не создается.  
+
Например, вопрос может быть записан так: "Переведите двоичное число '''{%дв_число%}'''<sub>2</sub> в десятичную систему счисления."
  
 +
[[File:generator62_1.png|600px]]
  
 +
Если задание на ручной ввод ответа и ответ генерируется автоматически, то в поле ответа ничего писать не нужно - ему соответствуют шаблон {%answer%}.
 +
Если вариантов ответа несколько, то каждому {%answer1%}, {%answer2%}...{%answer10%}.
  
1) Например, нужно сделать задания типа для какой-то страны указать её столицу. В одном массиве пишем страны, в другом столицы. Переменная index изменяется от 0 до N-1 (где N - сколько заданий сделать). Берем из массива нужные элементы и заполняем данные для замены.
+
<spoiler text="Еще автоматические шаблоны">
 +
Для числовых ответов answerDx1, ..., answerDx10 задают значение погрешности.
 +
 
 +
answerCaption1, ..., answerCaption10 - подписи полей ответа.
 +
 
 +
image - полное имя файла с изображением.
 +
</spoiler>
 +
 
 +
Если задание с вариантами ответа, то в тексте вариантов ответов можно тоже сделать шаблоны.
 +
 
 +
[[File:generator62b.png|600px]]
 +
 
 +
Для заданий с вариантами ответов шаблоны answer1, answer2... answer10 позволяют указать отмечен (значение 1 или true или +) или нет вариант ответа, а для типа сопоставление, с чем сопоставить.
 +
 
 +
 
 +
Генератор вместо шаблонов подставит конкретные значения и получится готовое задание.
 +
 
 +
Для открытия генератора выберите задание-шаблон и дайте команду Задания → Генератор...
 +
 
 +
[[File:generator62_2.png|600px]]
 +
 
 +
== Скрипт ==
 +
 
 +
Скрипт позволяет подготовить данные для создания заданий. Он пишется на языке программирования JavaScript.
 +
 
 +
Также вы можете подготовить данные другим способом (например, написав программу на другом языке программирования) и просто их вставить в соответствующее поле.
 +
 
 +
В скрипте может быть несколько функций, при запуске вызывается функция '''main()'''. Она должна подготовить данные для постановки и передать их функции generator(). В контекстном меню (правой кнопкой) поля скрипта есть несколько заготовок, облегчающих понимание и написание своих скриптов.
  
 
<pre>
 
<pre>
function main(index){
+
function main(){
  var country = ['России', 'Китая', 'Франции', 'Японии', 'США'];
+
   var m = {};
  var capital = ['Москва', 'Пекин', 'Париж', 'Токио', 'Вашингтон'];
+
   m['шаблон'] = 'значение';
 
+
   m['answer'] = 3.14;
   var m = {};
+
  //...
   m['страна'] = country[index];
+
   generator(m);
   m['answer'] = capital[index];
 
 
 
   return m;
 
 
}
 
}
 
</pre>
 
</pre>
  
или так
+
[[File:generator62_3.png|600px]]
 +
 
 +
Этот скрипт подготовит данные только для одного задания.
 +
 
 +
Примечание: если при нажатии кнопки Запустить скрипт удерживать клавишу Shift, то данные будут добавлены к уже имеющимся. Данные для разных заданий отделяются пустой строкой.
 +
 
 +
Для подготовки данных для нескольких заданий (ведь в этом смысл генератора) нужен цикл.
  
 
<pre>
 
<pre>
function main(index){
+
function main(){
   var country = ['России', 'Китая', 'Франции', 'Японии', 'США'];
+
   var m = {};
   var capital = ['Москва', 'Пекин', 'Париж', 'Токио', 'Вашингтон'];
+
   for(var i = 0; i < 3; i++){
 
+
    m['шаблон'] = 'значение';
  _result['страна'] = country[index];
+
    m['answer'] = 3.14;
  _result['answer'] = capital[index];
+
    //...
 
+
    generator(m);
   return _result;
+
   }
 
}
 
}
 
</pre>
 
</pre>
  
[[File:1.png|200px]] [[File:1-1.png|200px]] [[File:1-2.png|200px]]
+
Теперь мы получили данные (правда, один и те же) для 3 заданий, т.к. цикл выполнился 3 раза и 3 раза была вызвана функция generator(). Как получить различные данные смотрите ниже.
 +
 
 +
== Генерация ==
 +
 
 +
Когда данные подготовлены можно создавать задания. Выберите группу для новых заданий и нажмите кнопку Создать задания.
  
 +
[[File:generator62_4.png|600px]]
  
Можно сделать еще проще - списки как строки:
+
== Пример скриптов ==
 +
 
 +
Вернемся к первому шаблону и напишем рабочий скрипт.
  
 
<pre>
 
<pre>
function main(index){
+
function main(){
   var countrys = 'России, Китая, Франции, Японии, США';
+
   var m = {};
   var capitals = 'Москва, Пекин, Париж, Токио, Вашингтон';
+
   var a10, a2;
    
+
   for(var i = 0; i < 5; i++){
  var country = countrys.split(', ');
+
    a10 = randint(25, 50);
  var capital = capitals.split(', ');
+
    a2 = a10.toString(2);   
 
+
    m['дв_число'] = a2;
  var m = {};   
+
    m['answer'] = a10;
  m['страна'] = country[index];
+
    generator(m);
  m['answer'] = capital[index];
+
   }
 
 
   return m;
 
 
}
 
}
 
</pre>
 
</pre>
  
2) Переведите десятичное число {%дес_число%} в двоичную систему счисления. Нужно получить задания для числа от 25 до 125.
+
или
 +
 
 
<pre>
 
<pre>
function main(index){
+
function main(){
   var a10 = 25 + index;
+
   var m = {};
   var a2 = a10.toString(2);
+
   var a;
    
+
   for(var i = 0; i < 5; i++){
  var m = {};
+
    a = randint(25, 50);
  m['дес_число'] = a10;
+
    m['дв_число'] = a.toString(2);
  m['answer'] = a2;
+
    m['answer'] = a;
 
+
    generator(m);
   return m;
+
   }
 
}
 
}
 
</pre>
 
</pre>
  
[[File:2.png|200px]] [[File:2-1.png|200px]] [[File:2-2.png|200px]] [[File:2-3.png|200px]]
+
Примечание: функция randint(a, b) возвращает случайное целое число N из интервала a <= N <= b. Она использует функцию Math.random и для удобства уже прописана в генераторе.
  
Можно сделать с тремя полями для ответа:
+
При таком использовании можно получить одинаковые данные (хотя дубликаты заданий и не сложно удалить).
 +
Давайте сделаем чтобы мы получили задания для чисел от 25 до 50.
  
 
<pre>
 
<pre>
function main(index){
+
function main(){
   var a10 = 25 + index;
+
   var m = {};
   var a2 = a10.toString(2);
+
   for(var i = 25; i <= 50; i++){
  var a8 = a10.toString(8);
+
    m['дв_число'] = i.toString(2);
  var a16 = a10.toString(16).toUpperCase();
+
    m['answer'] = i;
 
+
    generator(m);
  var m = {}; 
+
   }
  m['дес_число'] = a10;
 
  m['answer1'] = a2;
 
  m['answer2'] = a8;
 
   m['answer3'] = a16;
 
 
 
  return m;
 
 
}
 
}
 
</pre>
 
</pre>
  
Т.к. в шестнадцатеричной сист. счисления могут быть буквы от A до F, то тип задания ввод текста, а то потеряется третий вариант ответа.
+
[[File:generator62_5pre.png|600px]]
  
3) В командах для Чертежника задать случайные значения, вычислить результат... Можно использовать генератор и для заданий с вариантами заданий, т.к. если включить перемешивание вариантов, то можно считать что первый (или другой) верный, все равно перемешаются...
+
[[File:generator62_5.png|600px]]
 +
 +
Мы получили 26 заданий на основе задания-шаблона. Аналогично можно получить и значительно большее количество.
  
<pre>
+
== Входные данные ==
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 = {};
+
<pre>
   m['n'] = n;
+
function main(){
   m['x1'] = x1;
+
   var m = {};
  m['y1'] = y1;
+
   var a;
  m['x2'] = x2;  
+
   for(var i = 0; i < input.length; i++){
  m['y2'] = y2;
+
    a = parseInt(input[i]);
  m['x'] = x;
+
    m['дв_число'] = a.toString(2);
  m['y'] = y;
+
    m['answer'] = a;
  m['mx'] = -x;
+
    generator(m);
  m['my'] = -y;
+
   }
    
 
  return m;
 
 
}
 
}
 
</pre>
 
</pre>
  
В версии 11.0.0.44 добавлена функция function _randomInteger(min, max), поэтому свою описывать не обязательно.
+
[[File:generator62_6.png|600px]]
  
[[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
+
В поле входных данных запишем (или вставим) название страны = название столицы. Вместо = можно использовать любой разделитель (в этом задании пробел и - не подойдут, они могут быть в тексте).
  
Команды Открыть, Сохранить скрипты доступны в контекстном меню (правой кнопкой) поля скрипта.
+
<pre>
 +
Китай=Пекин
 +
Япония=Токио
 +
Россия=Москва
 +
Индия=Дели
 +
Южная Корея=Сеул
 +
Малайзия=Куала-Лумпур
 +
</pre>
  
Для обмена данными между запусками пределах одной сессии, например, создавая 100 заданий) можно использовать глобальный массив ''gData''.
+
В этом случае потребуется разбить входную строку на две части (пример есть в заготовках).
  
Видео-примеры:
+
<pre>
 +
function main(){
 +
  var m = {};
 +
  var a;
 +
  for(var i = 0; i < input.length; i++){
 +
    a = input[i].split('=');
 +
    m['страна'] = a[0];
 +
    m['answer'] = a[1];
 +
    generator(m);
 +
  }
 +
}
 +
</pre>
  
* https://vk.com/mytestxpro?z=video-57959169_456239018%2F8e199bcebd99bf9ac6%2Fpl_wall_-57959169
+
[[File:generator62_7.png|600px]]
* https://vk.com/video-57959169_456239019
 
  
Создавая множество заданий с помощью генератора, вы, скорее всего, желаете что бы задавались не все задания, а только часть из них. В настройках группы заданий не забываем ставить ограничение по количеству заданий и перемешивание.
 
  
Сохранение данных между итерациями генератора.
+
Вернемся к примеру с числами. Пусть числа записаны в одной строке через запятую. Тогда скрипт можно было записать так:
  
Имитация генератора с вложенным циклом.
+
<pre>
 +
function main(){
 +
  var m = {};
 +
  var data = input[0].split(',');
 +
  var a;
 +
  for(var i = 0; i < data.length; i++){
 +
    a = parseInt(data[i]);
 +
    m['дв_число'] = a.toString(2);
 +
    m['answer'] = a;
 +
    generator(m);
 +
  }
 +
}
 +
</pre>
  
<pre>
+
== Пример цикл в цикле ==
function main(index){
+
 
  var i = 1;
+
Допустим требуется сделать задания на таблицу умножения. Создаем задание "{%a%} {%b%} = ?"
  var j = 1;
 
  if ('i' in _o) {i = _o['i']}
 
  if ('j' in _o) {j = _o['j']}
 
  
  var ij = i * j;
+
Пишем скрипт:
  
 +
<pre>
 +
function main(){
 
   var m = {};
 
   var m = {};
   m['i'] = i;
+
   for(var i = 1; i <= 10; i++){
  m['j'] = j;
+
    for(var j = 1; j <= 10; j++){
  m['answer'] = ij;
+
      m['a'] = i;
 
+
      m['b'] = j;
  if (j == 10) {
+
      m['answer'] = i*j;
    i++;
+
      generator(m);
     j = 1;
+
     }
  }else{
 
    j++
 
 
   }
 
   }
  _o['i'] = i;
 
  _o['j'] = j;
 
 
  return m;
 
 
}
 
}
 
</pre>
 
</pre>
 +
 +
И получаем 100 заданий.
 +
 +
[[File:generator62_8.png|400px]]
  
  
 +
== Учебник JavaScript ==
  
<pre>
+
Про JavaScript можно почитать, например, на сайте
function main(index){
+
 
  var i = 1;
+
https://learn.javascript.ru
  var j = 1;
+
 
  if (_a[0] > 0) {i = _a[0]}
+
Про работу с объектами https://learn.javascript.ru/object
  if (_a[1] > 0) {j = _a[1]}
+
 
 +
Про работу с массивами https://learn.javascript.ru/array
  
  var ij = i * j;
 
  
  var m = {};
+
Примечание: повторим еще раз, что данные для создания заданий вы можете подготовить и без скрипта JavaScript, а так как вам удобнее - вручную, с помощью другого любимого языка программирования, а затем просто вставить их в соответствующее поле и создать задания.
  m['i'] = i;
 
  m['j'] = j;
 
  m['answer'] = ij;
 
  
  if (j == 10) {
+
[[File:generator62_noscript.png|600px]]
    i++;
 
    j = 1;
 
  }else{
 
    j++
 
  }
 
  _a[0] = i;
 
  _a[1] = j;
 
  
  return m;
+
[[File:generator62_noscript_pas.png|600px]]
}
 
</pre>
 

Текущая версия на 16:04, 25 июля 2021

Информация для версии 11.0.0.62, для версии 11.0.0.61 смотрите Генераторы заданий (старая версия).

Генератор заданий позволяет быстро на основе задания-шаблона создать большое количество подобных заданий.

Шаблоны

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

Например, вопрос может быть записан так: "Переведите двоичное число {%дв_число%}2 в десятичную систему счисления."

Generator62 1.png

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

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


Если задание с вариантами ответа, то в тексте вариантов ответов можно тоже сделать шаблоны.

Generator62b.png

Для заданий с вариантами ответов шаблоны answer1, answer2... answer10 позволяют указать отмечен (значение 1 или true или +) или нет вариант ответа, а для типа сопоставление, с чем сопоставить.


Генератор вместо шаблонов подставит конкретные значения и получится готовое задание.

Для открытия генератора выберите задание-шаблон и дайте команду Задания → Генератор...

Generator62 2.png

Скрипт

Скрипт позволяет подготовить данные для создания заданий. Он пишется на языке программирования JavaScript.

Также вы можете подготовить данные другим способом (например, написав программу на другом языке программирования) и просто их вставить в соответствующее поле.

В скрипте может быть несколько функций, при запуске вызывается функция main(). Она должна подготовить данные для постановки и передать их функции generator(). В контекстном меню (правой кнопкой) поля скрипта есть несколько заготовок, облегчающих понимание и написание своих скриптов.

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

Generator62 3.png

Этот скрипт подготовит данные только для одного задания.

Примечание: если при нажатии кнопки Запустить скрипт удерживать клавишу Shift, то данные будут добавлены к уже имеющимся. Данные для разных заданий отделяются пустой строкой.

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

function main(){
  var m = {};
  for(var i = 0; i < 3; i++){
    m['шаблон'] = 'значение';
    m['answer'] = 3.14;
    //...
    generator(m);
  }
}

Теперь мы получили данные (правда, один и те же) для 3 заданий, т.к. цикл выполнился 3 раза и 3 раза была вызвана функция generator(). Как получить различные данные смотрите ниже.

Генерация

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

Generator62 4.png

Пример скриптов

Вернемся к первому шаблону и напишем рабочий скрипт.

function main(){
  var m = {};
  var a10, a2;
  for(var i = 0; i < 5; i++){
    a10 = randint(25, 50);
    a2 = a10.toString(2);  
    m['дв_число'] = a2;
    m['answer'] = a10;
    generator(m);
  }
}

или

function main(){
  var m = {};
  var a;
  for(var i = 0; i < 5; i++){
    a = randint(25, 50);
    m['дв_число'] = a.toString(2);
    m['answer'] = a;
    generator(m);
  }
}

Примечание: функция randint(a, b) возвращает случайное целое число N из интервала a <= N <= b. Она использует функцию Math.random и для удобства уже прописана в генераторе.

При таком использовании можно получить одинаковые данные (хотя дубликаты заданий и не сложно удалить). Давайте сделаем чтобы мы получили задания для чисел от 25 до 50.

function main(){
  var m = {};
  for(var i = 25; i <= 50; i++){
    m['дв_число'] = i.toString(2);
    m['answer'] = i;
    generator(m);
  }
}

Generator62 5pre.png

Generator62 5.png

Мы получили 26 заданий на основе задания-шаблона. Аналогично можно получить и значительно большее количество.

Входные данные

В новой версии появилась возможность передавать данные в скрипт. Для этого их нужно написать (или скопировать из файла и вставить) в поле "Входные данные".

Давайте создадим задания для чисел в это поле. В заготовках есть пример, как использовать эти входные данные для случая когда они записаны в отдельных строках. Цикл выполнится столько раз, сколько строк в поле "Входные данные".

 
function main(){
  var m = {};
  var a;
  for(var i = 0; i < input.length; i++){
    a = parseInt(input[i]);
    m['дв_число'] = a.toString(2);
    m['answer'] = a;
    generator(m);
  }
}

Generator62 6.png

В предыдущем примере потребовалось входные данные преобразовать в число, т.к. нам требовалось работать с числами. При работе с текстовыми данными это не требуется.

Рассмотрим еще пример. Пусть требуется создать задания по географии "Столица {%страна%}?"

В поле входных данных запишем (или вставим) название страны = название столицы. Вместо = можно использовать любой разделитель (в этом задании пробел и - не подойдут, они могут быть в тексте).

Китай=Пекин
Япония=Токио
Россия=Москва
Индия=Дели
Южная Корея=Сеул
Малайзия=Куала-Лумпур

В этом случае потребуется разбить входную строку на две части (пример есть в заготовках).

function main(){
  var m = {};
  var a;
  for(var i = 0; i < input.length; i++){
    a = input[i].split('=');
    m['страна'] = a[0];
    m['answer'] = a[1];
    generator(m);
  }
}

Generator62 7.png


Вернемся к примеру с числами. Пусть числа записаны в одной строке через запятую. Тогда скрипт можно было записать так:

function main(){
  var m = {};
  var data = input[0].split(',');
  var a;
  for(var i = 0; i < data.length; i++){
    a = parseInt(data[i]);
    m['дв_число'] = a.toString(2);
    m['answer'] = a;
    generator(m);
  }
}

Пример цикл в цикле

Допустим требуется сделать задания на таблицу умножения. Создаем задание "{%a%} ⋅ {%b%} = ?"

Пишем скрипт:

function main(){
  var m = {};
  for(var i = 1; i <= 10; i++){
    for(var j = 1; j <= 10; j++){
      m['a'] = i;
      m['b'] = j;
      m['answer'] = i*j;
      generator(m);
    }
  }
}

И получаем 100 заданий.

Generator62 8.png


Учебник JavaScript

Про JavaScript можно почитать, например, на сайте

https://learn.javascript.ru

Про работу с объектами https://learn.javascript.ru/object

Про работу с массивами https://learn.javascript.ru/array


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

Generator62 noscript.png

Generator62 noscript pas.png