Programming Taskbook


E-mail:

Пароль:

Регистрация пользователя   Восстановление пароля

English

ЮФУ SMBU

Электронный задачник по программированию

©  М. Э. Абрамян (Южный федеральный университет, Университет МГУ-ППИ в Шэньчжэне), 1998–2024

 

Решения | Ruby и Julia | Простое задание

PrevNext


Пример выполнения простого задания: Begin3

На данной странице приводится пошаговое описание процесса решения на языках Ruby и Julia следующего простого задания из группы Begin.

Begin3°. Даны стороны прямоугольника a и b. Найти его площадь S = ab и периметр P = 2(a + b).

Описание ориентировано на версию задачника 4.22, в которой для языков Ruby и Julia можно использовать среду VS Code (а также среду RubyMine для языка Ruby). В предыдущих версиях задачника для языка Ruby была доступна также среда NetBeans. При использовании среды NetBeans проект создавался в специальном подкаталоге PT_Ruby рабочего каталога, причем решение требовалось указывать в файле с фиксированным именем MyTask.rb, расположенном в этом подкаталоге. В остальном действия при решении задач на языке Ruby в среде NetBeans незначительно отличались от описываемых далее.

Создание программы-заготовки и знакомство с заданием

Для создания проекта, содержащего заготовку для требуемого задания, следует воспользоваться программным модулем PT4Load. Для этого достаточно перейти в рабочий каталог задачника и с помощью ярлыка Load.lnk запустить программу PT4Load.exe (начиная с версии 4.22, для быстрого запуска любых модулей задачника можно использовать программу PT4Panel, ярлык которой располагается на рабочем столе и в любом рабочем каталоге). В результате на экране появится окно модуля PT4Load, в котором следует указать имя нужного задания. Отметим, что в заголовке этого окна указывается имя той программной среды, для которой будет создана заготовка; при использовании языка Ruby в заголовке должен содержаться текст «Ruby», например, «Visual Studio Code (Ruby)» (означающий, что заготовка будет создана в редакторе VS Code) или «RubyMine 2020» (означающий, что заготовка будет создана в среде RubyMine версии 2020).

Созданный проект-заготовка размещается рабочем каталоге задачника и состоит из нескольких подкаталогов и файлов, однако для решения задания нам потребуется только один файл с именем Begin3 (и расширением .rb для Ruby и .jl для Julia), который будет автоматически загружен в редактор среды используемой среды. Приведем его содержимое (первая строка-комментарий в варианте для языка Ruby определяет используемую кодировку):

[Ruby]

# coding: utf-8
require "./PT"

def solve()
    task "Begin3"

end

start_solve

[Julia]

include("PT.jl")

function solve()
    task("Begin3")

end

start_solve()

Файлы Begin3.rb и Begin3.jl содержат описание функции solve, в которой требуется запрограммировать решение выбранной задачи (хотя, разумеется, в решении могут использоваться другие функции, описанные в данном файле). Функция solve уже включает вызов функции task, инициализирующей задание Begin3. Оператор require обеспечивает подключение кода из файла PT.rb, включающего вспомогательные функции и классы, необходимые для выполнения заданий. В этом файле, в частности, описана функция task. Кроме того, в файле PT.rb описана функция start_solve, вызов которой указывается в конце файла Begin3.rb. В этой функции выполняется инициализация задачника и тестирование алгоритма, описанного в функции solve. Дополнительные функции и классы для языка Julia описаны в файле PT.jl, который подключается к файлу Begin3.jl оператором include.

Данную программу уже можно запустить на выполнение. Для этого в среде VS Code достаточно нажать клавишу [F5], а в среде RubyMine — клавишу [Shift]+[F10]. Предусмотрены также кнопки с изображением треугольничка, позволяющие запустить программу (для отображения этой кнопки в среде VS Code надо предварительно установить режим отладки, нажав комбинацию [Ctrl]+[Shift]+[D]). Запуск программ можно ускорить, если отключить режим отладки; для этого достаточно использовать комбинацию [Ctrl]+{F5].

В результате на экране появится окно задачника, содержащее формулировку задания и пример исходных данных. Начиная с версии 4.11, окно задачника может отображаться в двух режимах: с динамической компоновкой, при которой каждый раздел «подстраивается» под свое содержимое, и с фиксированной компоновкой, при которой каждый раздел имеет фиксированные размеры. В предыдущих версиях задачника был доступен только режим с фиксированной компоновкой. Режим с динамической компоновкой особенно удобен для заданий с большими формулировками и большими наборами данных. Ниже приведены оба режима окна для данного задания при использовании языка Ruby; вначале указан режим с динамической компоновкой (для переключения режимов предназначена клавиша [F4]).




