Автоматические примеры в условиях

Последняя правка 3792 дня назад
Материал из Daysper manual
Перейти к навигации Перейти к поиску

Традиционно принято, что примеры вписываются в условия задачи вручную, т.е. в TeX-условие задачи просто вручную добавляется соответствующий текст. Daysper поддерживает такую систему (вообще, в TeX-условии задачи вы можете написать практически что угодно), но он позволяет также вставлять в условия автоматически-сгенерированные примеры. А именно, вы можете подготовить тесты из примера просто как тесты к задаче (как отдельный тестсет), после чего daysper будет сам генерировать TeX-файл с этими тестами; вам остается только подключить его в TeX-условие (как правило, командой \input).

Зачем это нужно[править | править код]

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

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

В-третьих, нередко при непосредственном вписывании примера в TeX-условия вам надо заботиться о том, чтобы все служебные символы TeX'а (\, #, { и т.д.) заменить соответствующими командами, а также принимать меры против других особенностей чтения входного файла TeX'ом (например, если вам надо сохранить пробелы в начале строки или несколько пробелов подряд, то могут потребоваться особые меры). При автоматической генерации примеров с использованием daysper вы можете об этом не думать. (Правда, это не связано с тем, что генерация автоматическая, а с тем, что для подключения файлов с примерами можно использовать команду \verbatiminput, см. ниже.)

Как это работает[править | править код]

Для включения автоматической генерации тестов надо установить параметр statement-needs-examples файла daysper.ini в true (по умолчанию он false). Если этот параметр равен false, то daysper не предпринимает никаких действий по генерации тестов. В таком случае .cmd/.sh-скрипт генерации примеров все равно создается, но содержит единственную команду — вывод на экран сообщения

The statement in this problem does not need generated examples, so exiting

Если этот параметр равен true, то по каждой команде, требующей генерации условий (daysper statement, daysper contest statements), а также по команде daysper examples происходит генерация примеров. А именно, происходит следующее:

  • Генерируются тесты тестсета st, т.е. генерируются тесты в соответствии со скриптом do_st.d, который должен находиться в каталоге тестов. В частности, как и при любой генерации тестов, для каждого теста:
    • Запускается валидатор;
    • Если на тест нет ручного answer-файла, то запускается решение (в соответствии с параметром solution файла daysper.ini) для генерации answer-файла, иначе запускается чекер, проверяющий корректность ручного answer-файла;
    • Проверяется правильность работы правильного решения на этом тесте.
Полученные тесты называются _001.in / _001.ans и т.д. и помещаются в каталог statement/_examples. (Технически это выполняется за счет замены параметров inputFormat, outputFormat и tests-directory в настройках daysper, поэтому значения этих параметров, указанные в файлах daysper.ini, не имеют значения при генерации примеров в условия).
  • После этого создается файл statement/_examples.tex с содержимым следующего формата:
\FilesWithExample{examples/_001.in}{examples/_001.ans}\FilesWithExample{examples/_002.in}{examples/_002.ans}%

Подключить этот файл в нужное место условий, а также реализовать TeX-команду \FilesWithExample вы должны сами. (См. также ниже.)

Что надо сделать для автоматической генерации тестов[править | править код]

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

Глобальная подготовка[править | править код]

Конечно, в TeX-файл вы, вообще говоря, можете написать что угодно; строгая спецификация того, что делает daysper, указана выше. Ниже приведены некоторые рекомендации; вы можете поступать и по-другому. В частности, можно совмещать автогенерируемые тесты и тесты, прописанные в условии задачи, если вы сможее сделать это так, чтобы TeX не ругался.

Скорее всего, сгенерированные примеры в условия вы будете вставлять командой \input{_examples.tex}. Вам надо решить, в каком контексте TeX-файла вы будете вставлять эту команду и в соответствии с этим предоставить команду \FilesWithExample (скорее, всего, изменив стилевой или классовый файл TeX или прописав нужный код в прологе). Эта команда должна принимать два параметра — имена файлов с примером входного и выходного файла очередного теста.

Общая идеология[править | править код]

Здесь описаны общие советы по реализации команды \FilesWithExample; конкретные инструкции для olymp.sty см. ниже.

Вообще говоря, если вы вставляете примеры в TeX-условия вручную, то у вас в TeX-условиях будет некоторый код, повторяющийся для каждого примера. Этот код и надо вынести в команду \FilesWithExample. При этом непосредственно текст примеров надо считать из файла; для этого можно воспользоваться командой \verbatiminput пакета verbatim, которая вставляет указанный файл как если бы он был набран в окружении verbatim.

