|
|
Основные компоненты
Определение общих характеристик группы заданий
При создании новой группы заданий требуется определить следующие характеристики этой группы:
- имя группы (GroupName) текстовая строка, содержащая от 1 до 25 символов
цифр и латинских букв, причем последний символ не может быть цифрой
(если имя группы содержит более 9 символов, то она считается особой библиотечной группой,
работа с которой отличается от работы с обычной группой); запрещается использовать имена стандартных групп задачника (Begin, Integer и т. д.);
имена, различающиеся только регистром букв, считаются совпадающими;
- описание группы (GroupDescription) непустая текстовая строка с кратким описанием данной группы; при генерации
полного описания группы в виде html-страницы данная строка указывается в качестве заголовка этого описания;
- сведения об авторе (GroupAuthor)
текстовая строка с информацией о разработчике данной группы (фамилия, инициалы, год разработки, e-mail и т. п.; строка может быть пустой);
- ключ группы (GroupKey) непустая текстовая строка с произвольным набором символов, позволяющая в дальнейшем
идентифицировать в файле результатов results.dat и results.abc те выполненные задания, которые относятся к данной группе;
- количество заданий в группе (TaskCount) целое число в диапазоне от 1 до 999, определяющее количество заданий в группе;
- основная процедура группы заданий (InitTaskProc) процедура с одним параметром типа integer,
обеспечивающая инициализацию всех заданий данной группы (параметр данной процедуры определяет номер задания в пределах группы).
Из перечисленных характеристик в дополнительном комментарии нуждается ключ группы. Если не использовать подобную
характеристику, то становится невозможной идентификация группы, к которой относятся задания, выполненные учащимся.
Действительно, имя задания, сохраненное в файле результатов, не позволяет однозначно его идентифицировать, поскольку
ничто не мешает разработать другую группу с тем же именем и совершенно другими заданиями, после чего «подменить»
ею исходную группу. Проблему решает использование ключа группы, который сложно подделать, так как он известен только разработчику
группы. При успешном выполнении задания в файл результатов дополнительно записывается идентификатор группы, вычисляемый
на основе ее ключа и позволяющий однозначно определить группу, к которой относится выполненное задание. Поскольку информация, связанная
с идентификаторами групп, представляет интерес только для преподавателя, ознакомиться с ней можно только с помощью программы
«Контрольный центр преподавателя» (см. команду «Check-файлы |
Просмотреть файл check.inf»).
Примечание. При выводе краткого описания группы в программных модулях PT4Demo и PT4Load первый символ этого описания
преобразуется к нижнему регистру (поскольку текст описания располагается в этих модулях после двоеточия).
Если понижать регистр первого символа
не следует (в случае, если этот символ является началом фамилии или некоторой аббревиатуры, например, «ЕГЭ»),
то в начале краткого описания группы надо указать дополнительный символ-метку «^» (шапочка).
Пример использования символа «^» приводится в разделе
«Разработка групп заданий, связанных с ЕГЭ по информатике».
Для определения характеристик новой группы необходимо вызвать процедуру CreateGroup,
указав эти характеристики в качестве параметров:
procedure CreateGroup(GroupName, GroupDescription, GroupAuthor,
GroupKey: string; TaskCount: integer; InitTaskProc: TInitTaskProc);
Тип TInitTaskProc является процедурным типом и определяется следующим образом:
type TInitTaskProc = procedure(n: integer); stdcall;
Процедуру CreateGroup необходимо вызывать в процедуре inittaskgroup, которая должна экспортироваться библиотекой, содержащей данную группу. При реализации
группы в виде pcu-файла системы PascalABC.NET процедура inittaskgroup должна вызываться в секции инициализации модуля, содержащего определение новой группы заданий.
Основная процедура группы (типа TInitTaskProc) при ее описании в библиотеке должна иметь модификатор stdcall
(в модуле PascalABC.NET этот модификатор не требуется).
Процедура CreateGroup контролирует правильность переданных ей параметров и в случае ошибки выводит на экран информационное окно
с ее описанием. В подобной ситуации все последующие действия, связанные с определением данной группы, игнорируются, и группа
не включается в список доступных для использования групп заданий. Перечислим некоторые из возможных ошибок:
- в процедуре inittaskgroup определяется более одной группы заданий (в этом случае определения всех групп, кроме первой, игнорируются);
при реализации групп в виде pcu-файла данное ограничение отсутствует;
- имя группы не соответствует имени dll-файла, в котором данная группа определяется (напомним, что имя dll-файла должно иметь вид
PT4<имя группы> или PT4<имя группы><маркер локали>);
при реализации группы в виде pcu-файла данное ограничение отсутствует;
- к задачнику Programming Taskbook уже подключена группа с указанным именем;
- имя группы не является допустимым (в частности, совпадает с именем одной из базовых групп задачника);
- не указано краткое описание группы;
- не указан ключ группы;
- количество заданий не принадлежит диапазону 1999;
- процедурная переменная InitTaskProc равна nil.
Базовые константы и процедуры для создания новых заданий
const
xCenter = 0;
xLeft = 100;
xRight = 200;
Эти константы, отвечают за выравнивание
данных по горизонтали: константа xCenter
центрирует текст, связанный с элементом данных, относительно всей экранной
строки, константы xLeft и xRight центрируют текст в
пределах левой и правой половины экранной строки соответственно.
Используются в качестве
параметра X в процедурах групп Data и Result, а также в процедуре TaskText.
procedure CreateTask(SubgroupName: string);
procedure CreateTask;
Данная процедура должна быть вызвана первой
при инициализации нового задания; в качестве параметра SubgroupName указывается заголовок подгруппы,
в которую включается задание (задания целесообразно разбивать на подгруппы, если их количество в группе является достаточно
большим; в случае деления группы на подгруппы каждое задание рекомендуется связывать с какой-либо подгруппой).
Если параметр является пустой строкой или отсутствует, то задание не связывается с какой-либо подгруппой.
В окне задачника заголовок подгруппы выводится над именем задания; если подгруппа для данного задания не указана, то
выводится краткое описание всей группы (определенное в параметре GroupDescription процедуры CreateGroup).
При выводе краткого описания группы или заголовка подгруппы в окне задачника его текст преобразуется к верхнему регистру.
В версии 4.9 конструктора учебных заданий к первоначальным двум вариантам процедуры CreateTask были добавлены еще два
варианта, предназначенные для инициализации задания по параллельному MPI-программированию.
procedure TaskText(S: string; X, Y: integer);
Данная процедура добавляет к формулировке задания строку S,
которая располагается в строке Y (от 1 до 5) раздела формулировки
задания, начиная с позиции X. Позиции нумеруются от 1; при указании параметра X следует учитывать, что
ширина раздела формулировок (как и разделов исходных и результирующих данных) равна 78 символам.
Кроме явного указания значения позиции X можно использовать специальные константы xCenter, xLeft и xRight; в частности,
если параметр X равен 0, то строка центрируется. Рекомендуется всегда центрировать строки
в формулировках заданий (как это делается в базовых группах, входящих в задачник); явное указание позиции X следует использовать лишь
при выводе многострочных формул и в других случаях специального выравнивания текста.
Все строки должны добавляться к формулировке последовательно; при этом если формулировка содержит 1 строку, то ее следует располагать
на экранной строке с номером 3, если 2 строки на экранных строках 2 и 4, если 3 строки на экранных строках 2, 3 и 4, если
4 строки на экранных строках с номерами от 2 до 5 (именно так оформляются задания в базовых группах задачника).
Нарушение порядка добавления строк не проявится при отображении формулировки в окне задачника, однако приведет к неверному выводу формулировки
в html-описании группы.
Кроме пяти строк с основным текстом формулировки, который отображается на экране при выводе задания,
можно указывать дополнительные строки, отображаемые на экране при прокрутке текста задания (связанные с прокруткой кнопки
отображаются в окне задачника справа от раздела формулировок, если в формулировке текущего задания имеются дополнительные строки).
Все дополнительные строки, как и основные, должны добавляться к формулировке последовательно, причем параметр Y для таких строк
надо положить равным 0. Максимальное количество дополнительных строк равно 200.
В строке S можно использовать управляющие
последовательности.
Если при выводе строки S часть ее не умещается на экранной строке, то выводится сообщение об ошибке «Ошибочное позиционирование
по горизонтали». Если ошибка произошла при выводе основной строки, то лишняя часть строки S отображается на следующей строке
(или на первой строке, если ошибочной является пятая строка в разделе формулировок).
Определенный с помощью процедур TaskText текст формулировки задания используется также при формировании html-описания группы.
В этом случае деление на строки, указанное для экранного вывода, игнорируется, однако учитываются дополнительные управляющие
последовательности, позволяющие разбивать текст на абзацы с различным способом выравнивания (на отображение текста в окне задачника
эти дополнительные последовательности не влияют).
Если при определении задания не указана его формулировка, то выводится сообщение об ошибке.
procedure DataB (Cmt: string; B: boolean; X, Y: integer);
procedure DataN(Cmt: string; N: Integer; X, Y, W: integer);
procedure DataN2(Cmt: string; N1, N2: Integer; X, Y, W: integer);
procedure DataN3(Cmt: string; N1, N2, N3: Integer; X, Y, W: integer);
procedure DataR(Cmt: string; R: real; X, Y, W: integer);
procedure DataR2(Cmt: string; R1, R2: real; X, Y, W: integer);
procedure DataR3(Cmt: string; R1, R2, R3: real; X, Y, W: integer);
procedure DataC(Cmt: string; C: char; X, Y: integer);
procedure DataS(Cmt: string; S: string; X, Y: integer);
Процедуры группы Data добавляют к заданию элементы исходных
данных. Добавленные элементы, вместе со строкой-комментарием Cmt,
отображаются в разделе исходных данных, начиная с позиции X строки
Y (позиции и строки нумеруются от 1; ширина экранной строки равна 78 позициям). Если используются значения параметра Y, большие 5, то разделе
исходных данных будет доступна прокрутка.
Как и для процедуры TaskText, параметр X может принимать три особых
значения: 0 (центрирование по горизонтали относительно всей экранной строки),
100 (центрирование по горизонтали относительно левой половины экранной строки),
200 (центрирование по горизонтали относительно правой половины экранной строки). Эти значения можно также задавать
с помощью констант xCenter, xLeft и xRight.
Параметр W определяет ширину поля вывода для числовых данных (выравнивание
всегда производится по правому краю поля вывода). Если ширины поля вывода недостаточно, то
значение параметра W игнорируется, и для вывода элемента используется минимально необходимое число
экранных позиций. При определении ширины поля вывода для вещественного числа следует учитывать
размер отображаемой дробной части (который определяется процедурой SetPrecision, описываемой далее).
Для нечисловых данных ширина поля вывода полагается равной фактической ширине данных;
в частности, для данных символьного типа отводятся 3 позиции, содержащие начальный апостроф,
собственно символ и конечный апостроф, а для логического типа отводятся 5 позиций, достаточных
для вывода названий обеих логических констант в любом используемом языке программирования.
Для строки отводятся L + 2 позиции, где L длина строки (начальная и конечная позиции
используются для вывода апострофов). В зависимости от текущего языка программирования используются либо
одинарные, либо двойные апострофы.
Используя процедуры группы Data, в задание можно включить до 200 различных скалярных исходных данных (при этом следует
учитывать, что некоторые процедуры, например, DataN2 и DataN3, добавляют в набор исходных данных несколько элементов).
Наложение различных элементов в разделе исходных данных задачником не контролируется, поэтому при размещении данных
следует обращать особое внимание на то, чтобы последующие элементы не скрывали предыдущие. Кроме того, важен порядок
определения исходных данных, так как именно в этом порядке данные будут передаваться программе учащегося, выполняющей это задание.
Следует придерживаться стандартных правил, принятых в базовых группах задачника: данные должны перебираться по строкам
(в направлении сверху вниз), а в пределах каждой строки слева направо.
В параметре Cmt, содержащем текст комментария к определяемому элементу исходных данных, можно использовать
управляющие последовательности (например, для отображения индексов).
В любом задании должен быть задан хотя бы один элемент исходных данных; в противном случае выводится сообщение об ошибке.
procedure DataComment(Cmt: string; X, Y: integer);
Процедура позволяет добавлять в раздел исходных данных комментарий Cmt,
не связанный с каким-либо элементом исходных данных. Этот комментарий использует ресурсы, выделяемые для
хранения исходных данных, поэтому общее число подобных комментариев, вместе с общим числом исходных данных, не должно
превосходить 200. Смысл параметров
X и Y тот же, что и для процедур
группы Data.
procedure ResultB (Cmt: string; B: boolean; X, Y: integer);
procedure ResultN(Cmt: string; N: Integer; X, Y, W: integer);
procedure ResultN2(Cmt: string; N1, N2: Integer; X, Y, W: integer);
procedure ResultN3(Cmt: string; N1, N2, N3: Integer; X, Y, W: integer);
procedure ResultR(Cmt: string; R: real; X, Y, W: integer);
procedure ResultR2(Cmt: string; R1, R2: real; X, Y, W: integer);
procedure ResultR3(Cmt: string; R1, R2, R3: real; X, Y, W: integer);
procedure ResultC(Cmt: string; C: char; X, Y: integer);
procedure ResultS(Cmt: string; S: string; X, Y: integer);
Процедуры данной группы добавляют к заданию элементы результирующих данных
вместе с их контрольными значениями. Комментарии Cmt к
результирующим данным сразу отображаются в разделе результатов. Контрольные
значения отображаются в разделе «Пример верного решения». Смысл параметров
X, Y и W тот же, что и для процедур
группы Data. Задание может содержать до 200 скалярных элементов результирующих данных.
Как и в случае исходных данных, если элемент контрольных данных не умещается в поле, выделенном для его
отображения (шириной W позиций), то параметр W игнорируется, и для вывода используется минимально необходимое число
экранных позиций. Однако если элемент результирующих данных, переданный
в задачник программой, решающей задание, не «уложится» в размер, выделенный для соответствующего
элемента контрольных данных, то
в правой позиции поля вывода для этого элемента отобразится символ «*» (звездочка) красного цвета.
Подобная ситуация возможна как для чисел, так и для строк (если программа учащегося выведет число или строку,
размер которых больше требуемого).
Для того чтобы в этой ситуации увидеть полный текст всех подобных элементов результирующих данных, следует
переместить курсор мыши в раздел результатов в окне задачника; через 12 секунды
полный текст всех данных, размер которых превышает допустимый, появится во всплывающей подсказке.
Порядок вызова процедур группы Result важен, так как он соответствует порядку, в котором результирующие данные, полученные
программой учащегося, должны передаваться задачнику для проверки их правильности. Поэтому, как и для исходных данных,
для набора результирующих данных должен соблюдаться стандартный
порядок их размещения: сверху вниз по строкам и слева направо в каждой строке.
В параметре Cmt, содержащем текст комментария к определяемому элементу результирующих данных, можно использовать
управляющие последовательности.
Проверка правильности результатов, полученных программой учащегося, выполняется путем сравнения текста, изображающего
эти результаты в окне задачника, с текстом, изображающим соответствующие контрольные данные. Это означает, в частности,
что вычислительная погрешность, возникающая при обработке вещественных чисел, не будет влиять на проверку правильности,
если при отображении этих чисел не используется слишком большое количество дробных знаков (напомним, что число
дробных знаков можно задать с помощью процедуры SetPrecision).
В любом задании должен быть задан хотя бы один элемент результирующих данных; в противном случае выводится сообщение об ошибке.
procedure ResultComment(Cmt: string; X, Y: integer);
Процедура позволяет добавлять в раздел результатов комментарий Cmt,
не связанный с каким-либо элементом результирующих данных. Этот комментарий использует ресурсы, выделяемые для
хранения результирующих данных, поэтому общее число подобных комментариев, вместе с общим числом результирующих данных, не должно
превосходить 200. Смысл параметров
X и Y тот же, что и для процедур
группы Data.
procedure SetPrecision(N: integer);
Процедура устанавливает количество N дробных знаков,
используемое в дальнейшем при выводе всех элементов данных вещественного типа.
По умолчанию количество дробных знаков равно 2. Если оно равно 0, то
вещественные данные отображаются в экспоненциальном формате, а количество дробных знаков определяется
шириной поля вывода, указанной для данного числа. Действие текущей настройки,
определенной процедурой SetPrecision, продолжается до очередного вызова этой процедуры, однако
не распространяется на другие учебные задания текущей группы. Заметим, что при отображении вещественных чисел
в качестве десятичного разделителя всегда используется точка.
procedure SetRequiredDataCount(N: integer);
Процедура определяет минимально необходимое количество N
элементов исходных данных, требуемое для правильного решения задания при текущем
наборе исходных данных. По умолчанию это количество равно общему числу всех
указанных в задании исходных данных. Если параметр N имеет нулевое или отрицательное значение, то
выводится сообщение об ошибке; если значение параметра превышает общее число элементов исходных данных, то
сообщение об ошибке не выводится, а требуемое количество исходных данных полагается равным их
общему количеству.
Примером задания, в котором необходимо использовать данную процедуру, может служить задание Series10.
В этом задании дается набор из N целых чисел и требуется вывести True, если данный набор содержит положительные числа,
и False в противном случае. Ясно, что если при считывании элементов набора будет обнаружено положительное число, то
можно сразу выводить значение True и завершать выполнение задания. Однако если
при подготовке задания не указать минимально необходимое
число исходных данных с помощью процедуры SetRequiredDataCount, то по умолчанию будет считаться, что для решения
необходимо прочесть все исходные данные, и приведенный выше
правильный вариант решения будет расценен как ошибочный (при этом будет выведено
сообщение «Введены не все требуемые исходные данные»).
Если заданное с помощью процедуры SetRequiredDataCount количество требуемых исходных данных
меньше их общего количества,
то программа учащегося не обязана считывать все исходные данные: достаточно прочесть только требуемые.
Однако если программа прочтет все данные и выведет правильный ответ, это также будет считаться
верным вариантом решения.
При выполнении заданий по параллельному программированию во
всех процессах параллельной программы должны быть введены все
связанные с ними исходные данные. Поэтому попытка вызова процедуры
SetRequiredDataCount(N) с параметром N, значение которого меньше
общего числа исходных данных, приведет в задании по параллельному
программированию к сообщению об ошибке.
procedure SetTestCount(N: integer);
Процедура определяет количество N успешных тестовых испытаний программы
учащегося, необходимое для того, чтобы задание было зачтено как выполненное.
По умолчанию количество тестовых испытаний полагается равным 5.
Значение N должно находиться в пределах от 2 до 9; при указании других вариантов параметра N выводится сообщение об ошибке.
После каждого успешного тестового испытания в окне задачника выводится сообщение (на зеленом фоне), в котором
указывается номер испытания и общее число тестов, необходимых для выполнения данного задания, например:
«Верное решение. Тест номер 2 (из 5)».
Если при очередном тестовом испытании программы ею будет получено ошибочное решение, то счетчик
успешных тестов будет сброшен в 0, и тестирование (после исправления обнаруженной ошибки) придется начинать заново.
function Center(I, N, W, B: integer): integer;
Вспомогательная функция, которая позволяет размещать по центру экранной
строки набор из N элементов данных одинаковой ширины. Эта функция
возвращает горизонтальную координату, начиная с которой следует выводить I-й
элемент набора (I меняется от 1 до N) при условии, что
ширина каждого элемента равна W позициям, а между элементами надо
указывать B пробелов. Функция Center обычно используется
в качестве параметра X в процедурах групп Data и
Result при выводе однотипных наборов данных (в частности, элементов массива).
В качестве примера приведем фрагмент, обеспечивающий формирование и вывод в разделе исходных данных
массива вещественных чисел:
n := 2 + Random(9);
DataN('N = ', n, 0, 2, 1);
for i := 1 to n do
begin
a[i] := 9.99 * Random;
DataR('', a[i], Center(i, n, 4, 2), 4, 4);
end;
Вначале (во второй строке области исходных данных) выводится размер N массива,
определяемый с помощью датчика случайных чисел и принимающий значения в диапазоне от 2 до 10
(он снабжается комментарием «N =»). Затем (в четвертой строке) выводятся сами элементы
массива, причем благодаря использованию функции Center весь список выравнивается относительно центра экранной строки
независимо от количества элементов. Целые части всех элементов лежат в диапазоне от 0 до 9, т. е.
представляются одной цифрой, одна позиция отводится под отображение десятичного разделителя-точки и по умолчанию
указываются два дробных знака, поэтому для каждого элемента следует выделить 4 экранных позиции; это число указывается дважды:
как второй параметр функции Center и как последний параметр процедуры DataR. Промежуток между элементами полагается равным
2 экранным позициям (это последний, четвертый параметр функции Center).
Обратите внимание на то, что при использовании
функции Center строку комментария следует оставлять пустой.
Прокрутка разделов исходных данных и результатов
Начиная с версии 4.9 конструктора учебных заданий,
для процедур групп Data и Result, в том числе DataComment и ResultComment,
в качестве параметра Y разрешено указывать значение, превышающее 5.
Если значение параметра Y для некоторого
элемента раздела исходных данных превышает 5, то этот элемент
размещается в строке с указанным номером, а в разделе
исходных данных становится доступной прокрутка. Аналогичным
образом, прокрутка будет доступна в разделе результатов, если хотя бы
один элемент этого раздела помещен в него процедурой с параметром Y,
превышающим 5. Если оба раздела допускают прокрутку, то она
выполняется независимо. Прокрутку в любом разделе можно выполнять с
помощью клавиатуры или мыши; в последнем случае следует использовать
кнопки , расположенные справа от прокручиваемого раздела.
В задании запрещено использовать прокрутку раздела, если в нем уже имеется
«внешний» объект (файл или
динамическая структура). Если
делается попытка вызвать какую-либо процедуру с параметром Y,
большим 5, для раздела, уже содержащего внешний объект, то выводится
сообщение об ошибке «При наличии внешних объектов режим
прокрутки для всего раздела недоступен». Если же в разделе,
уже имеющем элементы данных или комментарии, размещенные в
неотображаемых строках, делается попытка разместить внешний объект,
то выводится сообщение об ошибке «Раздел данных в режиме
прокрутки не может содержать внешние объекты».
Возможность прокрутки разделов исходных и результирующих данных добавлена, прежде всего,
для использования в заданиях по параллельному программированию.
Однако она может оказаться полезной и в других случаях, например, при
использования в качестве исходных данных
нескольких двумерных массивов или массива строк.
Заметим, что ни в одном из 1100 заданий, входящих в базовый набор задачника Programming Taskbook,
прокрутка разделов исходных и результирующих данных не используется.
Импортирование существующих заданий в новую группу
procedure UseTask(GroupName: string; TaskNumber: integer);
Данная процедура позволяет импортировать в создаваемую группу задание
с номером TaskNumber из группы GroupName.
Она обычно вызывается непосредственно в основной процедуре группы. Если импортируемое задание не найдено,
то при попытке его запуска в окне задачника выводится сообщение «Задание не реализовано для текущего языка
программирования», и этот же текст, выделенный курсивом, указывается в html-описании группы после имени,
которое должно быть связано с импортированным заданием.
При использовании мини-варианта задачника импортированные задания будут доступны для выполнения только в том случае,
если они доступны для выполнения в базовых группах.
В параметре GroupName после имени группы можно дополнительно указывать поправку для вычисления
ссылки на другое задание (поправка является целым числом и отделяется от имени группы
символом #). Например, если в группу Demo в качестве задания Demo10 импортируется
задание Proc46, а в качестве Demo11 задание Proc49, ссылающееся на Proc46, то при импортировании
задания Proc49 необходимо указать поправку, равную 2. Если этого не сделать, то в формулировке
задания Demo11 будет указана ссылка не на задание Demo10, а на задание Demo8 (поскольку оно находится
«на том же расстоянии» от задания Demo11, что и задание Proc46 относительно задания Proc49).
Добавление поправки 2 должно быть оформлено следующим образом: UseTask('Proc#2',49).
Примечание. Если новая группа заданий разрабатывается в среде PascalABC.NET, а группа, из которой импортируются задания,
также была разработана в PascalABC.NET и, следовательно, содержится в некотором pcu-модуле, то в список uses модуля с новой группой
необходимо добавить имя модуля, содержащего группу, из которой импортируются задания.
Документирование группы заданий
Группы заданий можно снабжать комментариями, делая их «самодокументируемыми».
Комментарии можно добавлять не только к группе, но и к ее подгруппам, т. е. наборам подряд идущих заданий в пределах группы
(для включения задания в определенную подгруппу
необходимо указать заголовок этой подгруппы в качестве параметра процедуры CreateTask).
Комментарии не отображаются в окне задачника, но включаются в html-описание группы.
Они располагаются между заголовком группы (подгруппы)
и формулировками заданий. Таким образом, эти комментарии представляют собой преамбулы к группе или ее подгруппам.
Определять преамбулу к подгруппе имеет смысл только в случае, если с этой подгруппой связаны некоторые задания,
входящие в определяемую группу. Если группа не содержит заданий, связанных
с некоторой подгруппой, то преамбула этой подгруппы в html-описании не выводится.
Для определения преамбул предназначены
следующие процедуры.
procedure CommentText(S: string);
Данная процедура добавляет содержимое строки S к текущей преамбуле,
отделяя это содержимое от предыдущего текста преамбулы пробелом.
В строке S можно использовать управляющие последовательности, обеспечивающие ее
форматирование. Например, для перехода к новому абзацу преамбулы следует использовать последовательность
\P (управляющие последовательности чувствительны к регистру букв).
procedure UseComment(GroupName, SubgroupName: string);
procedure UseComment(GroupName: string);
Процедура UseComment добавляет к текущей преамбуле текст преамбулы подгруппы SubgroupName
группы GroupName или, если параметр SubgroupName является пустой строкой или отсутствует, текст преамбулы самой
группы GroupName. Этот текст
отделяется от предыдущего текста преамбулы пробелом. Регистр символов в параметрах GroupName и SubgroupName
может быть произвольным.
Если группа с именем GroupName не найдена или в ней отсутствует подгруппа SubgroupName, то процедура не выполняет никаких действий;
сообщение об ошибке в этом случае не выводится.
Примечание. Если новая группа заданий разрабатывается в среде PascalABC.NET, а группа, из которой импортируется преамбула,
также была разработана в PascalABC.NET и, следовательно, содержится в некотором pcu-модуле, то в список uses модуля с новой группой
необходимо добавить имя модуля, содержащего группу, из которой импортируется преамбула.
Процедуры CommentText и UseComment должны вызваться после функции CreateGroup;
при этом они определяют преамбулу данной группы. Для того чтобы они определяли
преамбулу какой-либо подгруппы данной группы, перед их вызовом необходимо вызвать
процедуру Subgroup, описываемую далее.
procedure Subgroup(SubgroupName: string);
Данная процедура устанавливает режим добавления текста к преамбуле подгруппы SubgroupName текущей
группы. Этот режим сохраняется до следующего вызова данной процедуры или до завершения определения текущей группы заданий
(определение группы, создаваемой в виде dll-файла, завершается при выходе из процедуры inittaskgroup, а группы,
создаваемой в виде pcu-файла, при вызове процедуры RegisterGroup).
Процедуру Subgroup можно вызывать несколько раз для одной и той же подгруппы, при этом ранее определенный текст
преамбулы будет дополняться новыми данными. При вызове процедуры Subgroup с параметром пустой строкой
устанавливается режим дополнения преамбулы группы (напомним, что этот режим устанавливается также
сразу после вызова процедуры CreateGroup).
Регистрация новой группы заданий в модуле PT4Load для системы PascalABC.NET
procedure RegisterGroup(UnitName: string);
Данная процедура предназначена, прежде всего, для использования при создании групп в среде PascalABC.NET
(в виде pcu-файлов),
однако она доступна и в варианте конструктора, ориентированном на разработку групп в виде dll-файлов.
Эта процедура обеспечивает завершение формирования текущей группы; в частности, это означает, что
после ее вызова все последующие вызовы процедур, связанных с определением преамбул для группы и ее подгрупп,
будут игнорироваться. Впрочем, для группы, создаваемой в виде dll-файла, необходимые завершающие действия
выполняются автоматически при выходе из процедуры inittaskgroup, поэтому необходимости в специальном вызове
процедуры RegisterGroup не возникает. В то же время, при создании группы в виде pcu-файла системы PascalABC.NET
рекомендуется всегда вызывать процедуру RegisterGroup после формирования текущей группы, поскольку
это предотвращает опасность случайного добавления постороннего текста к последней определяемой преамбуле.
В варианте конструктора для создания pcu-файлов процедура RegisterGroup обеспечивает еще одно важное действие,
а именно, она добавляет информацию о созданной группе во вспомогательный программный модуль
PT4Load, интегрированный в систему PascalABC.NET. Это позволяет использовать модуль PT4Load
для создания программ-заготовок, связанных с данной группой. Следует заметить, что необходимость
в специальных действиях по регистрации новой группы в модуле PT4Load возникает только для групп,
созданных в виде pcu-файлов, так как группы, определенные в виде dll-файлов и размещенные в
текущем каталоге или подкаталоге Lib системного каталога задачника, регистрируются в модуле PT4Load
(а также в модуле PT4Demo) автоматически. Напомним, что при использовании варианта задачника, интегрированного в PascalABC.NET,
системным каталогом задачника считается подкаталог PT4 системного каталога PascalABC.NET.
Параметр UnitName процедуры должен содержать имя pcu-модуля (при вызове данной процедуры для группы, определяемой
в виде dll-файла, параметр может содержать произвольный текст, например, пустую строку).
Информация о регистрируемой группе сохраняется в файле PTGroups.dat, который размещается в подкаталоге
Lib системного каталога PascalABC.NET, а также в каталоге, из которого запускается программа с заданием.
При загрузке модуля PT4Load вначале считывается информация из файла PTGroups.dat, расположенного в текущем каталоге,
а затем из подкаталога Lib системного каталога PascalABC.NET.
При использовании английской версии задачника вместо файла PTGroups.dat используется файл PTGroups_en.dat.
Вызов процедуры RegisterGroup, как и процедуры CreateGroup, производится в секции инициализации pcu-модуля,
поэтому добавление (или восстановление) информации о данной группе заданий будет происходить при каждом запуске
программы, использующей этот модуль. При этом сразу после выполнения этой программы данная информация
будет доступна для использования в модуле PT4Load (в частности, при отображении на экране окна PT4Load новая группа появится
в списке имеющихся групп, и можно будет создать заготовку для любого задания из этой группы). Следует, однако, заметить,
что если некоторая группа заданий реализована как в виде dll-файла, так и в виде pcu-файла, то предпочтение
будет отдано группе из dll-файла как более универсальной, и именно с ней будет связана программа-заготовка, созданная
модулем PT4Load.
Примечание. В модуле PT4Load не отображаются библиотечные группы,
т. е. группы, имена которых содержат более 9 символов (задания из подобных групп не предназначены для непосредственного выполнения;
их можно лишь включать в состав других групп). Для библиотечных групп процедура RegisterGroup не выполняет
действий, связанных с их регистрацией.
Константы и функции для определения текущего состояния задачника
const
lgPascal = $0001;
lgVB = $0002;
lgCPP = $0004;
lg1C = $0040;
lgCS = $0100;
lgVBNET = $0200;
lgPascalNET = $0400;
lgAll = $FFFFFF;
lgNET = $FF00;
lgWithPointers = $003D;
lgPascalABCNET = $0401;
Данные константы, совместно с описываемой далее функцией CurrentLanguage,
позволяют определить язык программирования, на который
в данный момент (т. е. в момент инициализации текущей группы заданий) настроен задачник.
Константы lgPascal, lgVB, lgCPP, lgCS,
lgVBNET, lg1C соответствуют конкретному языку из числа тех, которые
доступны в версии 4.10 задачника (Pascal, Visual Basic, C++, C#, Visual Basic .NET, 1С:Предприятие). Эти константы являются битовыми флагами.
Заметим, что константа lg1C появилась в версии 4.9 конструктора учебных заданий (в связи с реализацией
комплекса PT for 1C варианта задачника
для системы 1С:Предприятие).
Некоторые константы являются комбинациями битовых флагов (т. е. битовыми масками) и позволяют определить, к какой категории
относится текущий язык:
- lgAll любой язык,
- lgWithPointers язык, поддерживающий работу
с указателями (в версии 4.10 задачника это языки Pascal и C++),
- lgNET язык платформы .NET
(в версии 4.10 задачника это языки C# и Visual Basic .NET).
Особое место занимает язык, реализованный в системе PascalABC.NET, поскольку в нем объединяются
свойства обычного языка Pascal и языка платформы .NET. Поэтому данному языку соответствует комбинация
флагов lgPascal + lgPascalNET; это, в частности, означает, что он принадлежит одновременно к категориям
lgWithPointers и lgNET. Для языка PascalABC.NET предусмотрена также именованная константа lgPascalABCNET.
function CurrentLanguage: integer;
Функция возвращает значение, соответствующее языку программирования, на который в данный момент настроен задачник.
Помимо сравнения
возвращаемого значения функции с константами, соответствующими конкретному языку (например, CurrentLanguage = lgCPP),
можно также использовать данную функцию для определения категории, к которой относится текущий язык программирования; в этом
случае необходимо применять побитовые операции. Например, для проверки того, что текущий язык программирования
относится к категории языков платформы .NET, достаточно проверить истинность условия
CurrentLanguage and lgNET <> 0.
При использовании задачника совместно с системой PascalABC.NET функция CurrentLanguage всегда возвращает значение
lgPascalABCNET.
function CurrentLocale: string;
Функция возвращает строку, соответствующую текущей локали, т. е. текущему языку интерфейса, используемому
в задачнике. В версии 4.10 конструктора учебных заданий возможными возвращаемыми значениями функции CurrentLocale являются 'ru'
(русский вариант задачника) и 'en' (английский вариант).
function CurrentVersion: string;
Данная функция добавлена в версию 4.10 конструктора учебных заданий.
Она возвращает номер текущей версии задачника в виде строки числа формата 'd.dd'.
В частности, в случае версии 4.10 возвращается строка '4.10'. Для предыдущих версий задачника
функция возвращает строку '4.00'.
Образцы слов и предложений
Приведенные ниже элементы конструктора PT4TaskMaker позволяют получить доступ к
встроенным в него образцам текстовых исходных данных: словам (Word),
предложениям (Sentence) и многострочным текстам (Text).
const
SampleError = '#ERROR?';
MaxLineCount = 50;
function WordCount: integer;
function SentenceCount: integer;
function TextCount: integer;
function WordSample(N: integer): string;
function SentenceSample(N: integer): string;
function TextSample(N: integer): string;
function EnWordCount: integer;
function EnSentenceCount: integer;
function EnTextCount: integer;
function EnWordSample(N: integer): string;
function EnSentenceSample(N: integer): string;
function EnTextSample(N: integer): string;
Функции WordSample, SentenceSample и TextSample
возвращают текстовые данные, соответствующие текущей локали, т. е. текущему языку интерфейса, используемому в задачнике
(см. функцию CurrentLocale):
для русского варианта задачника возвращаются русские данные, для английского английские. Варианты этих функций,
снабженные префиксом En, возвращают английские текстовые данные в любом варианте задачника.
Функции, оканчивающиеся словом Count, возвращают количество
соответствующих элементов данных. В версии 4.9 конструктора учебных заданий доступно 116 слов, 61
предложение и 85 текстов как на русском, так и на английском языке.
Функции WordSample/EnWordSample и SentenceSample/EnSentenceSample возвращают
соответственно слово или предложение с индексом N (индексирование проводится от 0).
Функция TextSample/EnTextSample возвращает строку, связанную с многострочным текстом,
имеющим индекс N (индексирование также проводится от 0). При этом между соседними строками этого текста
располагаются символы #13#10 (маркеры конца строки). В конце текста маркер конца строки отсутствует,
число строк в тексте не превышает значения константы MaxLineCount. Любой текст состоит из нескольких абзацев;
между абзацами текста помещается одна пустая строка, отступы в начале абзацев («красная строка») не используются.
В тексте не используются также переносы слов.
Если параметр N является недопустимым, то все функции возвращают особую строку, равную константе SampleError.
Буква «ё» в русских текстовых данных не используется.
Все слова-образцы состоят из заглавных (прописных) букв.
Помимо слов «общего вида» в набор слов включены слова, обладающие следующими особенностями
(наличие подобных особых слов может оказаться полезным при составлении заданий):
- слова, начинающиеся и оканчивающиеся одной и той же буквой;
- слова, содержащие три одинаковые буквы (в русском наборе три буквы «А», в английском наборе
три буквы «E»).
Длина предложений-образцов не превосходит 76 символов; таким образом, любое предложение умещается на одной экранной строке
(напомним, что строки при выводе в окне задачника обрамляются апострофами).
Многострочные тексты предназначены для использования, прежде всего, в заданиях на обработку текстовых файлов
(см. реализацию подобного задания в разделе «Примеры»).
Длина строк в многострочных текстах не превосходит 50 символов.
|