143 lines
8.1 KiB
Markdown
143 lines
8.1 KiB
Markdown
# Основные понятия
|
||
|
||
Для того чтобы составить варианты, вам сперва нужно: 1) написать все задачи/генераторы задач, 2) составить из них пул задач и 3) описать структуру варианта. Разберём по пунктам:
|
||
|
||
1.1 Задача - это основной строительный блок варианта. В `QuizGen` задача представляет собой класс с тремя значениями. Одно обязательные - это вопрос задачи `question`. И два опциональных -- ответ к задаче `answer` и теги `tags` (про которые позже)
|
||
|
||
```{python}
|
||
from modules.task import QTask
|
||
from modules.tag import Tags
|
||
|
||
task = QTask(
|
||
question="Посчитайте дисперсию для следующего ряда: 5, 6, 7, 8, 9",
|
||
answer="2", # можно опустить или не давать ответ: answer = None
|
||
tags=Tags(
|
||
("тема", "дисперсия"),
|
||
("сложность", "лёгкая"),
|
||
...
|
||
) # теги можно определять любые. Первое значение - это категория, второе - это значение в этой категории.
|
||
)
|
||
```
|
||
|
||
1.2 Генератор задач - это класс, с функцией generate(), которая при вызове генерирует задачу `QTask`:
|
||
|
||
```{python}
|
||
from moduels.task.factory.default import QTaskFactoryDefault
|
||
from modules.task import QTask
|
||
from modules.tag import Tags
|
||
|
||
#Сначала определим функцию, которая будет использоваться для генерации задач
|
||
def task_generator_function():
|
||
# генерируем два случайных целых числа от 1 до 9
|
||
alpha = random.randint(1, 9)
|
||
beta = random.randint(1, 9)
|
||
|
||
# Используем сгенерированные числа, чтобы составить задачу
|
||
question = f"Чему равна дисперсия величины V({alpha} * X + {beta} * Y), если X и Y подчинены стандартному нормальному закону распределения и независимы друг от друга?"
|
||
answer = f"{alpha ** 2 + beta ** 2}"
|
||
|
||
return QTask(
|
||
question,
|
||
answer,
|
||
)
|
||
|
||
# С её помощью создадим генератор задач
|
||
variance_task_factory = QTaskFactoryDefault(task_generator_function)
|
||
|
||
# Получаем генератор, который умеет производит задачи с разными числами, каждый раз, когда мы вызываем фукнцию generate():
|
||
|
||
variance_task_factory.generate() # => Чему равна дисперсия величины V(3 * X + 5 * Y), если X и Y подчинены стандартному нормальному закону распределения и независимы друг от друга? Ответ: 34
|
||
|
||
variance_task_factory.generate() # => Чему равна дисперсия величины V(6 * X + 2 * Y), если X и Y подчинены стандартному нормальному закону распределения и независимы друг от друга? Ответ: 40
|
||
```
|
||
|
||
2. Пул задач. Пул - это массив задач и генераторов задач, из которых составляются варианты.
|
||
|
||
```{python}
|
||
from modules.variant_builder.task_pool import QTaskPool
|
||
from modules.task import QTask
|
||
|
||
tasks = [
|
||
QTask(
|
||
question="Текст задачи 1"
|
||
),
|
||
QTask(
|
||
question="Текст задачи 2"
|
||
),
|
||
QTask(
|
||
question="Текст задачи 3"
|
||
),
|
||
variance_task_factory # каждый раз, когда в вариант отбирается генератор, он генерирует для этого варианта новую задачу с уникальными значениями
|
||
]
|
||
|
||
# Инициируем пул задач
|
||
task_pool = QTaskPool(tasks)
|
||
```
|
||
|
||
3. Описание структуры варианта. Для описания структуры варианта используется специальный класс `VariantFactory`. Чтобы его создать, из скольки задач будут состоять варианты, пул задач из которых подбираются задачи и (опционально) правило отбора задач. Если последнее не указать, то будет использоваться правило, которые старается минимизировать число пересечений между любыми двумя вариантами и по возможности равномерно распределить задачи.
|
||
|
||
Чтобы понять, как определяется структура варианта, рассмотрим простой пример. Допустим, мы хотим сделать вариант, состоящий из трёх задач и у каждой задачи есть две вариации.
|
||
|
||
```{python}
|
||
from modules.variant_builder import VariantFactory
|
||
|
||
# Сначала создадим пул задач
|
||
task_pool = QTaskPool([
|
||
# Задача 1
|
||
QTask(
|
||
question="1.1"
|
||
tags=Tag("order", "first") # Тег, чтобы отличать первую задачу от второй и третий
|
||
),
|
||
QTask(
|
||
question="1.2"
|
||
tags=Tag("order", "first")
|
||
),
|
||
|
||
# Задача 2
|
||
QTask(
|
||
question="2.1"
|
||
tags=Tag("order", "second")
|
||
),
|
||
QTask(
|
||
question="2.2"
|
||
tags=Tag("order", "second")
|
||
),
|
||
|
||
# Задача 3
|
||
QTask(
|
||
question="3.1"
|
||
tags=Tag("order", "third")
|
||
),
|
||
QTask(
|
||
question="3.2"
|
||
tags=Tag("order", "third")
|
||
),
|
||
])
|
||
|
||
# Инициируем генератор вариантов
|
||
vf = VariantFactory(number_of_tasks=3, task_pool = task_pool)
|
||
|
||
# Теперь самое главное - укажем, что первая задача в варианте должна быть задачей один, вторая - задачей два, а третья - задачей три
|
||
vf.task[0].must.include_tag("order", "first") # первая задача должна быть задачей с пометкой order = first
|
||
vf.task[1].must.include_tag("order", "second") # вторая задача должна быть задачей с пометкой order = second
|
||
vf.task[2].must.include_tag("order", "third") # первая задача должна быть задачей с пометкой order = third
|
||
|
||
# доступные методы include_all_tags() - должна включать все теги из списка, include_any_tag() - должна включать хотя один тег из списка, be_one_of() - должна быть одной из задач или должна быть сгенерирована определённым генератором, not(lambda b: b.must...) - логическое отрицание, or(lambda b: b.must..., lambda b: b.must...) - логическое или.
|
||
|
||
# Сгенерируем 10 вариантов:
|
||
variants = vf.generate_variants(number_of_variants=10) # можем указать любое число
|
||
```
|
||
|
||
Генератор вариантов сгенерирует 10 вариантов так, чтобы они были максимально уникальны относительно друг друга. Варианты, которые составляет `VariantFactory` представлены классом `QVariant`, который есть просто собрание задач и по сути представляет собой обычный массив:
|
||
|
||
```{python}
|
||
first_variant = variants[0] # первый вариант
|
||
first_task_of_first_variant = first_variant[0] # первая задача первого варианта
|
||
|
||
print(first_task_of_first_variant.question) # => 1.2
|
||
```
|
||
|
||
|
||
|
||
|