|
Вспомогательные функции задачника
Описанные на данной странице функции и класс Node будут доступны в программе, если к ней подключен файл
PT.rb для языка Ruby или файл PT.jl для языка Julia (данные файлы входят в состав дистрибутива задачника Programming Taskbook и автоматически
подключаются к любому проекту-заготовке, созданному для выполнения задания на языке Ruby или Julia).
Инициализация заданий, ввод-вывод данных
task(name)
Функция инициализирует задание с именем name (обязательный строковый параметр). Она должна
вызываться в начале программы, выполняющей это задание (до вызова функций ввода-вывода get и put).
Если в программе, подключившей файл PT.rb или PT.jl, не указана функция task, то при запуске программы
появится окно с сообщением об ошибке «Не вызвана функция task с именем задания».
Строковый параметр name должен включать имя группы заданий и порядковый номер в пределах группы (например, "Begin3" ).
Регистр букв в имени группы может быть произвольным. Если указана неверная группа, то программа выведет
сообщение об ошибке «Указана неверная тема задания»
(список всех доступных групп можно получить с помощью программных модулей PT4Demo и PT4Load).
Если указан недопустимый номер задания, то программа выведет сообщение,
в котором будет указан диапазон допустимых номеров для данной группы. Если после имени задания в параметре name
указан суффикс «?» (например, "Begin3?" ), то программа будет работать в демонстрационном режиме.
Функция task может также использоваться для генерации и вывода на экран html-страницы с текстом задания или группы заданий.
Для этого необходимо указать в качестве параметра name имя конкретного задания или группы заданий и суффикс «#»,
например, "Begin3#" или "Begin#" .
Начиная с версии 4.13, задачник обеспечивает автоматическое тестирование программы на нескольких
наборах исходных данных при ее однократном запуске. Для отключения этой возможности достаточно
указать в параметре Name после имени задания суффикс «!» (например, "Begin3!" );
в этом случае при запуске программы она будет протестирована на единственном наборе исходных данных,
и для проверки правильности решения программу потребуется запустить несколько раз (как в предыдущих версиях
задачника).
Если функция task вызывается в программе несколько раз, то все последующие ее вызовы игнорируются.
Исключением является ситуация, когда функция используется для генерации html-страницы с описанием нескольких
заданий или групп заданий; в этом случае учитываются все вызовы данной функции.
Начиная с версии 4.12, параметр name может содержать суффикс «_ru»
или «_en», позволяющий явным образом задать язык интерфейса
(русский или английский соответственно) для окна задачника и выполняемого задания.
В версиях 4.124.14 специальные суффиксы «?», «#» и «!» должны указываться перед данным суффиксом,
например, "Begin3#_en" ; начиная с версии 4.15, суффиксы могут указываться в любом порядке.
В случае нескольких вызовов функции task (для генерации
html-страницы) учитывается только суффикс, указанный при первом вызове функции.
При отсутствии суффикса используется язык интерфейса, определенный в качестве основного для данного рабочего каталога
(в универсальном варианте задачника основной язык интерфейса можно настроить с помощью программного модуля PT4Load,
используя его контекстное меню).
get()
get_b()
get_i()
get_f()
get_s()
get_node()
[Julia]
get_c()
Функции обеспечивают ввод исходных данных в программу, выполняющую учебное задание. Они должны вызываться
после вызова функции task; в случае их вызова до функции task программа выведет сообщение об ошибке
«В начале программы не вызвана функция task с именем задания».
Каждый вызов функции возвращает очередной
элемент исходных данных. Функция get позволяет ввести элемент данных любого типа: логического (типа TrueClass и FalseClass
в Ruby, Bool в Julia),
целого (типа Integer (Fixnum) в Ruby, Int в Julia), вещественного (типа Float в Ruby, Float64 в Julia),
символьного (типа Char в Julia; в языке Ruby особый символьный тип отсутствует, поэтому символьные данные
рассматриваются как частный случай строковых),
строкового (типа String в Ruby и Julia) или класса Node, описываемого ниже.
Прочие функции предназначены для ввода даннных определенного типа:
get_b логического, get_i целого, get_f вещественного, get_c символьного,
get_s строкового, get_node объекта типа Node.
Особенность «специализированных»
функций get_b, get_i, get_f, get_c, get_s и get_node по сравнению с «универсальной»
функцией get состоит в том, что если
вызванная «специализированная» функция не соответствует типу очередного элемента исходных данных, то
выводится сообщение об ошибке «Неверно указан тип при вводе исходных данных»
(такое сообщение будет выведено, например, если очередной элемент данных является строкой,
а для его ввода используется функция get_i). Таким образом, применение «специализированных»
функций позволяет задачнику выявить такие ошибки ввода, как, например,
ошибки, связанные с неверным порядком чтения исходных данных. «Универсальная»
функция get больше соответствует идеологии языков Ruby и Julia, однако при ее использовании
теряется часть возможностей задачника, связанных с контролем правильности ввода исходных данных.
Начиная с версии задачника 4.22, предусмотрены варианты get2, get3, get4, get5 универсальной функции ввода,
которые возвращают 2, 3, 4 или 5 очередных элементов исходных данных
(при этом элементы могут иметь различные типы), например:
[Ruby]
a, b, c = get3
[Julia]
a, b, c = get3()
При попытке ввести больше исходных данных, чем это предусмотрено в задании, выводится сообщение
об ошибке «Попытка ввести лишние исходные данные». Если исходные данные, необходимые
для решения задания, введены не полностью, то выводится сообщение «Введены не все требуемые исходные данные».
put(a, ...)
[Ruby]
a.put
Функция put обеспечивает вывод на экран результирующих данных, найденных программой,
и их сравнение с контрольными данными (т. е. с правильным решением). Как и функции группы get,
эта функция должна вызываться после вызова функции task; в противном случае ее вызов приводит к сообщению об ошибке
«В начале программы не вызвана функция task с именем задания».
В функции put можно указывать один или более параметров. В качестве любого параметра можно указать
переменную или выражение логического, числового, символьного, строкового типа, типа Node, а также массив
(Array в Ruby, AbstractVector в Julia), содержащий элементы этих типов.
Указание массива приводит к тому, что в задачник последовательно пересылаются все элементы
этого массива.
В качестве параметров метода put
можно указывать не только переменные, но и выражения (в частности, константы
соответствующего типа, а также пустой объект (nil в Ruby, nothing в Julia).
Заметим, что пустые объекты, как и объекты типа Node, требуется
выводить только в заданиях групп Dynamic
и Tree (и их аналогов GCDyn и GCTree, появившихся в версии задачника 4.15).
При попытке указания данных других типов
программа выводит сообщение об ошибке
«the put function has an argument of invalid type» (сообщение на английском языке означает, что
данная ошибка обнаружена без обращения к ядру задачника).
Тип параметра должен не только быть допустимым, но и соответствовать типу
очередного элемента результирующих данных; в противном случае выводится
сообщение об ошибке «Неверно указан тип при выводе результатов».
При вызове функции put задачник осуществляет контроль
за соответствием количества требуемых и выведенных результирующих данных. Если программа выведет
недостаточное или избыточное количество результирующих данных, то после проверки этих данных появится сообщение
«Выведены не все результирующие данные» или, соответственно, «Попытка вывести лишние результирующие данные».
Кроме функции put с произвольным числом параметров, в языке Ruby для вывода результатов можно использовать
метод put без параметров, вызывая его для требуемого элемента результирующих данных. Метод put определен
для логических типов TrueClass и FalseClass, числовых типов Integer (Fixnum) и Float, а также для типов String, Node и Array.
Например, для вывода целого числа 1 можно использовать как выражение put 1 , так и выражение 1.put .
Класс Node
[Ruby]
# Конструкторы:
Node.new()
Node.new(data)
Node.new(data, next)
Node.new(data, next, prev)
Node.new(left, right, data)
Node.new(left, right, data, parent)
# Свойства (доступны для чтения и для записи):
data
next
prev
left
right
parent
# Метод, освобождающий ресурсы, используемые объектом Node:
dispose()
[Julia]
# Конструкторы:
node()\m\|');
node(data::Integer)
node(data::Integer, next::Node)
node(data::Integer, next::Node, prev::Node)
node(left::Node, right::Node, data::Integer)
node(left::Node, right::Node, data::Integer, parent::Node)
# Функции для доступа к свойствам (символ ! означает изменение свойства):
data(node::Node)
data!(node::Node, value::Integer)
next(node::Node)
next!(node::Node, value::Node)
prev(node::Node)
prev!(node::Node, value::Node)
left(node::Node)
left!(node::Node, value::Node)
right(node::Node)
right!(node::Node, value::Node)
parent(node::Node)
parent!(node::Node, value::Node)
# Функция, освобождающая ресурсы, используемые объектом Node:
dispose!(node::Node)
Класс Node используется в заданиях групп Dynamic
и Tree и их аналогов GCDyn и GCTree. В заданиях на
стеки и очереди (Dynamic1Dynamic28) при работе с объектами типа Node
используются только свойства data и next; в заданиях на двусвязные списки
(Dynamic29Dynamic80) используются свойства data, next и prev. В большинстве заданий на
бинарные деревья (группа Tree) используются свойства data, left и right;
в заданиях на обработку бинарных деревьев с обратной связью
(Tree48Tree56 и Tree70Tree71) дополнительно используется свойство parent.
Варианты конструктора класса Node
позволяют задавать значения требуемых свойств при создании
объекта; прочие свойства инициализируются нулевыми значениями
(числом 0 для свойства data, пустым объектом nil или nothing для остальных свойств).
Следует обратить внимание на то, что при завершении работы с объектом типа Node требуется вызвать
его метод dispose, освобождающий ресурсы, выделенные для этого
объекта (исключение делается только для тех объектов, которые передаются обратно
задачнику в качестве результирующих данных). Если в задании требуется вызвать
метод dispose для некоторых объектов, но этот вызов не выполняется, то при запуске
программы выводится сообщение об ошибке «Не вызван метод dispose для
объекта типа Node». При выполнении заданий групп GCDyn и GCTree, появившихся в версии 4.15,
использовать метод dispose не требуется.
Все исходные и результирующие данные-ссылки в заданиях групп Dynamic и Tree
имеют тип Node; их ввод и вывод должен осуществляться с помощью описанных выше функций
get (или get_node) и put.
Вывод отладочной информации
С помощью описываемых далее средств можно выводить отладочную информацию
непосредственно в окно задачника (в специальный раздел отладки).
Начиная с версии 4.22, в раздел отладки можно выводить текстовые данные,
содержащие любые символы Юникода.
show(a, ...)
Отображает данные в разделе отладки окна задачника. В качестве параметров можно указывать элементы данных
любого типа; эти элементы будут автоматически преобразованы к своим строковым представлениям.
Если текущая экранная строка в разделе отладки уже содержит некоторый текст, то
каждый элемент выводимых данных снабжается начальным пробелом и приписывается к предшествующему тексту,
за исключением случая, когда при таком приписывании размер
полученного текста превысит ширину области данных (равную 80 символам).
В последнем случае вывод очередного элемента осуществляется с начала
следующей экранной строки; если же и в этой ситуации размер элемента превысит
ширину области данных, то он будет выведен на нескольких
экранных строках, причем разрывы текста будут выполняться по
пробельным символам строкового представления элемента, а при отсутствии пробелов при
достижении очередного фрагмента строки длины, равной 80.
Параметры могут содержать явные команды перехода на новую
экранную строку. В качестве таких команд можно использовать или
символ с кодом 13 ("\r" в Ruby, '\r' в Julia «возврат каретки»),
или символ с кодом 10 ("\n" в Ruby, '\n' в Julia «переход на новую
строку»), или их комбинацию в
указанном порядке (строка "\r\n" ).
show_line(a, ...)
Модификация ранее описанной функции show; после вывода всех элементов данных в раздел отладки
данная функция дополнительно осуществляет автоматический переход на следующую экранную строку.
hide_task()
Вызов данной функции обеспечивает автоматическое скрытие всех разделов окна
задачника, кроме раздела отладки. Если раздел отладки в окне задачника
не отображается (в частности, если программа запущена в
демонстрационном режиме), то вызов функции hide_task игнорируется.
Игнорируются также все повторные вызовы данной функции.
Скрыть/восстановить основные разделы окна
задачника после его отображения на экране можно также с помощью клавиши
пробела или соответствующей команды контекстного меню раздела отладки.
|