Запуск нашей программы был признан ознакомительным (и поэтому правильность решения не анализировалась), так как в ходе ее выполнения не было совершено ни одной операции ввода-вывода. Для завершения программы достаточно закрыть окно задачника, нажав клавишу [Esc] или кнопку «Выход (Esc)». При использовании среды RubyMine для закрытия окна можно также нажимать клавишу [F10], а при использовании среды VS Code — клавишу [F5].

Примечание. В версии 4.21 поддержка режима с фиксированной компоновкой была прекращена. Начиная с этой версии, команда Режим (F4), ранее применявшаяся для переключения между режимами с фиксированной и динамической компоновкой, обеспечивает отображение текста текущего задания в режиме html-документа. В дальнейшем в качестве иллюстраций будут использоваться только окна с динамической компоновкой.

Ввод исходных данных

Приступая к решению задачи, надо прежде всего организовать ввод в программу исходных данных. В нашем случае исходными данными являются вещественные числа a и b, определяющие стороны прямоугольника (в области исходных данных в окне задачника эти числа выделены желтым цветом и снабжены комментариями).

Для ввода исходных данных в нашем случае мы можем использовать функцию get_f, обеспечивающую ввод вещественных чисел, или «универсальную» функцию get, позволяющую ввести данные любого типа. Использование «универсальной» функции get не позволяет задачнику распознать ряд ошибок, связанных с вводом, поэтому при начальном изучении программирования целесообразнее использовать «специализированные» функции, каждая из которых предназначена для ввода данных определенного типа. Итак, организуем ввод данных с помощью функции get_f (здесь и далее будем приводить только текст функции solve):

[Ruby]

def solve()
    task "Begin3"
    a = get_f
    b = get_f
end

[Julia]

function solve()
    task("Begin3")
    a = get_f()
    b = get_f()
end

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

Ввод данных выполнен правильно. Однако наша программа не выводит результатов. Начиная с версии 4.15, в данной ситуации выводится сообщение на светло-синем фоне: «Запуск с правильным вводом данных: все требуемые исходные данные введены, результаты не выведены». Светло-синяя индикация означает, что успешно пройден первый этап решения: ввод исходных данных. Заметим, что в предыдущих версиях задачника в аналогичной ситуации выводилось сообщение об ошибке на оранжевом фоне «Выведены не все результирующие данные. Количество выведенных данных: 0 (из 2)».

Вычисления и вывод полученных данных

Выполним необходимые вычисления и выведем результаты, используя метод put:

[Ruby]

def solve()
    task "Begin3"
    a = get_f
    b = get_f
    p = 2 * (a + b)
    s = a * b
    put P, S
end

[Julia]

function solve()
    task("Begin3")
    a = get_f()
    b = get_f()
    p = 2 * (a + b)
    s = a * b
    put(P, S)
end

Обратите внимание на то, что параметры функций в языке Ruby не требуется заключать в круглые скобки (хотя это и не запрещается), а в языке Julia скобки после имени вызываемой функции необходимо указывать всегда, даже если функция не имеет параметров. При запуске этого варианта программы в информационной панели окна задачника будет выведено сообщение об ошибке (на красном фоне): «Error NameError: uninitialized constant P» (для языка Ruby) или «UndefVarError: P not defined» (для языка Julia). Это же сообщение будет выведен в окне терминала программ VS Code и RubyMine.

Наша ошибка объясняется тем обстоятельством, что в программах на языках Ruby и Julia учитывается регистр символов, и поэтому переменные p и P считаются различными (при этом, по правилам языка Ruby, переменные, начинающиеся с заглавной буквы, считаются константами). Так как ранее в нашей программе константа P не использовалась, она считается неопределенной, о чем и выводится сообщение. Для исправления программы достаточно изменить ее последний оператор:

[Ruby]

    put p, s

[Julia]

    put(p, s)

Исправленная программа не содержит ошибок, препятствующих ее выполнению. После ее запуска мы можем убедиться, что найденные значения выведены в разделе результирующих данных. Но из-за того, что вначале мы вывели значение периметра p, а затем — значение площади s, решение признано неверным, а сообщение об ошибке имеет вид «Ошибочное решение». Подобное сообщение означает, что все исходные данные были введены, все результирующие данные выведены, но значения полученных результатов не совпадают с контрольными:


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

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

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

