Идея: номера тестов

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

Почему генераторы не должны знать имен файлов с тестами[править | править код]

...Десять лет назад было принято называть input- / answer-файлы 1_1.TST / 1_1.ANS, 1_2.TST / 1_2.ANS, ... (где первая единица — номер задачи). Сейчас тесты иногда принято называть 01 / 01.a, 02 / 02.a и т.д. Что будет через 10 лет, неизвестно...

Кроме того, сейчас иногда принято называть тесты 001 / 001.а и т.п. Хочется, чтобы можно было взять задачу с контеста, использовавшего один формат названий, и, не изменяя ее, использовать на другом контесте. Но для этого надо, чтобы в самой задаче нигде не были жестко прописаны имена input- и answer-файлов.

Далее, концепция тестсетов также подразумевает возможность конкатенации тестсетов в любом порядке. Например, если есть отдельный тестсет st с двумя тестами из условия, и основной тестсет all с 20 тестами, то можно генерировать все 22 теста в порядке st, all. Можно (если есть желание) сгенерировать 22 теста в порядке all, st. А можно вообще сгенерировать только тестсет all без тестов st. Но тогда вообще заранее неизвестно, какой тест будет иметь какой номер: например, первый тест тестсета st может оказаться первым вообще, а может 21-м; первый тест тестсета all может оказаться 1-м, а может 3-м.

Поэтому генераторы и скрипты генерации тестов не должны в явном виде содержать номеров тестов. Вместо этого в скрипте генерации тестов (в .d-файле) должны использоваться шаблоны имен файлов. При генерации задачи, а также при экспортировании задачи daysper сам заменит их на правильные имена файлов с учетом того, каким по счету все-таки оказался этот тест и какой формат имен установлен в параметрах inputFormat и answerFormat файла daysper.ini

Использовать шаблоны не так сложно, как может показаться. Примеры:

Ручные файлы с тестами[править | править код]

Как назвать ручные файлы, не важно (точнее, важно, чтобы они случайно не совпали с окончательными названиями для файлов с тестами). Пусть мы их решили назвать 01.hand/01.hand.a и т.д. Тогда в .d-файле пишите

copy 01.hand ^t+
copy 01.hand.a ^a*

и т.д.

Если у вас ручных тестов очень много, то можно написать цикл:

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

Можно также использовать цикл по числам, это особенно помогает, если, например, ручные тесты называются 01.hand/01.a.hand

for $i from 1 to 12 format %02d
  copy {$i}.hand ^t+
  copy {$i}.a.hand ^a*
endfor

Генератор, выводящий тест в консоль[править | править код]

Пишем

gen > ^t+

Генератор, принимающий имя файла, который он должен создать, в качестве параметра командной строки[править | править код]

Т.е. пусть ваш генератор единственным параметром командной строки принимает название файла, куда он должен вывести тест. Тогда все совсем просто:

gen ^t+

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

gen ^t+ ^a*

Генератор, выводящий тест(ы) в файл с фиксированным именем[править | править код]

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

gen
copy test ^t+

где test — имя созданного файла.

В таком случае есть опасность, что генератор может перезаписать ранее сгенеренные тесты; поэтому генератор не должен создавать файл(ы) с именами, которые могут оказаться настоящими именами input-/answer-файлов.

Если когда-нибудь будет дописано перенаправление в формате a=b (см. планы развития языка), то можно будет писать

gen test=^t+

Генератор, создающий сразу много тестов[править | править код]

Если генератор выводит сразу много тестов (мое мнение, что это совсем неправильно, по ряду причин — П.К., *KAP*), то пишите

gen
copy 01.gen ^t+
copy 02.gen ^t+

и т.д.; считаю, что 01.gen и т.д. — имена файлов, генерируемых генератором.

Или организуете цикл:

gen
for -f $i in ??.gen
  copy $i ^t+
endfor

или

gen
for $i from 1 to 12 format %02d
  copy {$i}.gen ^t+
  copy {$i}.ans.gen ^a*
endfor

(в этом примере еще показано, что можно сделать, если генератор создает не только тесты, но и answer-файлы).

Тут тоже есть опасность, что генератор может перезаписать ранее сгенеренные тесты; поэтому генератор не должен создавать файл(ы) с именами, которые могут оказаться настоящими именами input-/answer-файлов.