Конкретно, можно использовать конструкцию

{\topsep=0cm\partopsep=0cm\raisebox{1.3ex}{\parbox[t]{\textwidth}{\verbatiminput{#1}}}}

для вставки содержимого файла #1 с адекватными пробелами, отступами и т.д. Возможно, вам захочется изменить ширину у \parbox (если \textwidth почему-либо не сработает) или добавить \vspace в конце.

Например, если ручные примеры вы вставляете в TeX-условия конструкцией

\begin{example}
2 3
4%
&5%
\\\hline
6 8
10%
&-2%
\\\hline
\end{example}

то команду \FilesWithExample можно определить так:

\newcommand{\FilesWithExample}[2]{%
\topsep=0cm\partopsep=0cm\raisebox{1.3ex}{\parbox[t]{\textwidth}{\verbatiminput{#1}\vspace*{0.1cm}}}% 
&% 
\topsep=0cm\partopsep=0cm\raisebox{1.3ex}{\parbox[t]{\textwidth}{\verbatiminput{#2}\vspace*{0.1cm}}}% 
\\\hline} 

после чего в условиях писать

\begin{example}%
\input{_examples.tex}%
\end{example}

(Обратите внимание на использование символов процент для предотвращения возможных ненужных пробелов.)

Использование olymp.sty[править | править код]

Если вы используете olymp.sty, то можете добавить в него (или в пролог) следующий код:

\newcommand{\FilesWithExample}[2]{%
\exmp%
{\topsep=0cm\partopsep=0cm\raisebox{1.3ex}{\parbox[t]{\textwidth}{\verbatiminput{#1}}}}%
{\topsep=0cm\partopsep=0cm\raisebox{1.3ex}{\parbox[t]{\textwidth}{\verbatiminput{#2}}}}%
}

Кроме того, чтобы в начале первого из автогенерируемых примеров не появлялся лишний отступ слева, в olymp.sty надо добавить процент в конец первой строки определения команд \exmp:

\newcommand{\exmp}[2]{

надо заменить на

\newcommand{\exmp}[2]{%

(Эта строка входит в olymp.sty два раза: первый раз в определении окружения example, второй раз — в examplewide. В первом вхождении замену надо сделать точно, во втором — скорее всего, но я не проверял. Совместимость со старыми TeX-условиями при этом сохранится.)

После этого в условиях задач надо писать

\begin{example}
\input{_examples.tex}%
\end{example}

или даже, если вы хотите совместить генерируемые тесты с негенерируемыми (что не рекомендуется):

\begin{example}
\exmp{2 3}{4}%
\input{_examples.tex}%
\end{example}

Подготовка задачи[править | править код]

Для подготовки задачи вам надо, во-первых, установить в этой задаче параметр statement-needs-examples файла daysper.ini; как правило, это надо сделать в файле daysper.ini, расположенном в каталоге задачи. (Если у вас есть целое дерево каталогов-задач, в которых все используют автоматические примеры, то этот параметр можно прописать и в файле daysper.ini более высокого уровня.)

Далее, вам надо подготовить тестсет st (см. ниже) и вставить в TeX-условие команду \input{_examples.tex} в соответствии с вашими настройками TeX'а (см. предыдущую секцию). После этого команды d examples и d statement должны работать (или выдавать адекватные сообщения об ошибке, например, если тесты неправильные).

Подготовка тестсета st[править | править код]

Как правило, при подготовке тестов в условия вы не используете генераторы; все входные данные у вас полностью ручные. (Хотя, конечно, при желании вы можете использовать всю мощь языка .d-файлов.)

Поэтому вы подготавливаете ручные входные файлы для примеров. Если по какому-то примеру вы хотите использовать ручной ответ (в частности, если вы не хотите использовать тот ответ, который выдаст правильное решение, а использовать другой ответ), то подготовьте также и эти файлы. Размещайте файлы в каталоге тестов.

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

copy st01.hand ^t+
copy st01.hand.a ^a*
copy st02.hand ^t+

или

for -f $i in st??.hand
  copy $i ^t+
  copy {$i}.a ^a*
endfor

(в первом примере для первого теста есть ручной файл ответа, а для второго — нет.)

Конечно, кроме этого, надо написать чекер, валидатор, и правильное решение.

Проверить тестсет можно или командой d examples, или просто командой d build + st.