Таким образом, важно не только найти правильные значения результирующих данных, но и вывести их в нужном порядке. Для того чтобы указать этот порядок, в разделе результатов используется поясняющий текст (см. приведенный выше рисунок окна задачника). Заметим, что исходные данные тоже важно вводить именно в том порядке, в котором они указаны в окне задачника. Общее правило здесь следующее: ввод и вывод данных производится по строкам (слева направо), а строки просматриваются сверху вниз. Иными словами, данные, отображаемые в окне задачника, вводятся и выводятся в том порядке, в котором читается обычный текст на русском языке.

Правильное решение и его тестирование

Исправим допущенную ошибку:

[Ruby]

    put s, p

[Julia]

    put(s, p)

После запуска исправленной программы на экране появится окно прогресса тестирования:

Данное окно отображается на экране, если программа успешно обработала хотя бы один набор исходных данных. Полоса прогресса показывает, сколько тестов было успешно пройдено к текущему моменту, а текст над полосой дублирует эту информацию и позволяет определить количество тестов, которое должна успешно пройти программа, чтобы задание считалось выполненным. Тестирование программы завершается в двух случаях: когда будет успешно пройдено требуемое число тестов или когда при прохождении очередного теста будет выявлена ошибка.

В нашем случае решение не содержит ошибок, поэтому после прохождения трех успешных тестов на экране появится окно задачника с сообщением «Задание выполнено!». Выполнение задания Begin3 завершено:


Возможность автоматического тестирования программы на нескольких наборах исходных данных была реализована в версии 4.13 задачника. В предыдущих версиях для тестирования на различных наборах данных программу требовалось запускать несколько раз; при этом на информационной панели выводилась информация о количестве успешно пройденных тестов. Возможность подобного «пошагового» тестирования сохранена и в последующих версиях; для этого надо дополнить имя задания в функции task символом «!» (восклицательный знак).

С помощью модуля PT4Results можно просмотреть информацию о ходе выполнения задания (начиная с версии 4.11, этот модуль можно вызывать непосредственно из окна задачника; для этого достаточно нажать клавишу [F2] или щелкнуть мышью на метке с описанием этой клавиши, размещенной в правом верхнем углу окна задачника):

Begin3      r04/02 14:57 Ознакомительный запуск.
Begin3      r04/02 15:07 Запуск с правильным вводом данных.
Begin3      r04/02 15:09 Error NameError.
Begin3      r04/02 15:12 Ошибочное решение.
Begin3      r04/02 15:15 Задание выполнено!

Буква «r», указанная перед датой, означает, что задание выполнялось на языке Ruby (для языка Julia используется буква «u»).

Примечание 1. В использовании вспомогательных переменных p и s при выполнении задания нет необходимости, поскольку при выводе результатов можно указать не только переменные, но и выражения. Учитывая это, можно получить более короткий вариант решения задания Begin3. Можно еще более сократить текст программы, если вместо функции get_f использовать «универсальную» функцию ввода get и организовать присваивание исходных данных двум переменным в одном операторе:

[Ruby]

def solve()
    task "Begin3"
    a, b = get, get
    put a * b, 2 * (a + b)
end

[Julia]

function solve()
    task("Begin3")
    a, b = get(), get()
    put(a * b, 2 * (a + b))
end

Начиная с версии задачника 4.22, предусмотрены варианты get2, get3, get4, get5 универсальной функции ввода, которые возвращают 2, 3, 4 или 5 очередных элементов исходных данных:

[Ruby]

    a, b = get2

[Julia]

    a, b = get2()

В языке Ruby можно также воспользоваться методами put без параметров, которые следует применять непосредственно к выводимым данным:

[Ruby]

def solve()
    task "Begin3"
    a, b = get2
    (a * b).put
    (2 * (a + b)).put
end

Таким образом, при организации действий по вводу-выводу в языке Ruby можно применять различные подходы, что соответствует идеологии языка Ruby: «Достигнуть требуемого результата можно разными способами».

Примечание 2. При работе в редакторе VS Code можно переключаться на другие задачи, если для них уже созданы заготовки для того же языка (Ruby или Julia). Для этого достаточно перейти в режим проводника (нажав [Ctrl]+[Shift]+[E]) и выполнить двойной щелчок мышью на требуемом файле с расширением rb или jl. Можно также переключаться между уже загруженными в редактор файлами и запускать любой из них на выполнение. Кроме того, можно создавать новые заготовки с помощью программы PT4Load, не закрывая окно редактора VS Code; при этом новая заготовка будет добавлена к уже загруженным в редактор файлам.

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


PrevNext

 

Рейтинг@Mail.ru

Разработка сайта:
М. Э. Абрамян, В. Н. Брагилевский

Последнее обновление:
01.01.2024