Quizard/docs/quick_start.md
2025-04-28 22:02:51 +03:00

8.1 KiB
Raw Blame History

Основные понятия

Для того чтобы составить варианты, вам сперва нужно: 1) написать все задачи/генераторы задач, 2) составить из них пул задач и 3) описать структуру варианта. Разберём по пунктам:

1.1 Задача - это основной строительный блок варианта. В QuizGen задача представляет собой класс с тремя значениями. Одно обязательные - это вопрос задачи question. И два опциональных -- ответ к задаче answer и теги tags (про которые позже)

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:

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
  1. Пул задач. Пул - это массив задач и генераторов задач, из которых составляются варианты.
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)
  1. Описание структуры варианта. Для описания структуры варианта используется специальный класс VariantFactory. Чтобы его создать, из скольки задач будут состоять варианты, пул задач из которых подбираются задачи и (опционально) правило отбора задач. Если последнее не указать, то будет использоваться правило, которые старается минимизировать число пересечений между любыми двумя вариантами и по возможности равномерно распределить задачи.

Чтобы понять, как определяется структура варианта, рассмотрим простой пример. Допустим, мы хотим сделать вариант, состоящий из трёх задач и у каждой задачи есть две вариации.

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, который есть просто собрание задач и по сути представляет собой обычный массив:

first_variant = variants[0] # первый вариант
first_task_of_first_variant = first_variant[0] # первая задача первого варианта

print(first_task_of_first_variant.question) # => 1.2